目录
RNN相关概念解析
图解RNN
RNN要做的就是把前一个时刻的信息传到下一个时刻 。
循环神经网络的输出取决于当前的输入和上一时刻的隐变量。隐变量中包含历史信息和Whh(如何转到下一时刻的输出)
Whx是输入与隐藏层之间的权重,Whh包含着时序信息
语言模型就是一个分类模型,输出就是判断下一个词
衡量标准
衡量一个语言模型好坏的方式是平均交叉熵
困惑度(perplexity)就是对平均交叉熵作指数运算,如果值为1是最优,越大越差(不知道选哪个)
-
在最好的情况下,模型总是完美地估计标签词元的概率为1。 此时,模型的困惑度为1。
-
在最坏的情况下,模型总是预测标签词元的概率为0。 此时,困惑度是正无穷大。
梯度剪裁(常用于RNN)
如果梯度过大,导致产生的结果都是NAN;如果梯度过小,会导致更新不动
对于长度为T的序列,我们在迭代中计算这T个时间步上的梯度, 将会在反向传播过程中产生长度为O(T)的矩阵乘法链。 当TT较大时,它可能导致数值不稳定, 例如可能导致梯度爆炸或梯度消失。 因此,循环神经网络模型往往需要额外的方式来支持稳定训练。
目前流行的解决方法是:通过将梯度g投影回给定半径 (例如θ)的球来裁剪梯度g
当g小于theta时,不会发生变化;如果g过大,会拉回至θ(可以设5和10)
RNNS的应用
循环神经网络从零开始实现
独热编码
首先定义一个One-hot独热编码代码,方便后续使用
F.one_hot(torch.tensor([0, 2]), len(vocab))
tensor([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
我们每次采样的小批量数据形状是二维张量: (批量大小,时间步数)。 one_hot
函数将这样一个小批量数据转换成三维张量, 张量的最后一个维度等于词表大小(len(vocab)
)。 我们经常转换输入的维度,以便获得形状为 (时间步数,批量大小,词表大小)的输出。
X = torch.arange(10).reshape((2, 5))
F.one_hot(X.T, 28).shape
转置是为了在连续的时间步上 迭代(虽然现在不太明白,但是感觉是为了方便训练,后面再理解一下)
如果第0维是批量大小,那么假如每次取一个样本 即(x1 x2 x3...)这样根据rnn计算规则,先算预测的x2