
训练的数据是 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 已经解决,谢谢各位讨论 |