pytorch 多分类的问题

2020-08-12 14:27:58 +08:00
 zckun

训练的数据是 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 的准确率

我想知道问题出在哪了,谢谢

2350 次点击
所在节点    Python
13 条回复
python35
2020-08-12 14:49:21 +08:00
交叉熵 loss 里面里面做 softmax 了 前面放 sigmoid 可能有影响??把这个节点去掉试试
zckun
2020-08-12 15:00:01 +08:00
@python35 不是这个原因
xcnick
2020-08-12 15:49:59 +08:00
激活函数要放在线性层中间,不然多个线性层等价于一个线性层
EggtartZ
2020-08-12 17:05:17 +08:00
为什么要 sigmoid 加 softmax 呢,我觉得这样可能会抹除数据之间的差异性吧,是不是 0 和 2 类别的差异性比较大,所以单独拿出来准确率还行
suith27
2020-08-12 17:10:44 +08:00
恕我愚钝,没看出来问题是什么
whenov
2020-08-12 17:16:57 +08:00
层数少应该是欠拟合而不是过拟合吧
shikimoon
2020-08-12 17:23:27 +08:00
1.CrossEntropy 前面不需要再加 sigmoid 或 softmax
2.多个线性层直接叠加相当于一个
daweii
2020-08-12 17:27:18 +08:00
你需要用 training loss 跟 validation loss 对比才能知道真正的情况。我下面所说的前提是你文中说的 loss 是 training loss 。

> loss 前期下降快,后面基本不动。
说明你的模型太小了,即使一直 train 也不能完全拟合数据。这是 underfitting 而不是 overfitting 。不过增加层数确实是解决 underfitting 的方法。

> 接着我训练,loss 会一直增长
训练 loss 只可能是一直下降。训练 loss 出现一直上涨的情况肯定是代码出 bug 了。建议检查代码。
lv2016
2020-08-12 17:30:48 +08:00
看楼主的代码应该是只有当 epoch 为 100 的倍数且标签为 2 的样本才打印 loss,可以先改成全体样本的平均 loss 看看,一般来说后期的 loss 确实下降的比较慢;同时可以尝试一下 mini-batch,单个样本的梯度方向的偏差可能过大了
Porphet
2020-08-12 17:37:14 +08:00
模型能训练的情况下,首先要考虑训练数据的质量,尽量不要出现一个训练条目既是 1 又是 2
tfdetang
2020-08-12 19:25:31 +08:00
没用过 pytorch,不是特别理解,为什么 y_train 不做独热编码? 你用, sigmoid 做输出,最后输出都是 0~1 之间吧。 那你如何输出 2 这个标签呢?
diggerdu
2020-08-12 19:52:00 +08:00
别的不论 初始化先做好
zckun
2020-08-12 21:08:25 +08:00
已经解决,谢谢各位讨论

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/697682

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX