Nlp 精细调整分类:不是学习,为什么损失没有改变?权重没有更新?
我对PyTorch和Huggingface变形金刚比较陌生,并在这方面进行了蒸馏试验 [1608]运行损耗:0.689损耗:0.687 [11248]运行损耗:0.693损耗:0.694 [11988]运行损耗:0.693损耗:0.683 [1528]运行损耗:0.689损耗:0.701 [13168]运行损耗:0.690损耗:0.684 [13808]运行损耗:0.689损耗:0.688 [14448]运行损耗:0.689损耗:0.692等 不管我怎么做,损失从未减少,甚至没有增加,预测也没有变好。在我看来,我忘记了一些东西,所以权重实际上没有更新。有人有主意吗? O 我尝试的Nlp 精细调整分类:不是学习,为什么损失没有改变?权重没有更新?,nlp,pytorch,text-classification,loss-function,huggingface-transformers,Nlp,Pytorch,Text Classification,Loss Function,Huggingface Transformers,我对PyTorch和Huggingface变形金刚比较陌生,并在这方面进行了蒸馏试验 [1608]运行损耗:0.689损耗:0.687 [11248]运行损耗:0.693损耗:0.694 [11988]运行损耗:0.693损耗:0.683 [1528]运行损耗:0.689损耗:0.701 [13168]运行损耗:0.690损耗:0.684 [13808]运行损耗:0.689损耗:0.688 [14448]运行损耗:0.689损耗:0.692等 不管我怎么做,损失从未减少,甚至没有增加,预测也没有
- 不同的损失函数
- BCE
- 交叉熵
- 偶均方误差损失
- 一个热编码与单个神经元输出
- 不同的学习速率和优化器
- 我甚至把所有的目标都改成了一个标签,但即使这样,网络也没有融合
查看运行损耗和小批量损耗很容易产生误导。你应该看看历元损失,因为每个损失的输入都是相同的 此外,您的代码中存在一些问题,修复了所有这些问题,其行为如预期的那样:在每个历元之后,损失会慢慢减少,而且它也可能过度适合小批量。请查看代码,更改包括:使用
model(x)
而不是model.forward(x)
,cuda()
只调用一次,学习率更低等
调整和微调ML模型是一项困难的工作
n_epochs = 5
batch_size = 1
bert_distil = DistilBertForSequenceClassification.from_pretrained('distilbert-base-uncased')
tokenizer = DistilBertTokenizer.from_pretrained('distilbert-base-uncased')
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(bert_distil.parameters(), lr=1e-3)
X_train = []
Y_train = []
for row in train_df.iterrows():
seq = tokenizer.encode(row[1]['text'], add_special_tokens=True, pad_to_max_length=True)[:100]
X_train.append(torch.tensor(seq).unsqueeze(0))
Y_train.append(torch.tensor([row[1]['target']]))
X_train = torch.cat(X_train)
Y_train = torch.cat(Y_train)
running_loss = 0.0
bert_distil.cuda()
bert_distil.train(True)
for epoch in range(n_epochs):
permutation = torch.randperm(len(X_train))
for i in range(0,len(X_train), batch_size):
optimizer.zero_grad()
indices = permutation[i:i+batch_size]
batch_x, batch_y = X_train[indices].cuda(), Y_train[indices].cuda()
outputs = bert_distil(batch_x)
loss = criterion(outputs[0], batch_y)
loss.backward()
optimizer.step()
running_loss += loss.item()
print('[%d] epoch loss: %.3f' %
(epoch + 1, running_loss / len(X_train) * batch_size))
running_loss = 0.0
输出:
[1] epoch loss: 0.695
[2] epoch loss: 0.690
[3] epoch loss: 0.687
[4] epoch loss: 0.685
[5] epoch loss: 0.684
当我尝试使用
xxxForSequenceClassification
微调我的下游任务时,我遇到了类似的问题
最后,我将xxxForSequenceClassification
更改为xxxModel
,并添加了Dropout
-FC
-Softmax
。奇迹般地解决了,损失如预期的那样减少了
我还在努力找出原因
希望它能帮助你
仅供参考,transformers verion:3.5.0您的学习率太高了。试试像1e-4或1e-5这样的小一点的。是的,我试过了。我只是玩了一下学习率,看看有没有什么变化。。。但是,即使数据集中只有一个类,它似乎也没有学到任何东西……试着在单个批次上进行过度拟合。也与您的问题无关,但是:您不需要显式调用model.forward(),只需执行model(X);而且不需要做损耗。requires_grad=True。即使在单个批次上过度装配也不会改变任何东西,损耗保持在0.65左右,但变化与以前相同。。。非常感谢你的回答。这会中断一个错误:RuntimeError:张量的元素0不需要梯度,也没有梯度fn。知道在哪里需要修复吗?如果我不看你的代码,我不知道在哪里修复。你完全复制了上面的代码吗?错误提示某些张量的自动标记已关闭。谢谢您的回答。如上所述,我尝试了不同的学习率,所以这不是问题所在。我还没有尝试过预训练,但我想还有一个更实际的问题:即使数据集中只有一个标签,模型也不会收敛。。。
[1] epoch loss: 0.695
[2] epoch loss: 0.690
[3] epoch loss: 0.687
[4] epoch loss: 0.685
[5] epoch loss: 0.684