循环神经网络的从零开始实现

https://zh-v2.d2l.ai/chapter_recurrent-neural-networks/rnn-scratch.html

  • 在不裁剪梯度的情况下运行本节中的代码。会发生什么事?

  • 我试着把train_epoch_ch8里的gradient_clip函数打成注释,并打印loss,好像loss没有明显的暴增,最后的困惑度也在1左右。这是正常现象吗?

hi @FZYUAN-1,好问题。 这里只是tiny example,很多情况下没有gradient_clip 会导致loss变成nan

函数train_epoch_ch8中,当updater非optimizer实例时,为什么updater(batch_size=1),这里的batch_size不应该为X.shape[0]吗。

这里批次数据等于1是因为d2l.sgd函数中对步长使用batch_size进行了归一化,也就是说d2l.sgd函数当初是针对没有平均的目标函数使用的,由batch_size长度的全体loss.sum()当然要在梯度更新的时候除以batch_size,如果是nn.CrossEntropyLoss()就已经平均过的loss值就没必要再除掉batch_size,所以设置为1。当然,这里又加了mean()操作可能是怕目标函数没有平均,保个险。在我看来如果是nn.CrossEntropyLoss()的话就没必要再mean了

1 Like

为什么对state进行了detach,难道不需要对状态相关的参数矩阵如Whh等进行更新吗

我认为在每次新的输入进去进行计算时,产生了新的计算图,此时隐状态又加到新的计算图里面了,就可以正常基色梯度了。之所以将每次输入产生的最后一个隐状态detach掉,是为了不将它从前一次的计算图中继续向下分支,这样的话反向传播时会计算到前一次的输入,这样计算变得复杂。detach之后每次的梯度计算都集中在该次小批量的输入中,计算会快一点。