如何解决后足200时期,LSTM LM回归仅<垫>,<UNK> '的' 令牌楠损失
我用pytorch
构建了Bi-LSTM语言模型,发现在200个时期之后,该模型突然仅返回了具有Nan损失的无意义的令牌,而之前却返回了合理的令牌。
请参考以下型号代码:
# optimizer = torch.optim.Adam(model.parameters(),lr=0.009,amsgrad=False)
class BiLSTM(nn.Module):
def __init__(self,voc_size,hidn_size,emb_size=300):
super().__init__()
self.voc_size = voc_size
self.emb_size = emb_size
self.hidn_size = hidn_size
self.emb = nn.Embedding(num_embeddings=voc_size,embedding_dim=emb_size)
self.lstm = nn.LSTM(input_size=emb_size,hidden_size=hidn_size,bidirectional=True)
self.lm_out = nn.Linear(hidn_size*2,voc_size)
self.dropout = nn.Dropout(p=0.3)
def forward(self,x,prev_state):
state_h,state_c = prev_state
bs = len(x)
emb = self.emb(x)
emb = emb.permute(1,-1)
out,(state_h,state_c) = self.lstm(emb,(state_h[:,:bs,:].contiguous(),state_c[:,:].contiguous()))
forward_out = out[:,:,:self.hidn_size]
backward_out = out[:,self.hidn_size:]
concat_h = torch.cat([forward_out[:-2],backward_out[2:]],dim=2)
final_out = self.lm_out(self.dropout(concat_h.permute(1,2)))
return final_out.view(final_out.size()[0]*final_out.size()[1],final_out.size()[-1]),state_c)
解决方法
该问题是由exploding gradient
引起的。
我通过检查图层的渐变和权重发现了这一点:
model.lm_out.weight
>>>
tensor([[nan,nan,...,nan],[nan,nan]],device='cuda:0',requires_grad=True)
model.lm_out.weight.grad
>>>
tensor([[nan,requires_grad=True)
所以我将代码编辑为:
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(),1)
optimizer.step()
它解决了我的问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。