當前位置:
首頁 > 知識 > 如何用Tensorflow實現RNN?本文將帶你進一步研究

如何用Tensorflow實現RNN?本文將帶你進一步研究

更多深度文章,請關註:https://yq.aliyun.com/cloud



在這篇文章中,我將介紹與構建循環神經網路最相關的tensorflow API。 tensorflow文檔很好地解釋了如何構建標準的RNN,但是對於構建個性化的RNN而言,它還是有不足之處的。

我將使用Chung等人在Hierarchical Multiscale Recurrent Neural Networks中描述的網路,作為一個非遞歸神經網路的示例。在github上有一個開源的網路實現。

基礎

在本節中,我將簡要介紹在tensorflow中創建標準RNN的工具。

標準的RNN單元

如果你需要標準RNN,GRU或LSTM,則你可以使用tensorflow。 API包含這些預先寫入的單元,所有這些都擴展了基類RNNCell。 他們關於RNN的教程中給出了如何使用這些單元的良好概述,所以我不會花太多時間在這裡。 如果你在tensorflow中完全不了解RNN,則可能需要先閱讀該教程才能繼續。

值得一提的是他們使用的是MultiRNNCell。 這是一個類,它用一個延伸RNNCell的對象列表構成。 它用於創建多層RNN,其中最低層在輸入中被饋送,然後每個後續層被饋送到先前層的輸出,並且最後一層的輸出是在給定時間步長的網路的輸出。 如果要以不同的方式在圖層之間傳遞信息,則需要一個自定義的多單元格。我們稍後再談這個。

請注意,MutliRNNCell本身也擴展了RNNCell,因此可以在任何其他RNNCell可以使用的地方使用。

動態展開的RNNs

我們發現RNNs展開時最容易考慮到。 在tensorflow中,這意味著我們為每個時間步驟重建一個相同的計算圖,並將隱藏的狀態從一個時間步驟前進到下一個手動傳遞。

這是採用tensorflow教程模型的方法。 這種方法的優點在於它易於思考,而且是靈活的。 如果要在傳遞之前以任何方式處理隱藏狀態,你可以輕鬆地將多個節點放在圖形中。

有兩個主要的缺點。首先,以這種方式組成的圖必須是固定長度的,這意味著你必須重建不同長度信號的圖形,或者用0填充它們。兩種解決辦法都不好。

第二,大型圖形需要更長的時間才能構建和使用更多的RAM。 根據你的計算環境的限制,這可能是令人望而生畏的。

tf.dynamic_rnn函數將你的RNNCell轉換為動態生成的圖形,將圖形從一個時間步驟傳遞到下一個時間段,並跟蹤輸出。 如果你有其他需求,tf.scan可以更靈活地提供類似的用途,我們將在後面看到。

新型RNN配置

在本節中,我將回顧一些可用於創建具有較少標準架構的RNN的選項。

直接擴展RNNCell

如果你需要與任何標準實現方式有所不同的網路,你可以直接擴展RNNCell。 你可以使用你自己的子類與上述的MultiRNNCell類以及DropoutWrapper和其他預定義的RNNCell包裝器。

擴展RNNCell意味著至少覆蓋state_size屬性,output_size屬性和調用方法。 Tensorflow的預構建單元內部表示狀態作為信號張量或張量的元組。 如果是單一的張量,則進入單元格後會被細分為隱藏狀態(或任何情況),然後最終將新狀態粘在一起。

我發現將單元格狀態視為元組更簡單。 在這種情況下,state_size屬性只是一個元組,其長度取決於您跟蹤哪一個。 output_size是單元格輸出的長度。 調用函數是您的單元格的邏輯空間。 RNNCell的__call__方法將包裝您的調用方法,並幫助實現範圍界定和其他邏輯。

為了使你的子類成為有效的RNNCell,調用方法必須接受參數input和state,並返回一個輸出元組new_state,其中state和new_state必須具有相同的形式。

請注意,如果你構建一個新的RNNCell,你想要與tensorflow中已經存在的tensorflow變數一起使用,則可以在__init__方法中將_reuse = True參數傳遞給父構造函數。 如果這些變數已經存在但是你沒有通過_reuse = True,那麼你會收到一個錯誤,因為tensorflow既不會覆蓋現有的變數,也不會在沒有顯式指令的情況下重用它們。

作為參考,HMLSTMCell類是用於表示上述分層和多尺度RNN的一個單元的RNNCell。 其實施涵蓋以上所有要點。

該代碼還在rnn_cell_impl模塊中使用了一個未記錄的函數,叫做_linear,這個函數在RNNCell子類中大部分被使用。 這有點冒險,因為它顯然不是為了外部使用,但它是一個有用的小函數,用來處理矩陣乘法及增加權重和偏差。

不尋常的多層RNN

如果你正在構建一個多層次的RNN,其中層不會簡單地將其輸出從一層到另一層傳遞,那麼必須構建你自己的MultiCell版本。 很像內置的MultiRNNCell,你的多單元應該擴展RNNCell。

在這種情況下,單元格狀態將是一個列表,其中每個元素是與其索引對應的圖層的單元格狀態。

在兩種情況下編寫自己的多單元格是有用的。 首先,在你想要在一層的結果之前做一些事情,然後再將它傳遞到下一層的單元格,但是你不想執行最低層的操作(否則你可以把它建進單元)。

第二,如果有上一個時間步驟的信息需要在不同的層之間進行分配,那麼這是非常有用的,但這並不完全符合從一個時間點到下一個階段的狀態。

例如,在分層多通道LSTM中,每個單元格希望從其上一層的層上接收隱藏狀態,作為其輸入的一部分。 這不符合堆疊RNN的標準思想,所以我們不能使用通常的MultiRNNCell。 作為參考,這裡是MultiHMLSTMCell的實現。

用tf.scan構建動態RNN

分層多尺度LSTM網路要求將隱藏狀態饋送到某些輸出網路。 我們已經看到,這個HMLSTM網路不能整齊地適應tensorflowRNN範例,由於它如何處理層之間的傳遞信息; 現在我們又碰到了另一個障礙。 我們需要通過另一個網路傳遞所有圖層的隱藏狀態,以獲得我們真正關心的輸出,而不是考慮最後一層輸出的網路輸出。 不僅如此,我們關心一些被視為單元狀態的指示神經元的價值。

由於這些原因,我們不能使用tf.dynamic_rnn網路,它只返回每個時間步長和最終狀態的輸出。

相反,tf.scan具有任意函數和有序的元素集合。 然後將該函數應用於集合中的每個元素,跟蹤一些累加器。 它在進程的每個步驟返回累加器的值的有序集合。

這對於更個性化的RNN是完美的。 因為你可以定義函數,所以可以選擇輸入、輸出和狀態。之後,你可以在每個時間步驟中獲得狀態的完整記錄,而不僅僅是輸出。

在HMLSTM的情況下,我們使用這些狀態來跟蹤邊界檢測,並且我們還對它們進行映射以獲得最終的預測。

這裡是參考代碼。

結論

在這篇文章中,我們研究了在tensorflow中處理RNN的標準工具,並探討了一些更靈活的選項,以便在這些工具不足時使用。

本文由北郵@愛可可-愛生活老師推薦,阿里云云棲社區組織翻譯。

文章原標題《Writing RNNs in Tensorflow》,

作者:Noam Finkelstein 譯者:TIAMO_ZN審閱:袁虎

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 雲棲社區 的精彩文章:

MaxCompute在網路輿情監控系統中的應用
機器學習PAI為你自動寫歌詞,媽媽再也不用擔心我的freestyle了(提供數據、代碼)
深度學習有很長的一段路要走!Keras作者談機器學習的局限性

TAG:雲棲社區 |

您可能感興趣

用TensorFlow Estimator實現文本分類
TensorFlow 攜手 NVIDIA,使用 TensorRT 優化 TensorFlow Serving 性能
如何使用Tensorflow玩轉深度學習?
如何使用 TensorFlow mobile將PyTorch和Keras 部署到移動設備
使用Tensorflow Object Detection API實現對象檢測
如何使用 TensorFlow.js 自動化 Chrome 恐龍遊戲?
谷歌正式開源 Hinton 膠囊理論代碼,即刻用 TensorFlow 實現吧
OpenCV調用TensorFlow是什麼意思
如何用一個Python示例入門TensorFlow?
TensorFlow可以做什麼?讓Google Brain首席工程師告訴你
在TensorFlow+Keras環境下使用RoI池化一步步實現注意力機制
如何使用 Android Things 和 TensorFlow 在物聯網上應用機器學習
如何使用TensorFlow中的Dataset API
基於 Tensorflow 輕鬆實現 XOR 運算!
TensorFlow Fold:用動態計算圖實現深度學習
TensorFlow王位不保?ICLR投稿論文PyTorch出鏡率快要反超了
Tensorflow中流動的tensor究竟是什麼?
基於Tensorflow Estimators的文本分類系列之一
使用PaddleFluid和TensorFlow訓練RNN語言模型
TensorFlow的動態圖工具Eager怎麼用?這是一篇極簡教程