成人av在线资源一区,亚洲av日韩av一区,欧美丰满熟妇乱XXXXX图片,狠狠做五月深爱婷婷伊人,桔子av一区二区三区,四虎国产精品永久在线网址,国产尤物精品人妻在线,中文字幕av一区二区三区欲色
    您正在使用IE低版瀏覽器,為了您的雷峰網賬號安全和更好的產品體驗,強烈建議使用更快更安全的瀏覽器
    此為臨時鏈接,僅用于文章預覽,將在時失效
    人工智能開發者 正文
    發私信給AI研習社
    發送

    0

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    本文作者: AI研習社 編輯:賈智龍 2017-05-26 16:01
    導語:從0開始實現LSTM。

    前言

    最近看完了 LSTM 的一些外文資料,主要參考了 Colah 的 blog以及 Andrej Karpathy blog的一些關于 RNN 和 LSTM 的材料,準備動手去實現一個 LSTM 模型。代碼的基礎框架來自于 Udacity 上深度學習納米學位的課程(付費課程)的一個 demo,我剛開始看代碼的時候真的是一頭霧水,很多東西沒有理解,后來反復查閱資料,并我重新對代碼進行了學習和修改,對步驟進行了進一步的剖析,下面將一步步用 TensorFlow 來構建 LSTM 模型進行文本學習并試圖去生成新的文本。本篇文章比較適合新手去操作,LSTM 層采用的是 BasicLSTMCell。

    關于 RNN 與 LSTM 模型本文不做介紹,詳情去查閱資料過著去看上面的 blog 鏈接,講的很清楚啦。這篇文章主要是偏向實戰,來自己動手構建 LSTM 模型。

    數據集來自于外文版《安娜卡列妮娜》書籍的文本文檔(本文后面會提供整個 project 的 git 鏈接)。

    工具介紹

    • 語言:Python 3

    • 包:TensorFlow 及其它數據處理包(見代碼中)

    • 編輯器:jupyter notebook

    • 線上 GPU:floyd

    正文部分

    正文部分主要包括以下四個部分:

    - 數據預處理:加載數據、轉換數據、分割數據 mini-batch

    - 模型構建:輸入層,LSTM 層,輸出層,訓練誤差,loss,optimizer

    - 模型訓練:設置模型參數對模型進行訓練

    - 生成新文本:訓練新的文本

    主題:整個文本將基于《安娜卡列妮娜》這本書的英文文本作為 LSTM 模型的訓練數據,輸入為單個字符,通過學習整個英文文檔的字符(包括字母和標點符號等)來進行文本生成。在開始建模之前,我們首先要明確我們的輸入和輸出。即輸入是字符,輸出是預測出的新字符。

    一. 數據預處理

    在開始模型之前,我們首先要導入需要的包:


    import timeimport numpy as npimport tensorflow as tf


    這一部分主要包括了數據的轉換與 mini-batch 的分割步驟。

    首先我們來進行數據的加載與編碼轉換。由于我們是基于字符(字母和標點符號等單個字符串,以下統稱為字符)進行模型構建,也就是說我們的輸入和輸出都是字符。舉個栗子,假如我們有一個單詞 “hello”,我們想要基于這個單詞構建 LSTM,那么希望的到的結果是,輸入 “h”,預測下一個字母為 “e”;輸入 “e” 時,預測下一個字母為 “l”,等等。

    因此我們的輸入便是一個個字母,下面我們將文章進行轉換。

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    上面的代碼主要完成了下面三個任務:

    - 得到了文章中所有的字符集合 vocab

    - 得到一個字符 - 數字的映射 vocab_to_int

    - 得到一個數字 - 字符的映射 int_to_vocab

    - 對原文進行轉碼后的列表 encoded

    完成了前面的數據預處理操作,接下來就是要劃分我們的數據集,在這里我們使用 mini-batch 來進行模型訓練,那么我們要如何劃分數據集呢?在進行 mini-batch 劃分之前,我們先來了解幾個概念。

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    假如我們目前手里有一個序列 1-12,我們接下來以這個序列為例來說明劃分 mini-batch 中的幾個概念。首先我們回顧一下,在 DNN 和 CNN 中,我們都會將數據分 batch 輸入給神經網絡,加入我們有 100 個樣本,如果設置我們的 batch_size=10,那么意味著每次我們都會向神經網絡輸入 10 個樣本進行訓練調整參數。同樣的,在 LSTM 中,batch_size 意味著每次向網絡輸入多少個樣本,在上圖中,當我們設置 batch_size=2 時,我們會將整個序列劃分為 6 個 batch,每個 batch 中有兩個數字。

    然而由于 RNN 中存在著 “記憶”,也就是循環。事實上一個循環神經網絡能夠被看做是多個相同神經網絡的疊加,在這個系統中,每一個網絡都會傳遞信息給下一個。上面的圖中,我們可以看到整個 RNN 網絡由三個相同的神經網絡單元疊加起來的序列。那么在這里就有了第二個概念 sequence_length(也叫 steps),中文叫序列長度。上圖中序列長度是 3,可以看到將三個字符作為了一個序列。

    有了上面兩個概念,我們來規范一下后面的定義。我們定義一個 batch 中的序列個數為 N(即 batch_size),定義單個序列長度為 M(也就是我們的 num_steps)。那么實際上我們每個 batch 是一個N×M的數組,相當于我們的每個 batch 中有N×M個字符。在上圖中,當我們設置 N=2, M=3 時,我們可以得到每個 batch 的大小為 2 x 3 = 6 個字符,整個序列可以被分割成 12 / 6 = 2 個 batch。

    基于上面的分析,我們下面來進行 mini-batch 的分割:

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    上面的代碼定義了一個 generator,調用函數會返回一個 generator 對象,我們可以獲取一個 batch。

    經過上面的步驟,我們已經完成了對數據集的預處理。下一步我們開始構建模型。

    二. 模型構建

    模型構建部分主要包括了輸入層,LSTM 層,輸出層,loss,optimizer 等部分的構建,我們將一塊一塊來進行實現。

    1. 輸入層

    在數據預處理階段,我們定義了 mini-batch 的分割函數,輸入層的 size 取決于我們設置 batch 的 size(n_seqs × n_steps),下面我們首先構建輸入層。

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    同樣的,輸出層的(因為輸入一個字符,同樣會輸出一個字符)。除了輸入輸出外,我們還定義了 keep_prob 參數用來在后面控制 dropout 的保留結點數。關于 dropout 正則化請參考鏈接。

    2.LSTM 層

    LSTM 層是整個神經網絡的關鍵部分。TensorFlow 中,tf.contrib.rnn 模塊中有 BasicLSTMCell 和 LSTMCell 兩個包,它們的區別在于:

    BasicLSTMCell does not allow cell clipping, a projection layer, and does not use peep-hole connections: it is the basic baseline.(來自 TensorFlow 官網)

    在這里我們僅使用基本模塊 BasicLSTMCell。

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    上面的代碼中,我并沒有使用 tf.contrib.rnn 模塊,是因為我在使用遠程 floyd 的 GPU 運行代碼時候告訴我找不到這個模塊,可以用 tf.nn.run_cell.BasicLSTMCell 替代。構建好 LSTM cell 后,為了防止過擬合,在它的隱層添加了 dropout 正則。

    后面的 MultiRNNCell實現了對基本 LSTM cell 的順序堆疊,它接收的是 cell 對象組成的 list。最后 initial_state 定義了初始 cell state。

    3. 輸出層

    到目前為止,我們的輸入和 LSTM 層都已經構建完畢。接下來就要構造我們的輸出層,輸出層采用 softmax,它與 LSTM 進行全連接。對于每一個字符來說,它經過 LSTM 后的輸出大小是1×L(L 為 LSTM cell 隱層的結點數量),我們上面也分析過輸入一個 N x M 的 batch,我們從 LSTM 層得到的輸出為N×M×L,要將這個輸出與 softmax 全連接層建立連接,就需要對 LSTM 的輸出進行重塑,變成( N * M ) × L 的一個 2D 的 tensor。softmax 層的結點數應該是 vocab 的大?。ㄎ覀円嬎愀怕史植迹R虼苏麄€ LSTM 層到 softmax 層的大小為L×vocab_size。

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    將數據重塑后,我們對 LSTM 層和 softmax 層進行連接。并計算 logits 和 softmax 后的概率分布。

    4. 訓練誤差計算

    至此我們已經完成了整個網絡的構建,接下來要定義 train loss 和 optimizer。我們知道從 sotfmax 層輸出的是概率分布,因此我們要對 targets 進行 one-hot 編碼。我們采用 softmax_cross_entropy_with_logits交叉熵來計算 loss。

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    5.Optimizer

    我們知道 RNN 會遇到梯度爆炸(gradients exploding)梯度彌散(gradients disappearing) 的問題。LSTM 解決了梯度彌散的問題,但是 gradients 仍然可能會爆炸,因此我們采用 gradient clippling 的方式來防止梯度爆炸。即通過設置一個閾值,當 gradients 超過這個閾值時,就將它重置為閾值大小,這就保證了梯度不會變得很大。

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    tf.clip_by_global_norm會返回 clip 以后的 gradients 以及 global_norm。整個學習過程采用 AdamOptimizer

    6. 模型組合

    經過上面五個步驟,我們完成了所有的模塊設置。下面我們來將這些部分組合起來,構建一個類。

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    我們使用 tf.nn.dynamic_run 來運行 RNN 序列。

    三. 模型訓練

    在模型訓練之前,我們首先初始化一些參數,我們的參數主要有:

    • batch_size: 單個 batch 中序列的個數

    • num_steps: 單個序列中字符數目

    • lstm_size: 隱層結點個數

    • num_layers: LSTM 層個數

    • learning_rate: 學習率

    • keep_prob: 訓練時 dropout 層中保留結點比例

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    這是我自己設置的一些參數,具體一些調參經驗可以參考 Andrej Karpathy 的 git 上的建議。

    參數設置完畢后,離運行整個 LSTM 就差一步啦,下面我們來運行整個模型。

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    我這里設置的迭代次數為 20 次,并且在代碼運行中我們設置了結點的保存,設置了每運行 200 次進行一次變量保存,這樣的好處是有利于我們后面去直觀地觀察在整個訓練過程中文本生成的結果是如何一步步 “進化” 的。

    四. 文本生成

    經過漫長的模型訓練,我們得到了一系列訓練過程中保存下來的參數,可以利用這些參數來進行文本生成啦。當我們輸入一個字符時,它會預測下一個,我們再將這個新的字符輸入模型,就可以一直不斷地生成字符,從而形成文本。

    為了減少噪音,每次的預測值我會選擇最可能的前 5 個進行隨機選擇,比如輸入 h,預測結果概率最大的前五個為[o,i,e,u,b],我們將隨機從這五個中挑選一個作為新的字符,讓過程加入隨機因素會減少一些噪音的生成。

    代碼封裝了兩個函數來做文本生成,具體請參看文章尾部的 git 鏈接中的源碼。

    訓練步數:200

    當訓練步數為 200 的時候,LSTM 生成的文本大概長下面這個樣子:

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    看起來像是字符的隨機組合,但是可以看到有一些單詞例如 hat,her 等已經出現,并且生成了成對的引號。

    訓練步數:1000

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    當訓練步數到達 1000 的時候,已經開始有簡單的句子出現,并且單詞看起來似乎不是那么亂了。

    訓練步數:2000

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    當訓練步數達到 2000 的時候,單詞和句子看起來已經有所規范。

    訓練步數:3960

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    當訓練結束時(本文僅訓練了 3960 步),生成的文本已經有小部分可以讀的比較通順了,而且很少有單詞拼寫的錯誤。

    五. 總結

    整個文章通過構建 LSTM 模型完成了對《安娜卡列寧娜》文本的學習并且基于學習成果生成了新的文本。

    通過觀察上面的生成文本,我們可以看出隨著訓練步數的增加,模型的訓練誤差在持續減少。本文僅設置了 20 次迭代,嘗試更大次數的迭代可能會取得更好的效果。

    個人覺得 LSTM 對于文本的學習能力還是很強,后面可能將針對中文文本構造一些學習模型,應該會更有意思!

    我對 RNN 也是在不斷地探索與學習中,文中不免會有一些錯誤和謬誤,懇請各位指正,非常感謝!

    ----------------------------------------------------------------------------------------------------------

    整個項目地址已經上傳到個人的 GitHub上。

    如果覺得有用,請叫上全村兒的小伙伴兒幫我 star 一下,不勝感激!

    雷鋒網按:本文原作者天雨粟,原載于知乎專欄

    雷峰網版權文章,未經授權禁止轉載。詳情見轉載須知

    《安娜卡列尼娜》文本生成——利用 TensorFlow 構建 LSTM 模型

    分享:
    相關文章

    編輯

    聚焦數據科學,連接 AI 開發者。更多精彩內容,請訪問:yanxishe.com
    當月熱門文章
    最新文章
    請填寫申請人資料
    姓名
    電話
    郵箱
    微信號
    作品鏈接
    個人簡介
    為了您的賬戶安全,請驗證郵箱
    您的郵箱還未驗證,完成可獲20積分喲!
    請驗證您的郵箱
    立即驗證
    完善賬號信息
    您的賬號已經綁定,現在您可以設置密碼以方便用郵箱登錄
    立即設置 以后再說