第三次作业问题1和问题2
编写:张礼俊/SlyneD
校对:毛丽
总校对与审核:寒小阳
1. 问题背景
在问题1里,我们要训练一个递归神经网络(Recurrent neural networks)来生成一个图片的文字注释(captions)。问题2中,用以长短时记忆单元(Long-short term memory,LSTM)为基础的递归神经网络来完成同样的任务。
我们将用到的数据集是微软的COCO数据集,该数据集是测试为图片加文字注释算法的标准数据集。在该数据集中有大概80000张训练图片和40000张测试图片,每张图片在Amazon Mechanical Turk上征集了五个志愿者来手动写文字说明。
我们可以运行问题1的前几个单元来对我们将要应用的数据有个直观的概念,要注意一点的是之后的处理中我们不会再碰到原始图像,该问题已经为我们提取了图像特征。
2. 递归神经网络
问题1要求我们实现一个递归神经网络。这一部分讲述了问题1的前半部分代码。
递归神经网络是一类处理序列数据的神经网络。在本题用到的递归神经网络的架构如下图所示:
1)单步前向传播(RNN step forward)
我们要实现的第一段代码是单步前向传播。对于每一层神经网络,或每一个时刻,我们输入一个隐藏状态 ht−1 h t − 1 (上一层神经网络的输出),一个外部输入 xt x t ;之后得到下一个隐藏状态 ht h t ,以及该时刻的输出 yt y t 。对应的数学表达式为
b b 为偏差值。
作业中,我们要在rnn_layers.py文件下实现如下函数:
def rnn_step_forward(x, prev_h, Wx, Wh, b):
"""
输入:
- x: 外部输入数据, 维度 (N, D).
- prev_h: 上一个时刻的隐藏状态, 维度 (N, H)
- Wx: x对应的权值矩阵, 维度 (D, H)
- Wh: 隐藏状态h对应的权值矩阵, 维度 (H, H)
- b: 偏差值 shape (H,)
输出:
- next_h: 下一个时态的隐藏状态, 维度 (N, H)
- cache: 计算梯度反向传播时需要用到的变量.
"""
temp1 = np.dot(x,Wx)
temp2 = np.dot(prev_h,Wh)
cache=(x,prev_h,Wx,Wh,temp1+temp2+b)
next_h = np.tanh(temp1+temp2+b)
return next_h, cache
单层的前向传播并不难,实现的时候只要熟练使用numpy底下的矩阵运算即可。一个要注意的点是这里的激活函数是作用于向量中的每一个元素(element wise)。
2)梯度单步反向传播(RNN step backward)
可以说几乎所有训练神经网络的算法都是基于梯度下降(gradient descent)的,所以如何获得每个节点,以及相应的参数对应的梯度至关重要。正如之前的作业中训练神经网络时做的,求梯度反向传播其实只是在不断的应用求导的链式法则。假设最终的损失函数为
,在进行反向传播时,我们得到了上一层传来的梯度 dEdht d E d h t ,我们需要计算 dEdht−1 d E d h t − 1 , dEdxt d E d x t , dEdWxh d E d W x h , dEdWhh d E d W h h 和 dEdb d E d b 。还记得前向传播的公式为
假设 a=Whhht−1+Wxhxt+b a = W h h h t − 1 + W x h x t + b ,那么利用求导的链式法则,我们会有:
而 dhtda d h t d a 就是在对激活函数求导。