从Tensorflow代码中理解LSTM网络
来源:互联网 发布:手机数据采集软件 编辑:程序博客网 时间:2024/06/05 17:19
目录
- RNN
- LSTM
参考文档与引子
缩略词
RNN (Recurrent neural network) 循环神经网络
LSTM (Long short-term memory) 长短期记忆人工神经网络
当我们在谷歌搜索LSTM这个关键字时,搜索结果的第一条就是一篇非常著名的博客 Understanding LSTM Networks 来介绍LSTM网络,这篇博客的作者是 Christopher Olah,在谷歌 Google Brain 工作。这篇博客的中文翻译版为 [译] 理解 LSTM 网络。
Tensorflow是一个由谷歌开发的基于Python语言的开源机器学习库。它具有跨平台(手机/个人电脑/服务器都可使用,CPU/GPU随意切换),高效率,高度自定义化,可以充分利用计算机性能等特点,在近几年中越来越受到机器学习研究者的喜欢,许多大公司也都在使用Tensorflow,诸如 ARM,snapchat,Uber,京东 等。
在本篇博客中,我将尝试通过解释Tensorflow中RNN/LSTM部分的源码来帮助大家深入理解LSTM网络的运作,同时也是为了来帮助我自己更好的理解LSTM网络。这是本人尝试写的第一篇博客,欢迎大家来加来指正文中的错误或者不合理之处,也欢迎提出各种各样的建议或意见。谢谢!
LSTM与RNN的关系
有一篇非常有名的博客The Unreasonable Effectiveness of Recurrent Neural Networks 详细介绍了什么是RNN并且作者开源一个基于LSTM的多层RNN神经网络项目(使用了Torch),强烈建议没有看过的人或者对于RNN概念不是非常清楚的人进来看看。这篇博客还有中文翻译版本:链接
LSTM从本质上来说并不是一个完整的神经网络模型,它其实是对RNN神经网络中的神经元/隐含单元(CELL/Hidden unit)的一种变形与改进。在这种改变当中,LSTM在神经元中加入了一个状态(State)的概念用来储存长期的记忆(具体LSTM结构将会在博客的后面有介绍)。在很多网上面介绍LSTM的教程或者博客当中,他们其实都只给了LSTM神经元的结构,这是属于RNN框架中的一部分。所以说如果想要理解LSTM我们首先需要理解什么是RNN。
RNN
本篇博客的主要目的是在于将Tensorflow中的代码与LSTM和RNN的理论公式对接起来。让大家可以更容易的使用Tensorflow来开发属于自己的神经网络,或者让大家可以对LSTM与RNN有一个更加直观的从代码方面的理解。所以说本博客假设读者已经对LSTM与RNN有一定的了解,我将会直接从图片开始来解读RNN和LSTM。对于那些对RNN和LSTM没有概念的人,我建议可以从参考文档中的那篇博客开始读起。
首先让我们从全局查看RNN神经网络是如何运作的
RNN 网络图中的
下面让我们取上图中最中间的神经元为例来分析普通RNN神经元中的运作方式:
RNN 神经元/隐含单元(CELL / Hidden unit)图中的
基础等式
对应的Tensorflow代码(Github)
def __call__(self, inputs, state, scope=None): """Most basic RNN: output = new_state = activation(W * input + U * state + B).""" with vs.variable_scope(scope or type(self).__name__): # "BasicRNNCell" output = self._activation(_linear([inputs, state], self._num_units, True)) return output, output
上述代码块对应的就是一个普通RNN神经元中的操作
"""Most basic RNN: output = new_state = activation(W * input + U * state + B)."""
下面是上述代码中的变量与基础等式中的变量的对应表
代码变量基础等式变量new_stateoutput = self._activation(_linear([inputs, state], self._num_units, True))
下面是上述代码对应的解释
代码解释self._activation()激活函数,等同于基础等式中的_linear([a,b], num_units, True)
= =
我们首先假设我们数据
批尺寸(batch size) = 10
输入数据大小(input size)= 300
隐含单元数(number of unit)= 200
那么
[输入数据大小(input size)300, 单元数(number of unit)200]
[隐含单元数(number of unit)200,隐含单元数(number of unit)200]
[批尺寸大小(batch size)10, 输入数据大小(input size)300]
[批尺寸大小(batch size)10, 隐含单元数(number of unit)200]
[隐含单元数(number of unit)200]
(注意:在tensorflow代码当中,实际上tensorflow做的操作是
[批尺寸大小(batch size)10, 隐含单元数(number of unit)200]
,但是 [隐含单元数(number of unit)200]
,他们的大小无法匹配,但是tensorflow却可以把他们相加,这是因为tensorflow只是使用同样的 [[1,2],[3,4]] + [1,1] = [[2,3],[4,5]]
。)inputsstate这里的inputs就等同于上面解释的
LSTM
下面让我们看一看LSTM,首先我们来看一下LSTM神经元的内部结构:
LSTM 神经元/隐含单元(CELL / Hidden unit)与RNN一样,图中的
基础等式
对应的Tensorflow代码(Github)
def __call__(self, inputs, state, scope=None): """Long short-term memory cell (LSTM).""" with vs.variable_scope(scope or type(self).__name__): # "BasicLSTMCell" # Parameters of gates are concatenated into one multiply for efficiency. if self._state_is_tuple: c, h = state else: c, h = array_ops.split(1, 2, state) concat = _linear([inputs, h], 4 * self._num_units, True) # i = input_gate, j = new_input, f = forget_gate, o = output_gate i, j, f, o = array_ops.split(1, 4, concat) new_c = (c * sigmoid(f + self._forget_bias) + sigmoid(i) * self._activation(j)) new_h = self._activation(new_c) * sigmoid(o) if self._state_is_tuple: new_state = LSTMStateTuple(new_c, new_h) else: new_state = array_ops.concat(1, [new_c, new_h]) return new_h, new_state
下面列表是上面代码中的变量的大小与解释
变量名对应的基础等式变量大小(shape)解释inputs[批尺寸大小(batch size), 输入数据大小(input size)]
输入的数据([批尺寸大小(batch size), 隐含单元数(number of unit)]
,[批尺寸大小(batch size), 隐含单元数(number of unit)]
)这个一个tuple数据类型,储存了上一个时间段也就是旧的记忆单元([批尺寸大小(batch size), 隐含单元数(number of unit)]
旧的记忆单元([批尺寸大小(batch size), 隐含单元数(number of unit)]
旧的隐含状态([批尺寸大小(batch size), 隐含单元数(number of unit)]
Input Gatej[批尺寸大小(batch size), 隐含单元数(number of unit)]
Input Modulation Gate 也就是代码解释中的new_inputf[批尺寸大小(batch size), 隐含单元数(number of unit)]
Forget Gateo[批尺寸大小(batch size), 隐含单元数(number of unit)]
Output Gatenew_c[批尺寸大小(batch size), 隐含单元数(number of unit)]
新的记忆单元([批尺寸大小(batch size), 隐含单元数(number of unit)]
新的隐含状态(concat = _linear([inputs, h], 4 * self._num_units, True)
上述代码的_linear
函数与之前RNN代码中的_linear
函数一样。在函数里面,tensorflow会自动创建基础等式中相应的
i, j, f, o = array_ops.split(1, 4, concat)
由于在上面的_linear
函数中,tensorflow将input gate, input modulation gate, forget gate和output gate串联到了一起,并且他们的大小都是一致的为[批尺寸大小(batch size), 隐含单元数(number of unit)]
。所以在这个步骤当中,tensorflow通过切割数组单独获取了input gate, input modulation gate, forget gate和output gate的值。
new_c = (c * sigmoid(f + self._forget_bias) + sigmoid(i) * self._activation(j))
这一段代码对应的正是基础等式中的等式
new_h = self._activation(new_c) * sigmoid(o)
这一段代码对应的则是基础等式中的
结束语
至此我们应该对LSTM有了一定程度上的理解,欢迎读者们在下方评论区留言发表修改意见。谢谢!
原文地址: http://gdf.name/lstm-with-tensorflow/
- 从Tensorflow代码中理解LSTM网络
- tensorflow中对lstm及双向lstm的理解
- 从理解RNN到LSTM 网络
- LSTM 网络中几个门的理解
- tensorflow中lstm学习
- 理解LSTM网络
- 理解LSTM网络
- 理解LSTM网络
- 理解LSTM网络
- 理解LSTM网络
- 理解 LSTM 网络
- 理解LSTM网络
- 理解LSTM网络
- 理解 LSTM 网络
- 理解LSTM网络
- 理解 LSTM 网络
- 理解 LSTM 网络
- 理解 LSTM 网络
- Qt信号槽传递自定义类型参数
- android的m、mm、mmm编译命令的使用
- Google 面试题:最优交易次数
- 接口与内部类
- PHP命名空间解惑
- 从Tensorflow代码中理解LSTM网络
- 10月集训test16
- opencv学习调整图像对比度
- Java8 Function和BiFunction
- Linux下Hadoop2.7.1集群环境的搭建(超详细版)
- scrapy 抓取内涵社区
- AC自动机+有向拓扑判环 Taboo Kattis
- AsyncTask的基础使用
- 机器学习实现双十一购物清单的自动商品标签归类