Pytorch RNN 循环网络中 RuntimeError: Trying to backward through the graph a second time

model = RNN()
hn = torch.zeros(1,seq_len,hidden_num)
epochs = 250
clip_value = 100
loss = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(),lr=0.001)

for epoch in range(epochs):
    accu,num = 0.0,0
    for x,y in data_collect(corpus_indice,batch_size,seq_len):
		
		#-------------------------------------------------------------#
		# 这里添加上一句话即可
		hn.detach_()
		#-------------------------------------------------------------#
        output,hn = model(x,hn)
        y = y.transpose(1,0).contiguous().view(-1)
        ls = loss(output.view(-1,vocab_len),y)
        
        optimizer.zero_grad() 
        ls.backward()
        
        torch.nn.utils.clip_grad_value_(model.parameters(), clip_value)
        
        optimizer.step()
        accu += ls.item() * y.shape[0]
        num += y.shape[0]
    if epoch%50 == 0:
        print("现在是第{}次epoch,loss的值为{}".format(epoch,math.exp(accu/num)))
print("完成")

在这里插入图片描述

因为每个iteration,都需要传入一个 h i h_i hi(上一个iteration的结果,如果在上一步执行backward()就会释放 h i h_i hi 的值),在第 i + 1 i+1 i+1步,我们需要传入 h i h_i hi 的值,计算它的梯度,而这个时候 h i h_i hi 的值已经被释放了,导致不能梯度不能回传。

解决办法

使用

hn.detach()

detach()的作用:
返回一个新的Variable,从当前计算图中分离下来的,但是仍指向原变量的存放位置,不同之处只是requires_grad为false,得到的这个Variable永远不需要计算其梯度,不具有grad。

即使之后重新将它的requires_grad置为true,它也不会具有梯度grad

这样我们就会继续使用这个新的Variable进行计算,后面当我们进行反向传播时,到该调用detach()的Variable就会停止,不能再继续向前进行传播

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值