查看原文
其他

干货|《超智能体》作者会津博士YJango:循环神经网络—scan实现LSTM

2017-03-18 全球人工智能

全球人工智能


来源:知乎   作者:YJango


相关文章:

干货|《超智能体》作者会津博士YJango:如何利用循环神经网络实现LSTM?

【超智能体】循环神经网络(Recurrent)与前馈网络的差别及优劣

【AI技术】超智能体:人工神经网络●梯度下降训练法

【AI技术】超智能体:概率

超智能体:线性代数(会津大学博士:YJango著)


github原文阅读地址:《循环神经网络——代码LV1 》(https://yjango.gitbooks.io/superorganism/content/%E4%BB%A3%E7%A0%81%E6%BC%94%E7%A4%BA.html


注:从《人工神经网络》https://yjango.gitbooks.io/superorganism/content/ren_gong_shen_jing_wang_luo.html)后的内容就需要逐步阅读,没有相关知识而跳跃阅读是难以理解的。


上一节在《循环神经网络——实现LSTM》(https://yjango.gitbooks.io/superorganism/content/lstmgru.html)中介绍了循环神经网络目前最流行的实现方法LSTM和GRU,这一节就演示如何利用Tensorflow来搭建LSTM网络。


代码LV1是指本次的演示是最核心的code,并没有多余的功能。


为了更深刻的理解LSTM的结构,这次所用的并非是tensorflow自带的rnn_cell类,而是从新编写,并且用scan来实现graph里的loop (动态RNN)。


任务描述


这次所要学习的模型依然是代码演示LV3 (https://yjango.gitbooks.io/superorganism/content/%E4%BB%A3%E7%A0%81%E6%BC%94%E7%A4%BAlv3.html)中的用声音来预测口腔移动,没有阅读的朋友请先阅读链接中的章节对于任务的描述。同时拿链接中的前馈神经网络与循环神经网络进行比较。


处理训练数据


  • 目的:减掉每句数据的平均值,除以每句数据的标准差,降低模型拟合难度。


  • 代码:



  • 示意图:1,2,3,4,5表示list中的每个元素,而每个元素又是一个长度为2的list。


  • 解释:比如全部数据有100个序列,如果设定每个input的形状就是[1, n_steps, D_input],那么处理后的list的长度就是100,这样的数据使用的是SGD的更新方式。而如果想要使用mini-batch GD,将batch size(也就是n_samples)的个数为2,那么处理后的list的长度就会是50,每次网络训练时就会同时计算2个样本的梯度并用均值来更新权重。 因为每句语音数据的时间长短都不相同,如果使用3维tensor,需要大量的zero padding,所以将n_samples设成1。但是这样处理的缺点是:只能使用SGD,无法使用mini-batch GD。如果想使用mini-batch GD,需要几个n_steps长度相同的样本并在一起形成3维tensor(不等长时需要zero padding,如下图)。


  • 演示图:v表示一个维度为39的向量,序列1的n_steps的长度为3,序列2的为7,如果想把这三个序列并成3维tensor,就需要选择最大的长度作为n_steps的长度,将不足该长度的序列补零(都是0的39维的向量)。最后会形成shape为[3,7,39]的一个3维tensor。



权重初始化方法


  • 目的:合理的初始化权重,可以降低网络在学习时卡在鞍点或极小值的损害,增加学习速度和效果。


  • 代码:



  • 解释:其中shufflelists是用于洗牌重新排序list的。正交矩阵初始化是有利于gated_rnn的学习的方法。

定义LSTM类


  • 属性:使用class类来定义是因为LSTM中有大量的参数,定义成属性方便管理。


  • 代码:在init中就将所有需要学习的权重全部定义成属性



  • 解释:将hidden state和memory并在一起,以及将输入的形状变成[n_steps, n_samples, D_cell]是为了满足tensorflow中的scan的特点,后面会提到。


  • 每步计算方法:定义一个function,用于制定每一个step的计算。


  • 代码:



  • 解释:将上一时刻的hidden state和memory拆开,用于计算后,所出现的新的当前时刻的hidden state和memory会再次并在一起作为该function的返回值,同样是为了满足scan的特点。定义该function后,LSTM就已经完成了。one_step方法会使用LSTM类中所定义的parameters与当前时刻的输入和上一时刻的hidden state与memory cell计算当前时刻的hidden state和memory cell。


  • scan:使用scan逐次迭代计算所有timesteps,最后得出所有的hidden states进行后续的处理。


  • 代码:


  • 解释:scan接受的fn, elems, initializer有以下要求:


  1. fn:第一个输入是上一时刻的输出(需要与fn的返回值保持一致),第二个输入是当前时刻的输入。

  2. elems:scan方法每一步都会沿着所要处理的tensor的第一个维进行一次一次取值,所以要将数据由[n_samples, n_steps, D_cell]的形状变成[n_steps, n_samples, D_cell]的形状。

  3. initializer:初始值,需要与fn的第一个输入和返回值保持一致。

  4. scan的返回值在上例中是[n_steps, 2, n_samples, D_cell],其中第二个维度的2是由hidden state和memory cell组成的。

构建网络

  • 代码:


  • 解释:以hard coding的方式直接构建一个网络,输入是39维,第一个隐藏层也就是RNN-LSTM,1024维,而输出层又将1024维的LSTM的输出变换到24维与label对应。


  • 注: 这个网络并不仅仅取序列的最后一个值,而是要用所有timestep的值与实际轨迹进行比较计算loss


训练网络

  • 代码:

  • 解释:由于上文的LSTM是非常直接的编写方式,并不高效,在实际使用中会花费较长时间。

预测效果

  • 代码:


  • 解释:plot出一个样本中的维度的预测效果与真是轨迹进行对比


  • 效果图:



总结说明


该文是尽可能只展示LSTM最核心的部分(只训练了10次,有兴趣的朋友可以自己多训练几次),帮助大家理解其工作方式而已,完整代码可以从我的github中LSTM_lV1中找到。
该LSTM由于运行效率并不高,下一篇会稍微进行改动加快运行速度,并整理结构方便使用GRU以及多层RNN的堆叠以及双向RNN,同时加入其他功能。


GitHub资源:https://github.com/YJango/tensorflow/blob/master/RNN/LSTM_scan_LV1.ipynb


热门文章推荐

重磅|Google发布新开源图像算法工具Guetzli:压缩35%的图片大小仍保证高质量

重磅|3.15曝光的“人脸识别”技术真的那么脆弱吗?!

重磅|谷歌DeepMind将“记忆”植入机器学习,从而提高机器持续的自适应学习!

资源|28本必读的经典机器学习/数据挖掘书籍(免费下载)

活动|12位AI大佬齐聚ACM TURC 2017-中国(已开始报名)

恐怖|50 亿条用户隐私信息泄露,嫌犯竟是互联网名企工程师

干货|周志华揭开机器学习本质的57张PPT

重磅|百度PaddlePaddle发布最新API 从三大方面优化了性能

重磅|NVIDIA发布两款"深度神经网络训练"开发者产品:DIGITS 5 和 TensorRT

重磅|“萨德”——不怕!我国的人工智能巡航导弹可破解

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存