鍍金池/ 教程/ 人工智能/ 遞歸神經(jīng)網(wǎng)絡(luò) <a class="md-anchor" id="AUTOGENERATED-recurrent-neural-n
BibTex 引用<a class="md-anchor" id="AUTOGENERATED-bibtex-citation"
術(shù)語表
自定義數(shù)據(jù)讀取 <a class="md-anchor" id="AUTOGENERATED-custom-data-reade
使用 GPUs <a class="md-anchor" id="AUTOGENERATED-using-gpus"></a>
Vector Representations of Words <a class="md-anchor" id="AUTOGEN
TensorFlow 個人學(xué)習(xí)心得
共享變量<a class="md-anchor" id="AUTOGENERATED-sharing-variables"></
應(yīng)用實(shí)例 <a class="md-anchor" id="AUTOGENERATED-example-uses"></a>
其他資源 <a class="md-anchor" id="AUTOGENERATED-additional-resources
偏微分方程 <a class="md-anchor" id="AUTOGENERATED-partial-differentia
TensorBoard:可視化學(xué)習(xí) <a class="md-anchor" id="AUTOGENERATED-tensorb
TensorFlow運(yùn)作方式入門 <a class="md-anchor" id="AUTOGENERATED-tensorfl
常見問題 <a class="md-anchor" id="AUTOGENERATED-frequently-asked-que
MNIST機(jī)器學(xué)習(xí)入門 <a class="md-anchor" id="AUTOGENERATED-mnist-for-ml-
曼德布洛特(Mandelbrot)集合 <a class="md-anchor" id="AUTOGENERATED-mande
變量:創(chuàng)建、初始化、保存和加載
TensorBoard: 圖表可視化 <a class="md-anchor" id="AUTOGENERATED-tensor
簡介 <a class="md-anchor" id="AUTOGENERATED-introduction"></a>
張量的階、形狀、數(shù)據(jù)類型<a class="md-anchor" id="AUTOGENERATED-tensor-ranks-
線程和隊(duì)列 <a class="md-anchor" id="AUTOGENERATED-threading-and-queue
下載與安裝 <a class="md-anchor" id="AUTOGENERATED-download-and-setup"
常見問題匯總
綜述
綜述 Overview
TensorFlow 相關(guān)資源
數(shù)據(jù)讀取 <a class="md-anchor" id="AUTOGENERATED-reading-data"></a>
遞歸神經(jīng)網(wǎng)絡(luò) <a class="md-anchor" id="AUTOGENERATED-recurrent-neural-n
深入MNIST <a class="md-anchor" id="AUTOGENERATED-deep-mnist-for-ex
增加一個新 Op <a class="md-anchor" id="AUTOGENERATED-adding-a-new-op"
卷積神經(jīng)網(wǎng)絡(luò) <a class="md-anchor" id="AUTOGENERATED-convolutional-neur
基本使用 <a class="md-anchor" id="AUTOGENERATED-basic-usage"></a>
MNIST 數(shù)據(jù)下載 <a class="md-anchor" id="AUTOGENERATED-mnist-data-dow

遞歸神經(jīng)網(wǎng)絡(luò) <a class="md-anchor" id="AUTOGENERATED-recurrent-neural-n

介紹

可以在 this great article 查看循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)以及 LSTM 的介紹。

語言模型

此教程將展示如何在高難度的語言模型中訓(xùn)練循環(huán)神經(jīng)網(wǎng)絡(luò)。該問題的目標(biāo)是獲得一個能確定語句概率的概率模型。為了做到這一點(diǎn),通過之前已經(jīng)給出的詞語來預(yù)測后面的詞語。我們將使用 PTB(Penn Tree Bank) 數(shù)據(jù)集,這是一種常用來衡量模型的基準(zhǔn),同時它比較小而且訓(xùn)練起來相對快速。

語言模型是很多有趣難題的關(guān)鍵所在,比如語音識別,機(jī)器翻譯,圖像字幕等。它很有意思--可以參看 here。

本教程的目的是重現(xiàn) Zaremba et al., 2014 的成果,他們在 PTB 數(shù)據(jù)集上得到了很棒的結(jié)果。

教程文件

本教程使用的下面文件的目錄是 models/rnn/ptb:

文件 作用
ptb_word_lm.py 在 PTB 數(shù)據(jù)集上訓(xùn)練一個語言模型.
reader.py 讀取數(shù)據(jù)集.

下載及準(zhǔn)備數(shù)據(jù)

本教程需要的數(shù)據(jù)在 data/ 路徑下,來源于 Tomas Mikolov 網(wǎng)站上的 PTB 數(shù)據(jù)集http://www.fit.vutbr.cz/~imikolov/rnnlm/simple-examples.tgz

該數(shù)據(jù)集已經(jīng)預(yù)先處理過并且包含了全部的 10000 個不同的詞語,其中包括語句結(jié)束標(biāo)記符,以及標(biāo)記稀有詞語的特殊符號 (<unk>) 。我們在 reader.py 中轉(zhuǎn)換所有的詞語,讓他們各自有唯一的整型標(biāo)識符,便于神經(jīng)網(wǎng)絡(luò)處理。

模型

LSTM

模型的核心由一個 LSTM 單元組成,其可以在某時刻處理一個詞語,以及計(jì)算語句可能的延續(xù)性的概率。網(wǎng)絡(luò)的存儲狀態(tài)由一個零矢量初始化并在讀取每一個詞語后更新。而且,由于計(jì)算上的原因,我們將以 batch_size 為最小批量來處理數(shù)據(jù)。

基礎(chǔ)的偽代碼就像下面這樣:

lstm = rnn_cell.BasicLSTMCell(lstm_size)
# 初始化 LSTM 存儲狀態(tài).
state = tf.zeros([batch_size, lstm.state_size])

loss = 0.0
for current_batch_of_words in words_in_dataset:
    # 每次處理一批詞語后更新狀態(tài)值.
    output, state = lstm(current_batch_of_words, state)

    # LSTM 輸出可用于產(chǎn)生下一個詞語的預(yù)測
    logits = tf.matmul(output, softmax_w) + softmax_b
    probabilities = tf.nn.softmax(logits)
    loss += loss_function(probabilities, target_words)

截?cái)喾聪騻鞑?

為使學(xué)習(xí)過程易于處理,通常的做法是將反向傳播的梯度在(按時間)展開的步驟上照一個固定長度(num_steps)截?cái)唷?通過在一次迭代中的每個時刻上提供長度為 num_steps 的輸入和每次迭代完成之后反向傳導(dǎo),這會很容易實(shí)現(xiàn)。

一個簡化版的用于計(jì)算圖創(chuàng)建的截?cái)喾聪騻鞑ゴa:

# 一次給定的迭代中的輸入占位符.
words = tf.placeholder(tf.int32, [batch_size, num_steps])

lstm = rnn_cell.BasicLSTMCell(lstm_size)
# 初始化 LSTM 存儲狀態(tài).
initial_state = state = tf.zeros([batch_size, lstm.state_size])

for i in range(len(num_steps)):
    # 每處理一批詞語后更新狀態(tài)值.
    output, state = lstm(words[:, i], state)

    # 其余的代碼.
    # ...

final_state = state

下面展現(xiàn)如何實(shí)現(xiàn)迭代整個數(shù)據(jù)集:

# 一個 numpy 數(shù)組,保存每一批詞語之后的 LSTM 狀態(tài).
numpy_state = initial_state.eval()
total_loss = 0.0
for current_batch_of_words in words_in_dataset:
    numpy_state, current_loss = session.run([final_state, loss],
        # 通過上一次迭代結(jié)果初始化 LSTM 狀態(tài).
        feed_dict={initial_state: numpy_state, words: current_batch_of_words})
    total_loss += current_loss

輸入

在輸入 LSTM 前,詞語 ID 被嵌入到了一個密集的表示中(查看 矢量表示教程)。這種方式允許模型高效地表示詞語,也便于寫代碼:

# embedding_matrix 張量的形狀是: [vocabulary_size, embedding_size]
word_embeddings = tf.nn.embedding_lookup(embedding_matrix, word_ids)

嵌入的矩陣會被隨機(jī)地初始化,模型會學(xué)會通過數(shù)據(jù)分辨不同詞語的意思。

損失函數(shù)

我們想使目標(biāo)詞語的平均負(fù)對數(shù)概率最小

http://wiki.jikexueyuan.com/project/tensorflow-zh/images/re.png" alt="" />

實(shí)現(xiàn)起來并非很難,而且函數(shù) sequence_loss_by_example 已經(jīng)有了,可以直接使用。

論文中的典型衡量標(biāo)準(zhǔn)是每個詞語的平均困惑度(perplexity),計(jì)算式為

http://wiki.jikexueyuan.com/project/tensorflow-zh/images/re1.png" alt="" />

同時我們會觀察訓(xùn)練過程中的困惑度值(perplexity)。

多個 LSTM 層堆疊

要想給模型更強(qiáng)的表達(dá)能力,可以添加多層 LSTM 來處理數(shù)據(jù)。第一層的輸出作為第二層的輸入,以此類推。

MultiRNNCell 可以無縫的將其實(shí)現(xiàn):

lstm = rnn_cell.BasicLSTMCell(lstm_size)
stacked_lstm = rnn_cell.MultiRNNCell([lstm] * number_of_layers)

initial_state = state = stacked_lstm.zero_state(batch_size, tf.float32)
for i in range(len(num_steps)):
    # 每次處理一批詞語后更新狀態(tài)值.
    output, state = stacked_lstm(words[:, i], state)

    # 其余的代碼.
    # ...

final_state = state

編譯并運(yùn)行代碼

首先需要構(gòu)建庫,在 CPU 上編譯:

bazel build -c opt tensorflow/models/rnn/ptb:ptb_word_lm

如果你有一個強(qiáng)大的 GPU,可以運(yùn)行:

bazel build -c opt --config=cuda tensorflow/models/rnn/ptb:ptb_word_lm

運(yùn)行模型:

bazel-bin/tensorflow/models/rnn/ptb/ptb_word_lm \
  --data_path=/tmp/simple-examples/data/ --alsologtostderr --model small

教程代碼中有 3 個支持的模型配置參數(shù):"small", "medium" 和 "large"。它們指的是 LSTM 的大小,以及用于訓(xùn)練的超參數(shù)集。

模型越大,得到的結(jié)果應(yīng)該更好。在測試集中 small 模型應(yīng)該可以達(dá)到低于 120 的困惑度(perplexity),large 模型則是低于 80,但它可能花費(fèi)數(shù)小時來訓(xùn)練。

除此之外?

還有幾個優(yōu)化模型的技巧沒有提到,包括:

  • 隨時間降低學(xué)習(xí)率,
  • LSTM 層間 dropout.

繼續(xù)學(xué)習(xí)和更改代碼以進(jìn)一步改善模型吧。

原文:Recurrent Neural Networks 翻譯:Warln 校對:HongyangWang