0%

CS231n笔记——循环神经网络

循环神经网络

背景

在批量归一化发明之前,20 层以上的深层卷积神经网络的训练非常困难。当年(2014 年)出现的深层卷积网络如 VGG 和 GoogleNet 都是采用了一些小技巧来让它收敛——

  • 如 VGG 采用先训练 11 层,然后在中间添加一些额外的随机层。
  • 在网络的下层添加一些辅助分类器。

这些都是为了获得额外的梯度,而不是为了更好地分类。

ResNet——残差神经网络,输入通过一些小的残差块,再进入到卷积层再得到输出。两个好的性质:

  • 如果残差块所有权值都设为 0,那么所有残差块都是恒等的。因此模型更容易训练。
  • 一旦添加了 L2 正则化,网络中的权值将迫使所有的参数趋近于 0,在残差网络中,将不再使用不需要的层。
  • 残差网络与反向路径中的梯度流有关,数据流既通过卷积层,又通过残差块形成梯度。残差块为梯度提供专用的“高速公路”,使网络训练更快更容易。

合理地管理梯度流,包括到 DenseNet 和 FractalNet 等深层网络,都是为梯度流建立了更直接的通路,使得梯度流动更好。

RNN 用来处理大小可变的有序数据,例如一对一,一对多,多对一,多对多,具体些,例如普通的图像分类、视频分类、图像文字描述、文字情感分析、语言文字转换等 RNN处理的数据类型 RNN 都有一个循环单元,接受一个输入 x,其有一个内部隐藏态,会在 RNN 每次读取新的输入时更新,然后当模型下一次读取时,会将结果反馈至模型。 读取输入-更新隐藏态-输出

\[ h_t=f_W(h_{t-1,x_t}) \]

\(h_t\)是新状态(新的隐藏态),\(h_{t-1}\)是旧状态(当前隐藏态),\(x_t\)是当前态(当前输入),\(f_W\)是带有权值 W 的某种循环关系 enter image description here Vanilla RNN:

\[ h_t=tanh(W_{hh}h_{t-1}+W_{xh}x_t)\\ y_t=W_{hy}h_t \]

语言模型

输入一个字符序列,让RNN学习,最终学习到它能预测下一个字符最可能是什么,逐渐学习到一些有趣的应用,比如生成莎士比亚风格的文章,比如生成拓扑代数的教科书,比如写代码,当然这些内容往往都没有实际意义,但是模型模仿的,至少在结构上有一定的相似度。

多层隐藏层的RNN,

一个个的RNN连起来,组成一个序列。\(h_0\)的梯度在每一次都会乘上一个权重矩阵,因此如果权重矩阵W的奇异值>1,梯度将指数爆炸增长;如果<1,梯度则将指数级减小。因此,为了防止梯度爆炸,我们采用一种叫梯度截断的方法——计算完梯度后,如果L2范式大于某个阈值,就将它剪断并做除法 grad = grad * (threshold / grad_norm) 梯度=梯度×(阈值/L2范式的值) 而对于梯度消失,常用的做法是换一个更复杂的RNN结构

LSTM 长短期记忆网络,RNN的更高级的递归结构,用来缓解梯度消失和梯度爆炸的问题,可以获得更好的梯度流动 LSTM中有两个隐藏变量,一个类似于vanilla的\(h_t\),另一个则是隐藏在LSTM内部,不会暴露出去的单元状态\(c_t\)

在LSTM中,使用当前输入\(x\)和当前隐藏状态\(h\)加上一个权重矩阵\(W\),来计算四个门:\(i,f,o,g\) - i 是输入门,表示要接受多少新的输入信息 - f 是遗忘门,表示要遗忘多少之前的单元记忆 - o 是输出门,表示要展示多少信息给外部 - g 叫门之门,表示有多少信息要写入到输入单元中去