1. 程式人生 > >tensorflow學習筆記(三十九) : 雙向rnn (BiRNN)

tensorflow學習筆記(三十九) : 雙向rnn (BiRNN)

雙向RNN實際上僅僅是兩個獨立的RNN放在一起, 本博文將介紹如何在tensorflow中實現雙向rnn

單層雙向rnn

這裡寫圖片描述

單層雙向rnn (cs224d)

tensorflow中已經提供了雙向rnn的介面,它就是tf.nn.bidirectional_dynamic_rnn(). 我們先來看一下這個介面怎麼用.

bidirectional_dynamic_rnn(
    cell_fw, #前向 rnn cell
    cell_bw, #反向 rnn cell
    inputs, #輸入序列.
    sequence_length=None,# 序列長度
    initial_state_fw=
None,#前向rnn_cell的初始狀態 initial_state_bw=None,#反向rnn_cell的初始狀態 dtype=None,#資料型別 parallel_iterations=None, swap_memory=False, time_major=False, scope=None )

返回值:一個tuple(outputs, outputs_states), 其中,outputs是一個tuple(outputs_fw, outputs_bw). 關於outputs_fwoutputs_bw,如果time_major=True

則它倆也是time_major的,vice versa. 如果想要concatenate的話,直接使用tf.concat(outputs, 2)即可.

如何使用:
bidirectional_dynamic_rnn 在使用上和 dynamic_rnn是非常相似的.

  1. 定義前向和反向rnn_cell
  2. 定義前向和反向rnn_cell的初始狀態
  3. 準備好序列
  4. 呼叫bidirectional_dynamic_rnn
import tensorflow as tf
from tensorflow.contrib import rnn
cell_fw = rnn.LSTMCell(10)
cell_bw =
rnn.LSTMCell(10) initial_state_fw = cell_fw.zero_state(batch_size) initial_state_bw = cell_bw.zero_state(batch_size) seq = ... seq_length = ... (outputs, states)=tf.nn.bidirectional_dynamic_rnn(cell_fw, cell_bw, seq, seq_length, initial_state_fw,initial_state_bw) out = tf.concat(outputs, 2) # ....

多層雙向rnn

這裡寫圖片描述

多層雙向rnn(cs224d)

單層雙向rnn可以通過上述方法簡單的實現,但是多層的雙向rnn就不能簡單的將MultiRNNCell傳給bidirectional_dynamic_rnn了.
想要知道為什麼,我們需要看一下bidirectional_dynamic_rnn的原始碼片段.

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,
        time_major=time_major, scope=fw_scope)

這只是一小部分程式碼,但足以看出,bi-rnn實際上是依靠dynamic-rnn實現的,如果我們使用MuitiRNNCell的話,那麼每層之間不同方向之間互動就被忽略了.所以我們可以自己實現一個工具函式,通過多次呼叫bidirectional_dynamic_rnn來實現多層的雙向RNN 這是我對多層雙向RNN的一個精簡版的實現,如有錯誤,歡迎指出

bidirectional_dynamic_rnn原始碼一探

上面我們已經看到了正向過程的程式碼實現,下面來看一下剩下的反向部分的實現.
其實反向的過程就是做了兩次reverse

  1. 第一次reverse:將輸入序列進行reverse,然後送入dynamic_rnn做一次運算.
  2. 第二次reverse:將上面dynamic_rnn返回的outputs進行reverse,保證正向和反向輸出 對應位置的 輸入是一致的 是對上的.
def _reverse(input_, seq_lengths, seq_dim, batch_dim):
  if seq_lengths is not None:
    return array_ops.reverse_sequence(
        input=input_, seq_lengths=seq_lengths,
        seq_dim=seq_dim, batch_dim=batch_dim)
  else:
    return array_ops.reverse(input_, axis=[seq_dim])

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)

output_bw = _reverse(
  tmp, seq_lengths=sequence_length,
  seq_dim=time_dim, batch_dim=batch_dim)

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

return (outputs, output_states)

tf.reverse_sequence

對序列中某一部分進行反轉

reverse_sequence(
    input,#輸入序列,將被reverse的序列
    seq_lengths,#1Dtensor,表示輸入序列長度
    seq_axis=None,# 哪維代表序列
    batch_axis=None, #哪維代表 batch
    name=None,
    seq_dim=None,
    batch_dim=None
)

官網上的例子給的非常好,這裡就直接貼上過來:

# Given this:
batch_dim = 0
seq_dim = 1
input.dims = (4, 8, ...)
seq_lengths = [7, 2, 3, 5]

# then slices of input are reversed on seq_dim, but only up to seq_lengths:
output[0, 0:7, :, ...] = input[0, 7:0:-1, :, ...]
output[1, 0:2, :, ...] = input[1, 2:0:-1, :, ...]
output[2, 0:3, :, ...] = input[2, 3:0:-1, :, ...]
output[3, 0:5, :, ...] = input[3, 5:0:-1, :, ...]

# while entries past seq_lens are copied through:
output[0, 7:, :, ...] = input[0, 7:, :, ...]
output[1, 2:, :, ...] = input[1, 2:, :, ...]
output[2, 3:, :, ...] = input[2, 3:, :, ...]
output[3, 2:, :, ...] = input[3, 2:, :, ...]

例二:

# Given this:
batch_dim = 2
seq_dim = 0
input.dims = (8, ?, 4, ...)
seq_lengths = [7, 2, 3, 5]

# then slices of input are reversed on seq_dim, but only up to seq_lengths:
output[0:7, :, 0, :, ...] = input[7:0:-1, :, 0, :, ...]
output[0:2, :, 1, :, ...] = input[2:0:-1, :, 1, :, ...]
output[0:3, :, 2, :, ...] = input[3:0:-1, :, 2, :, ...]
output[0:5, :, 3, :, ...] = input[5:0:-1, :, 3, :, ...]

# while entries past seq_lens are copied through:
output[7:, :, 0, :, ...] = input[7:, :, 0, :, ...]
output[2:, :, 1, :, ...] = input[2:, :, 1, :, ...]
output[3:, :, 2, :, ...] = input[3:, :, 2, :, ...]
output[2:, :, 3, :, ...] = input[2:, :, 3, :, ...]

參考資料

相關推薦

tensorflow學習筆記() : 雙向rnn (BiRNN)

雙向RNN實際上僅僅是兩個獨立的RNN放在一起, 本博文將介紹如何在tensorflow中實現雙向rnn 單層雙向rnn 單層雙向rnn (cs224d) tensorflow中已經提供了雙向rnn的介面,它就是tf.nn.bidirectional_dyna

opencv學習筆記:視訊讀寫

 VideoCapture:視訊抓取的類 VideoWriter :寫視訊的類 fps(frame per second)幀率:每秒抓取顯示多少幀 #include<opencv2\opencv.hpp> using namespace cv; int m

C#回顧學習筆記:事務

1)事務是什麼? 事務是保證多個操作全部成功時才認為是一次有效操作,當有一個操作失敗時就會認為全部操作無效,並且回到執行操作之前的狀態只有資料改變時(增加、修改、刪除)時才會引發事務,查詢不會引發事務。如果在寫入一個記錄時出現失敗,則事務會讓其他已經寫入的資料回滾,讓資料

機器學習筆記):TensorFlow實戰一(多執行緒輸入資料)

1 - 引言 為了加速模型訓練的時間,TensorFlow提供了一套多執行緒處理輸入資料的框架。 下面我們來詳細的介紹如何使用多執行緒來加速我們的模型訓練速度 2 - 佇列與多執行緒 在TensorFlow中,佇列和變數類似,我們可以修改它們的狀態。下面給出一個示例來展示如

【Unity 3D】學習筆記:遊戲元素——遊戲地形

nbsp 3d遊戲 strong 直觀 分辨率 == 摩擦力 fill 世界 遊戲地形 在遊戲的世界中,必然會有非常多豐富多彩的遊戲元素融合當中。它們種類繁多。作用也不大同樣。一般對於遊戲元素可分為兩種:經經常使用。不經經常使用。經常使用的元素是遊戲中比較重要的元素。一

tensorflow學習筆記():實現自編碼器

sea start ear var logs cos soft 編碼 red 黃文堅的tensorflow實戰一書中的第四章,講述了tensorflow實現多層感知機。Hiton早年提出過自編碼器的非監督學習算法,書中的代碼給出了一個隱藏層的神經網絡,本人擴展到了多層,改進

Python學習筆記

插入 imp 集合類 屬性 counter 以及 雙向 ror 簡單的 一、collections介紹   collections是Python中內建的一個集合模塊,提供了許多有用的集合類 二、namedtuple   namedtuple是一個函數,用來創建一個類似類的自

Python學習)—— Django之Form組件

tran important edi 日期 style p s ext 一個 這樣的 一、構建一個表單 假設你想在你的網站上創建一個簡單的表單,以獲得用戶的名字。你需要類似這樣的模板: <form action="/your-name/" method="post"

python學習筆記)面向對象編程,類

時代 alt 類名 rst tps 玉溪 connect nbsp nco 一、面向對象編程 面向對象,是一種程序設計思想。 編程範式:編程範式就是你按照什麽方式去編程,去實現一個功能。不同的編程範式本質上代表對各種類型的任務采取的不同的解決問題的思路,兩種最重要的編程範式

Linux學習筆記)文件壓縮

文件壓縮一、常見的壓縮文件 Windows .rar .zip .7z Linux .zip,.gz,.bz2,.xz,.tar.gz,.tar.bz2,.tar.xz文件壓縮可以節省內存,也可以節省傳輸速度 二、gzip首先創建了一個文件夾 /tmp/d6z/找了些比較大的文件寫入1.txt例如find

學習筆記節課

作業zip壓縮工具 zip支持壓縮目錄。windows下有zip的工具和文件。 linux下默認不支持解壓windows下rar文件,需要安裝工具。 先把root下的234目錄 cp到當前目錄下。 然後把4.txt也cp過來 這樣目錄的內容比較多。 zip的壓縮文件 和gzip 。dzip2 不一樣。

c++ primer第五版----學習筆記)Ⅱ

部分習題解答: 19.1、19.2: #include <iostream> #include <cstdlib> using namespace std; void *operator new(size_t size) { cout << "new(

c++ primer第五版----學習筆記)Ⅰ

文章目錄 ==特殊工具與技術== 1.控制記憶體分配 1.1 過載new和delete 1.2 定位new表示式 2. 執行時型別識別 2.1 dynamic_cast運算子 2.2 typeid運算子

Tensorflow學習筆記()——邏輯迴歸

首先,邏輯迴歸是一個二分類,而mnist是一個十分類,因此我們要做一個多分類的任務,引入一個知識softmax分類器。 softmax分類器公式如下: 舉個例子: 一、接下來準備資料集。 import numpy as np import tensorflow as tf imp

學習筆記第二節:動態Dp

正題       因為NOIP2018考了這一個東西,所以不得不學。       我們以這一題為例題來引入今天的學習:【模板】動態dp       我們顯然可以用樹形Dp去做,倒不如我們先把方程

opencv學習筆記:SIFT特徵點檢測與匹配

SIFT(Scale-invariant feature transform)是一種檢測區域性特徵的演算法,該演算法通過求一幅圖中的特徵點(interest points,or corner points)及其有關scale 和 orientation 的描述子得到特徵並進行

opencv學習筆記二:Haar特徵與積分影象

一、 Haar特徵定義         Haar特徵是基於“塊”的特徵,也被稱為矩形特徵。Haar特徵(模板)分為三類:邊緣特徵、線性特徵、中心特徵和對角線特徵。特徵模板內有白色和黑色兩種矩形,並定義該模板的特徵值為白色矩形畫素和減去黑色矩形畫素和。Haar特徵值反映了影象

opencv學習筆記六:AKAZE特徵點檢測與匹配

KAZE是日語音譯過來的 , KAZE與SIFT、SURF最大的區別在於構造尺度空間,KAZE是利用非線性方式構造,得到的關鍵點也就更準確(尺度不變性 ); Hessian矩陣特徵點檢測 ,方向指定,基於一階微分影象(旋轉不變性 ) ; 描述子生成 ,歸一化處理(光照不變

opencv學習筆記:基於距離變換和區域性自適應閾值的物件計數

案例背景:統計下圖中玉米粒的個數 方案思路:先灰度化,再二值化(基於THRESH_TRIANGLE,圖中直方圖有明顯的雙峰值),腐蝕去掉一些小雜點,距離變換,再自適應區域性閾值,膨脹連成連通域,尋找輪廓進行計數。 距離變換於1966年被學者首次提出,目前已被廣泛應

opencv學習筆記:影象融合之背景替換

以證件照為例,圖片中有大部分為背景,先用kmeans對影象進行分割,可以得到背景的標籤,然後將影象分為前景和背景兩部分,非背景的都當作前景,顯示kmeans分割後的影象dst,將原影象前景賦給dst, 背景都設為0,得到kmeans分割後的影象如下,可看到邊緣處有一些小藍邊,