RNN的python实现

代码见 https://github.com/cs123951/machine_learning_practice
RNN.ipynb和RNN_add.py
实现的难点主要在于backward层。

首先定义Tanh和sigmoid两个激活层,以及最后的softmax层。

  1. Tanh的导数为:(1-tanh(x)*tanh(x))
  2. simoid的导数为:(1-sigmoid(x))*sigmoid(x)
  3. softmax计算式为: qi=eziezk q i = e z i ∑ e z k ,也就是输出类别的概率, zi z i 是softmax层前一层的输出。
    类别的输出形式为[1,0,0,…0]的one-hot向量的形式,采用交叉熵 plogq − ∑ p log q (p为真实样本分布,q为预测样本分布)作为损失函数,则只有当p为1时,log q才有意义,所以损失 Loss= pilogqj − p i log q j .
    当预测正确,j=i, dLossdzi=dLossdqdqdzi=1qj(qiqiqi)=qi1 d L o s s d z i = d L o s s d q ∗ d q d z i = − 1 q j ∗ ( q i − q i ∗ q i ) = q i − 1
    当预测不正确,j != i, dLossdzi=dLossdqdqdzi=1qj(qjqi)=qi d L o s s d z i = d L o s s d q ∗ d q d z i = − 1 q j ∗ ( − q j ∗ q i ) = q i

然后定义乘法矩阵和加法矩阵的求导过程:
对于矩阵x*w=z, dw = x’*dz, dx = dz*x’
对于矩阵加法:x1+x2=z, dx1=dx2=dz

有了上面的基础运算,就可以构建RNN层,
RNN的python实现_第1张图片

而一个RNN就是由若干个RNN层堆叠在一起的,其中的U,W,V参数是共享的。
RNN的反向传播用到了bptt(BackPropagation Through Time),也就是在更新一个节点的时候,往前统计t-1个节点的梯度,称为向前看。
而优化算法用了最简单的随机梯度下降法,因此loss下降特别慢,训练时间特别长。

构建了网络之后,通过两个案例来测试效果,其中对网络都有稍加修改:

  1. 输入一个句子,然后输出预测的下一个句子。RNN.ipynb
    句子的每个词用一个8000维的向量表示,因此输入x的长度是8000,
    输入输出如下:
    x:[1, 51, 27, 16, 10, 853, 53, 25, 34, 69]
    y:[51, 27, 16, 10, 853, 53, 25, 34, 69, 0]
    结果:我不知道为啥预测的都是333333.
  2. 输入两个二进制数字,预测相加后的数字。RNN_add.py
    x:[0 1 1 1 1 0 1 1] [0 0 1 0 1 1 1 1]
    y:[1 0 1 0 1 0 1 0]

你可能感兴趣的:(基础,算法)