双向RNN:bidirectional_dynamic_rnn()函数的使用详解


Posted in Python onJanuary 20, 2020

双向RNN:bidirectional_dynamic_rnn()函数的使用详解

先说下为什么要使用到双向RNN,在读一篇文章的时候,上文提到的信息十分的重要,但这些信息是不足以捕捉文章信息的,下文隐含的信息同样会对该时刻的语义产生影响。

举一个不太恰当的例子,某次工作会议上,领导进行“简洁地”总结,他会在第一句告诉你:“下面,为了节约时间,我简单地说两点…”,(…此处略去五百字…),“首先,….”,(…此处略去一万字…),“碍于时间的关系,我要加快速度了,下面我简要说下第二点…”(…此处再次略去五千字…)“好的,我想说的大概就是这些”(…此处又略去了二百字…),“谢谢大家!”如果将这篇发言交给一个单层的RNN网络去学习,因为“首先”和“第二点”中间隔得实在太久,等到开始学习“第二点”时,网络已经忘记了“简单地说两点”这个重要的信息,最终的结果就只剩下在风中凌乱了。。。于是我们决定加一个反向的网络,从后开始往前听,对于这层网络,他首先听到的就是“第二点”,然后是“首先”,最后,他对比了一下果然仅仅是“简要地两点”,在于前向的网络进行结合,就深入学习了领导的指导精神。

双向RNN:bidirectional_dynamic_rnn()函数的使用详解

上图是一个双向LSTM的结构图,对于最后输出的每个隐藏状态双向RNN:bidirectional_dynamic_rnn()函数的使用详解 都是前向网络和后向网络的元组,即双向RNN:bidirectional_dynamic_rnn()函数的使用详解 其中每一个双向RNN:bidirectional_dynamic_rnn()函数的使用详解 或者双向RNN:bidirectional_dynamic_rnn()函数的使用详解 又是一个由隐藏状态和细胞状态组成的元组(或者是concat)。同样最终的output也是需要将前向和后向的输出concat起来的,这样就保证了在最终时刻,无论是输出还是隐藏状态都是有考虑了上文和下文信息的。

下面就来看下tensorflow中已经集成的 tf.nn.bidirectional_dynamic_rnn() 函数。似乎双向的暂时只有这一个动态的RNN方法,不过想想也能理解,这种结构暂时也只会在encoder端出现,无论你的输入是pad到了定长或者是不定长的,动态RNN都是可以处理的。

具体的定义如下:

tf.nn.bidirectional_dynamic_rnn(
 cell_fw,
 cell_bw,
 inputs,
 sequence_length=None,
 initial_state_fw=None,
 initial_state_bw=None,
 dtype=None,
 parallel_iterations=None,
 swap_memory=False,
 time_major=False,
 scope=None
)

仔细看这个方法似乎和dynamic_rnn()没有太大区别,无非是多加了一个bw的部分,事实上也的确如此。先看下前向传播的部分:

with vs.variable_scope(scope or "bidirectional_rnn"):
 # Forward direction
 with vs.variable_scope("fw") as fw_scope:
  output_fw, output_state_fw = dynamic_rnn(
    cell=cell_fw, inputs=inputs, 
    sequence_length=sequence_length,
    initial_state=initial_state_fw, 
    dtype=dtype,
    parallel_iterations=parallel_iterations, 
    swap_memory=swap_memory,
    scope=fw_scope)

完全就是一个dynamic_rnn(),至于你选择LSTM或者GRU,只是cell的定义不同罢了。而双向RNN的核心就在于反向的bw部分。刚才说过,反向部分就是从后往前读,而这个翻转的部分,就要用到一个reverse_sequence()的方法,来看一下这一部分:

with vs.variable_scope("bw") as bw_scope:
 # ———————————— 此处是重点 ———————————— 
 inputs_reverse = _reverse(
   inputs, seq_lengths=sequence_length,
   seq_dim=time_dim, batch_dim=batch_dim)
 # ————————————————————————————————————
 tmp, output_state_bw = dynamic_rnn(
   cell=cell_bw, 
   inputs=inputs_reverse, 
   sequence_length=sequence_length,
   initial_state=initial_state_bw, 
   dtype=dtype,
   parallel_iterations=parallel_iterations,
   swap_memory=swap_memory,
   time_major=time_major, 
   scope=bw_scope)

我们可以看到,这里的输入不再是inputs,而是一个inputs_reverse,根据time_major的取值,time_dim和batch_dim组合的 {0,1} 取值正好相反,也就对应了时间维和批量维的词序关系。

而最终的输出:

outputs = (output_fw, output_bw)
output_states = (output_state_fw, output_state_bw)

这里还有最后的一个小问题,output_states是一个元组的元组,我个人的处理方法是用c_fw,h_fw = output_state_fw和c_bw,h_bw = output_state_bw,最后再分别将c和h状态concat起来,用tf.contrib.rnn.LSTMStateTuple()函数生成decoder端的初始状态。

以上这篇双向RNN:bidirectional_dynamic_rnn()函数的使用详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 按照固定长度分割字符串的方法小结
Apr 30 Python
Python列表推导式与生成器用法分析
Aug 02 Python
python机器学习之神经网络实现
Oct 13 Python
python实现flappy bird游戏
Dec 24 Python
Python英文文本分词(无空格)模块wordninja的使用实例
Feb 20 Python
Python3.5面向对象编程图文与实例详解
Apr 24 Python
python读取图片的几种方式及图像宽和高的存储顺序
Feb 11 Python
tensorflow将图片保存为tfrecord和tfrecord的读取方式
Feb 17 Python
解析pip安装第三方库但PyCharm中却无法识别的问题及PyCharm安装第三方库的方法教程
Mar 10 Python
Jupyter Notebook折叠输出的内容实例
Apr 22 Python
浅谈Python类的单继承相关知识
May 12 Python
Python利用Turtle绘制哆啦A梦和小猪佩奇
Apr 04 Python
关于tf.reverse_sequence()简述
Jan 20 #Python
tensorflow使用range_input_producer多线程读取数据实例
Jan 20 #Python
浅谈tensorflow中Dataset图片的批量读取及维度的操作详解
Jan 20 #Python
使用tensorflow DataSet实现高效加载变长文本输入
Jan 20 #Python
python机器学习库xgboost的使用
Jan 20 #Python
python 爬取马蜂窝景点翻页文字评论的实现
Jan 20 #Python
tensorflow-gpu安装的常见问题及解决方案
Jan 20 #Python
You might like
php部分常见问题总结
2008/03/27 PHP
使用php shell命令合并图片的代码
2011/06/23 PHP
PHP用PDO如何封装简单易用的DB类详解
2017/07/30 PHP
Ext javascript建立超链接,进行事件处理的实现方法
2009/03/22 Javascript
jquery插件开发注意事项小结
2013/06/04 Javascript
JavaScript异步编程:异步数据收集的具体方法
2013/08/19 Javascript
jQuery实现鼠标点击弹出渐变层的方法
2015/07/09 Javascript
jQuery Mobile弹出窗、弹出层知识汇总
2016/01/05 Javascript
基于BootStrap Metronic开发框架经验小结【六】对话框及提示框的处理和优化
2016/05/12 Javascript
微信小程序 video组件详解
2016/10/25 Javascript
AngularJS学习第二篇 AngularJS依赖注入
2017/02/13 Javascript
微信小程序 wx:for的使用实例详解
2017/04/27 Javascript
关于react-router的几种配置方式详解
2017/07/24 Javascript
Vue组件模板形式实现对象数组数据循环为树形结构(实例代码)
2017/07/31 Javascript
express框架实现基于Websocket建立的简易聊天室
2017/08/10 Javascript
理解 Node.js 事件驱动机制的原理
2017/08/16 Javascript
React Native 搭建开发环境的方法步骤
2017/10/30 Javascript
javascript实现数字配对游戏的实例讲解
2017/12/14 Javascript
vue指令只能输入正数并且只能输入一个小数点的方法
2018/06/08 Javascript
微信公众号生成新浪短网址的实现(快速生成)
2019/08/18 Javascript
基于Vue el-autocomplete 实现类似百度搜索框功能
2019/10/25 Javascript
vue实例的选项总结
2020/06/09 Javascript
[01:07:11]Secret vs Newbee 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
[01:05:52]DOTA2-DPC中国联赛 正赛 Ehome vs Aster BO3 第一场 2月2日
2021/03/11 DOTA
python实现拓扑排序的基本教程
2018/03/11 Python
python脚本实现验证码识别
2018/06/07 Python
Flask实现图片的上传、下载及展示示例代码
2018/08/03 Python
在django中图片上传的格式校验及大小方法
2019/07/28 Python
详解python中__name__的意义以及作用
2019/08/07 Python
解决pycharm上的jupyter notebook端口被占用问题
2019/12/17 Python
如何让pre和textarea等HTML元素去掉滚动条自动换行自适应文本内容高度
2019/08/01 HTML / CSS
洗手间标语
2014/06/23 职场文书
一般党员对照检查材料
2014/09/24 职场文书
在酒桌上的敬酒词
2015/08/12 职场文书
申论不会写怎么办?教您掌握这6点思维和原则
2019/07/17 职场文书
js作用域及作用域链工作引擎
2022/07/07 Javascript