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

作者:Cerisier 时间:2022-07-26 17:42:07 

双向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端的初始状态。

来源:https://blog.csdn.net/Cerisier/article/details/80135999

标签:双向RNN,bidirectional,dynamic,rnn
0
投稿

猜你喜欢

  • 关于《回访确认》的几个问题

    2009-08-24 12:43:00
  • python打包压缩、读取指定目录下的指定类型文件

    2021-01-19 08:23:26
  • 解决pyinstaller打包exe文件出现命令窗口一闪而过的问题

    2021-09-28 01:03:45
  • Pycharm中的下载安装、配置与测试方式

    2023-11-18 01:53:27
  • FrontPage 2002应用技巧四则

    2008-08-17 10:57:00
  • python进行相关性分析并绘制散点图详解

    2023-02-25 14:45:54
  • Python图像处理之透视变换的实战应用

    2022-08-16 17:22:10
  • 自适应网页设计(Responsive Web Design)

    2012-05-02 10:49:07
  • Python实现获取照片拍摄日期并重命名的方法

    2023-04-14 03:26:37
  • Python cookbook(数据结构与算法)将名称映射到序列元素中的方法

    2021-06-06 01:26:54
  • python 利用panda 实现列联表(交叉表)

    2022-02-21 02:24:32
  • 详解Python的循环结构知识点

    2021-09-30 11:42:03
  • asp中数组的用法

    2008-05-12 22:29:00
  • JSP分页显示的实例代码

    2023-06-26 06:06:37
  • asp如何用组件实现自动发送电子邮件?

    2010-06-16 09:56:00
  • 报错No module named numpy问题的解决办法

    2023-09-20 12:02:07
  • python开发游戏的前期准备

    2022-01-06 12:58:01
  • Python编程之变量赋值操作实例分析

    2021-09-20 12:12:01
  • Python实现敏感词过滤的4种方法

    2021-10-01 06:21:08
  • 在Python的Django框架中生成CSV文件的方法

    2023-07-18 01:13:24
  • asp之家 网络编程 m.aspxhome.com