这周主要研读了HMN中reference的一篇论文TRL,经过学习对比发现TRL中的很多思想都在HMN中有所借鉴,看完TRL后对HMN中的一些问题理解也更加的透彻;因为这周需要集中对深度学习基础进行学习,因此回顾复习了一些深度学习的基础知识。
每当我们听到神经网络时,就会认为它里面有许许多多的隐藏层,但其实还有一种只有少量隐藏层的神经网络,浅神经网络只包含一到两层隐藏层。对浅神经网络的研究可以加强我们对深度神经网络内部运行机制的理解。下图所示是一个只包含一个隐藏层、一个输入层和一个输出层的浅神经网络:
神经元是神经网络中的原子单元。给定神经元一个输入,它将得到对应的输出,并将其作为下一层的输入。一个神经元可以认为是以下两部分的结合:
隐藏层由许多神经元组成,每一个都会执行上述两步运算。在上图的浅层神经网络中,隐藏层的四个神经元进行如下计算:
在上面的方程中:
显而易见,上述四个方程比较冗长,因此我们把它们进行向量化:
对于人脸识别等应用,神经网络的第一层从原始图片中提取人脸的轮廓和边缘,每个神经元学习到不同边缘的信息;网络的第二层将第一层学得的边缘信息组合起来,形成人脸的一些局部的特征,例如眼睛、嘴巴等;后面的几层逐步将上一层的特征组合起来,形成人脸的模样。随着神经网络层数的增加,特征也从原来的边缘逐步扩展为人脸的整体,由整体到局部,由简单到复杂。层数越多,那么模型学习的效果也就越精确。
通过例子可以看到,随着神经网络的深度加深,模型能学习到更加复杂的问题,功能也更加强大。
以单个样本来进行表示,每层经过线性计算和激活函数两步计算
z [ 1 ] = W [ 1 ] x + b [ 1 ] , a [ 1 ] = g [ 1 ] ( z [ 1 ] ) z^{[1]}=W^{[1]}x+b^{[1]},a^{[1]}=g^{[1]}(z^{[1]}) z[1]=W[1]x+b[1],a[1]=g[1](z[1])
z [ 2 ] = W [ 2 ] a [ 1 ] + b [ 2 ] , a [ 2 ] = g [ 2 ] ( z [ 2 ] ) z^{[2]}=W^{[2]}a^{[1]}+b^{[2]},a^{[2]}=g^{[2]}(z^{[2]}) z[2]=W[2]a[1]+b[2],a[2]=g[2](z[2])
z [ 3 ] = W [ 3 ] a [ 2 ] + b [ 3 ] , a [ 3 ] = g [ 3 ] ( z [ 3 ] ) z^{[3]}=W^{[3]}a^{[2]}+b^{[3]},a^{[3]}=g^{[3]}(z^{[3]}) z[3]=W[3]a[2]+b[3],a[3]=g[3](z[3])
z [ 4 ] = W [ 4 ] a [ 3 ] + b [ 4 ] , a [ 4 ] = g [ 4 ] ( z [ 4 ] ) z^{[4]}=W^{[4]}a^{[3]}+b^{[4]},a^{[4]}=g^{[4]}(z^{[4]}) z[4]=W[4]a[3]+b[4],a[4]=g[4](z[4])
将上式简单的用通用公式表达出来:
z [ L ] = W [ L ] a [ L − 1 ] + b [ L ] , a [ L ] = g [ L ] ( z [ L ] ) z^{[L]}=W^{[L]}a^{[L-1]}+b^{[L]},a^{[L]}=g^{[L]}(z^{[L]}) z[L]=W[L]a[L−1]+b[L],a[L]=g[L](z[L]),输入 a [ L − 1 ] a^{[L-1]} a[L−1],输出 a [ L ] a^{[L]} a[L]
单个样本的反向传播:
d Z [ l ] = d J d a [ l ] d a [ l ] d Z [ l ] = d a [ l ] ∗ g [ l ] ′ ( Z [ l ] ) dZ^{[l]}=\frac{dJ}{da^{[l]}}\frac{da^{[l]}}{dZ^{[l]}}=da^{[l]}*{g^{[l]}}'(Z^{[l]}) dZ[l]=da[l]dJdZ[l]da[l]=da[l]∗g[l]′(Z[l])
d W [ l ] = d J d Z [ l ] d Z [ l ] d W [ l ] = d Z [ l ] ∗ a [ l − 1 ] dW^{[l]}=\frac{dJ}{dZ^{[l]}}\frac{dZ^{[l]}}{dW^{[l]}}=dZ^{[l]}*a^{[l-1]} dW[l]=dZ[l]dJdW[l]dZ[l]=dZ[l]∗a[l−1]
d b [ l ] = d J d Z [ l ] d Z [ l ] d b [ l ] = d Z [ l ] db^{[l]}=\frac{dJ}{dZ^{[l]}}\frac{dZ^{[l]}}{db^{[l]}}=dZ^{[l]} db[l]=dZ[l]dJdb[l]dZ[l]=dZ[l]
d a [ l − 1 ] = W [ l ] T ⋅ d Z [ l ] da^{[l-1]}=W^{[l]T}\cdot dZ^{[l]} da[l−1]=W[l]T⋅dZ[l]
多个样本的反向传播:
d Z [ l ] = d A [ l ] ∗ g [ l ] ′ ( Z [ l ] ) dZ^{[l]}=dA^{[l]}*{g^{[l]}}'(Z^{[l]}) dZ[l]=dA[l]∗g[l]′(Z[l])
d W [ l ] = 1 m d Z [ l ] ⋅ A [ l − 1 ] T dW^{[l]}=\frac{1}{m}dZ^{[l]}\cdot A^{[l-1]T} dW[l]=m1dZ[l]⋅A[l−1]T
d b [ l ] = 1 m n p ⋅ s u m ( d Z [ l ] , a x i s = 1 ) db^{[l]}=\frac{1}{m}np\cdot sum(dZ^{[l]},axis=1) db[l]=m1np⋅sum(dZ[l],axis=1)
d A [ l ] = W [ l + 1 ] T ⋅ d Z [ l + 1 ] dA^{[l]}=W^{[l+1]T}\cdot dZ^{[l+1]} dA[l]=W[l+1]T⋅dZ[l+1]
参数即是我们在过程中想要模型学习到的信息(模型自己能计算出来的),例如 W [ l ] , b [ l ] W^{[l]},b^{[l]} W[l],b[l]。而超参数(hyper parameters)即为控制参数的输出值的一些网络信息(需要人经验判断)。超参数的改变会导致最终得到的参数 W [ l ] , b [ l ] W^{[l]},b^{[l]} W[l],b[l]的改变。
典型的超参数有:
如果在初始时将两个隐藏神经元的参数设置为相同的大小,那么两个隐藏神经元对输出单元的影响也是相同的,通过反向梯度下降去进行计算的时候,会得到同样的梯度大小,所以在经过多次迭代后,两个隐藏层单位仍然是对称的。无论设置多少个隐藏单元,其最终的影响都是相同的,那么多个隐藏神经元就没有了意义。
在初始化的时候,W 参数要进行随机初始化,不可以设置为 0。b 因为不存在上述问题,可以设置为 0。
长短期记忆(Long short-term memory, LSTM)是一种特殊的RNN,主要是为了解决长序列训练过程中的梯度消失和梯度爆炸问题。简单来说,就是相比普通的RNN,LSTM能够在更长的序列中有更好的表现。
LSTM结构(图右)和普通RNN的主要输入输出区别如下所示。
相比RNN只有一个传递状态 h t h^t ht ,LSTM有两个传输状态,一个 c t c^t ct(cell state),和一个 h t h^t ht(hidden state)。(Tips:RNN中的 h t h^t ht 对于LSTM中的 c t c^t ct )
其中对于传递下去的 c t c^t ct 改变得很慢,通常输出的 c t c^t ct 是上一个状态传过来的 c t − 1 c^{t-1} ct−1 加上一些数值。
而 h t h^t ht 则在不同节点下往往会有很大的区别。
首先使用LSTM的当前输入 x t x^t xt 和上一个状态传递下来的 h t − 1 h^{t-1} ht−1 拼接训练得到四个状态。
其中, z f , z i , z o z^f,z^i,z^o zf,zi,zo 是由拼接向量乘以权重矩阵之后,再通过一个 s i g m o i d sigmoid sigmoid 激活函数转换成0到1之间的数值,来作为一种门控状态。而 z z z 则是将结果通过一个 t a n h tanh tanh 激活函数将转换成-1到1之间的值(这里使用 t a n h tanh tanh 是因为这里是将其做为输入数据,而不是门控信号)。
⊙ \odot ⊙是矩阵对应元素相乘,要求两个相乘矩阵是同型的。 ⊕ \oplus ⊕是矩阵对应元素相加。
LSTM内部主要有三个阶段:
与普通RNN类似,输出 y t y^t yt 往往最终也是通过 h t h^t ht 变化得到。
以上,就是LSTM的内部结构。通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;而不像普通的RNN那样仅有一种记忆叠加方式。对很多需要“长期记忆”的任务来说,尤其好用。但也因为引入了很多内容,导致参数变多,也使得训练难度加大了很多。