训练的数据是 300x10 的矩阵,一共 14000 个,每个矩阵对应三种情况,表示为 0 1 2
需要特别说明的是,大部分的数据所对应的类别是 0,少数是对应着 1 2 的。可以理解为数据中 50%是 0 类,剩下的 50%分给了 1 2 类
我使用的是逻辑回归
网络如下
class LogisticRegression(nn.Module):
def __init__(self):
super(LogisticRegression, self).__init__()
self.lr = Linear(300 * 10, 3)
self.sm = nn.Sigmoid()
def forward(self, x: Tensor):
# 展开
x = x.view(-1, self.in_features)
x = self.lr(x)
x = self.sm(x)
return x
优化器使用的是 SGD 梯度下降,学习率是 0.001 损失函数用的是 CrossEntropyLoss
训练部分代码如下
其中 x_train 是训练数据,y_train 对应的类别,y_train 中的每个元素均为 0/1/2,没有经过独热编码
x_train 的 shape 为torch.Size([14000, 300, 10])
y_train 的 shape 为torch.Size([14000, 1])
model = LogisticRegression().to(device)
optimizer = optim.SGD(model.parameters(), lr=1e-3)
criterion = nn.CrossEntropyLoss()
for epoch in range(1, 10001):
for i, (data, target) in enumerate(zip(x_train, y_train)):
x, y = data.to(device), target.to(device)
y_pred = model(x)
loss = criterion(y_pred, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 100 == 0:
if y == 2:
print(f'Epoch: {epoch}, Loss: {loss.item()}')
如果训练所有数据,会出现 loss 前期下降快,后面基本不动 我请教过他人,提出我的网络层数太少,出现了过拟合,让我多加几层网络 加了几层后我的网络是这样的
class LogisticRegression(nn.Module):
def __init__(self):
super(LogisticRegression, self).__init__()
self.lr = Linear(300 * 10, 200 * 10)
self.lr2 = Linear(200 * 10, 3)
self.sm = nn.Sigmoid()
def forward(self, x: Tensor):
# 展开
x = x.view(-1, self.in_features)
x = self.lr(x)
x = self.lr(x)
x = self.sm(x)
return x
接着我训练,loss 会一直增长
期间我试过取 0 和 2 两个类别的数据训练 10000 次,结果是 97 的准确率
我想知道问题出在哪了,谢谢
1
python35 2020-08-12 14:49:21 +08:00
交叉熵 loss 里面里面做 softmax 了 前面放 sigmoid 可能有影响??把这个节点去掉试试
|
3
xcnick 2020-08-12 15:49:59 +08:00
激活函数要放在线性层中间,不然多个线性层等价于一个线性层
|
4
EggtartZ 2020-08-12 17:05:17 +08:00
为什么要 sigmoid 加 softmax 呢,我觉得这样可能会抹除数据之间的差异性吧,是不是 0 和 2 类别的差异性比较大,所以单独拿出来准确率还行
|
5
suith27 2020-08-12 17:10:44 +08:00
恕我愚钝,没看出来问题是什么
|
6
whenov 2020-08-12 17:16:57 +08:00
层数少应该是欠拟合而不是过拟合吧
|
7
shikimoon 2020-08-12 17:23:27 +08:00
1.CrossEntropy 前面不需要再加 sigmoid 或 softmax
2.多个线性层直接叠加相当于一个 |
8
daweii 2020-08-12 17:27:18 +08:00 via iPhone
你需要用 training loss 跟 validation loss 对比才能知道真正的情况。我下面所说的前提是你文中说的 loss 是 training loss 。
> loss 前期下降快,后面基本不动。 说明你的模型太小了,即使一直 train 也不能完全拟合数据。这是 underfitting 而不是 overfitting 。不过增加层数确实是解决 underfitting 的方法。 > 接着我训练,loss 会一直增长 训练 loss 只可能是一直下降。训练 loss 出现一直上涨的情况肯定是代码出 bug 了。建议检查代码。 |
9
lv2016 2020-08-12 17:30:48 +08:00
看楼主的代码应该是只有当 epoch 为 100 的倍数且标签为 2 的样本才打印 loss,可以先改成全体样本的平均 loss 看看,一般来说后期的 loss 确实下降的比较慢;同时可以尝试一下 mini-batch,单个样本的梯度方向的偏差可能过大了
|
10
Porphet 2020-08-12 17:37:14 +08:00
模型能训练的情况下,首先要考虑训练数据的质量,尽量不要出现一个训练条目既是 1 又是 2
|
11
tfdetang 2020-08-12 19:25:31 +08:00
没用过 pytorch,不是特别理解,为什么 y_train 不做独热编码? 你用, sigmoid 做输出,最后输出都是 0~1 之间吧。 那你如何输出 2 这个标签呢?
|
12
diggerdu 2020-08-12 19:52:00 +08:00 via iPhone
别的不论 初始化先做好
|
13
zckun OP 已经解决,谢谢各位讨论
|