雙向RNN:bidirectional_dynamic_rnn()函數(shù)的使用詳解
雙向RNN:bidirectional_dynamic_rnn()函數(shù)的使用詳解
先說下為什么要使用到雙向RNN,在讀一篇文章的時(shí)候,上文提到的信息十分的重要,但這些信息是不足以捕捉文章信息的,下文隱含的信息同樣會(huì)對(duì)該時(shí)刻的語義產(chǎn)生影響。
舉一個(gè)不太恰當(dāng)?shù)睦?,某次工作?huì)議上,領(lǐng)導(dǎo)進(jìn)行“簡(jiǎn)潔地”總結(jié),他會(huì)在第一句告訴你:“下面,為了節(jié)約時(shí)間,我簡(jiǎn)單地說兩點(diǎn)…”,(…此處略去五百字…),“首先,….”,(…此處略去一萬字…),“礙于時(shí)間的關(guān)系,我要加快速度了,下面我簡(jiǎn)要說下第二點(diǎn)…”(…此處再次略去五千字…)“好的,我想說的大概就是這些”(…此處又略去了二百字…),“謝謝大家!”如果將這篇發(fā)言交給一個(gè)單層的RNN網(wǎng)絡(luò)去學(xué)習(xí),因?yàn)椤笆紫取焙汀暗诙c(diǎn)”中間隔得實(shí)在太久,等到開始學(xué)習(xí)“第二點(diǎn)”時(shí),網(wǎng)絡(luò)已經(jīng)忘記了“簡(jiǎn)單地說兩點(diǎn)”這個(gè)重要的信息,最終的結(jié)果就只剩下在風(fēng)中凌亂了。。。于是我們決定加一個(gè)反向的網(wǎng)絡(luò),從后開始往前聽,對(duì)于這層網(wǎng)絡(luò),他首先聽到的就是“第二點(diǎn)”,然后是“首先”,最后,他對(duì)比了一下果然僅僅是“簡(jiǎn)要地兩點(diǎn)”,在于前向的網(wǎng)絡(luò)進(jìn)行結(jié)合,就深入學(xué)習(xí)了領(lǐng)導(dǎo)的指導(dǎo)精神。
上圖是一個(gè)雙向LSTM的結(jié)構(gòu)圖,對(duì)于最后輸出的每個(gè)隱藏狀態(tài) 都是前向網(wǎng)絡(luò)和后向網(wǎng)絡(luò)的元組,即
其中每一個(gè)
或者
又是一個(gè)由隱藏狀態(tài)和細(xì)胞狀態(tài)組成的元組(或者是concat)。同樣最終的output也是需要將前向和后向的輸出concat起來的,這樣就保證了在最終時(shí)刻,無論是輸出還是隱藏狀態(tài)都是有考慮了上文和下文信息的。
下面就來看下tensorflow中已經(jīng)集成的 tf.nn.bidirectional_dynamic_rnn() 函數(shù)。似乎雙向的暫時(shí)只有這一個(gè)動(dòng)態(tài)的RNN方法,不過想想也能理解,這種結(jié)構(gòu)暫時(shí)也只會(huì)在encoder端出現(xiàn),無論你的輸入是pad到了定長(zhǎng)或者是不定長(zhǎng)的,動(dòng)態(tài)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 )
仔細(xì)看這個(gè)方法似乎和dynamic_rnn()沒有太大區(qū)別,無非是多加了一個(gè)bw的部分,事實(shí)上也的確如此。先看下前向傳播的部分:
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)
完全就是一個(gè)dynamic_rnn(),至于你選擇LSTM或者GRU,只是cell的定義不同罷了。而雙向RNN的核心就在于反向的bw部分。剛才說過,反向部分就是從后往前讀,而這個(gè)翻轉(zhuǎn)的部分,就要用到一個(gè)reverse_sequence()的方法,來看一下這一部分:
with vs.variable_scope("bw") as bw_scope: # ———————————— 此處是重點(diǎn) ———————————— 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,而是一個(gè)inputs_reverse,根據(jù)time_major的取值,time_dim和batch_dim組合的 {0,1} 取值正好相反,也就對(duì)應(yīng)了時(shí)間維和批量維的詞序關(guān)系。
而最終的輸出:
outputs = (output_fw, output_bw) output_states = (output_state_fw, output_state_bw)
這里還有最后的一個(gè)小問題,output_states是一個(gè)元組的元組,我個(gè)人的處理方法是用c_fw,h_fw = output_state_fw和c_bw,h_bw = output_state_bw,最后再分別將c和h狀態(tài)concat起來,用tf.contrib.rnn.LSTMStateTuple()函數(shù)生成decoder端的初始狀態(tài)。
以上這篇雙向RNN:bidirectional_dynamic_rnn()函數(shù)的使用詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python 定義給定初值或長(zhǎng)度的list方法
今天小編就為大家分享一篇python 定義給定初值或長(zhǎng)度的list方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-06-06vscode 配置 python3開發(fā)環(huán)境的方法
這篇文章主要介紹了vscode 配置 python3開發(fā)環(huán)境的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09Python中一個(gè)for循環(huán)循環(huán)多個(gè)變量的示例
今天小編就為大家分享一篇Python中一個(gè)for循環(huán)循環(huán)多個(gè)變量的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-07-07Python3+OpenCV實(shí)現(xiàn)簡(jiǎn)單交通標(biāo)志識(shí)別流程分析
這篇文章主要介紹了Python3+OpenCV實(shí)現(xiàn)簡(jiǎn)單交通標(biāo)志識(shí)別,主要思路是解析XML文檔,根據(jù)<name>標(biāo)簽進(jìn)行分類,如果是直行、右轉(zhuǎn)、左轉(zhuǎn)、停止就把它從原圖中裁剪下來并重命名,感謝的朋友跟隨小編一起看看示例代碼2021-12-12matplotlib.subplot()畫子圖并共享y坐標(biāo)軸的方法
Matplotlib的可以把很多張圖畫到一個(gè)顯示界面,本文主要介紹matplotlib.subplot()畫子圖并共享y坐標(biāo)軸的方法,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05Python中使用Flask、MongoDB搭建簡(jiǎn)易圖片服務(wù)器
這篇文章主要介紹了Python中使用Flask、MongoDB搭建簡(jiǎn)易圖片服務(wù)器,本文是一個(gè)詳細(xì)完整的教程,需要的朋友可以參考下2015-02-02Python的Scrapy爬蟲框架簡(jiǎn)單學(xué)習(xí)筆記
這篇文章主要介紹了Python的Scrapy爬蟲框架簡(jiǎn)單學(xué)習(xí)筆記,從基本的創(chuàng)建項(xiàng)目到CrawlSpider的使用等都有涉及,需要的朋友可以參考下2016-01-01