閱讀111 返回首頁    go 人物


送機器學習電子書——(TensorFlow)RNN入門

更多深度文章,請關注雲計算頻道:https://yq.aliyun.com/cloud


今天我們將研究一種名為循環神經網絡的神經網絡體係結構。它針對的不是自然語言數據,而是處理連續的時間數據,如股票市場價格。在本文結束之時,你將能夠對時間序列數據中的模式進行建模,以對未來的值進行預測。

a1d1902a809c6ad3473e31d9ac71127cc4ee2ba0

1.上下文信息

回到學校,我的一個期中考試僅由真的或假的問題組成時。假設一半的答案是真的,而另一半則是假的。我想出了大部分問題的答案,剩下的是靠隨機猜測。我做了一件聰明的事情,也許你也可以嚐試一下這個策略。在計數了我的“真”的答案之後,我意識到它與“假”這個答案不成比例。於是我的大部分猜測是“假”的,這樣就可以平衡分配。

這竟然是有效的。在那一時刻我感覺到我是狡猾的。這是什麼樣的判斷力,使我們對自己的決定那麼有信心,我們又如何將這種判斷力給予神經網絡?

這個問題的一個答案是使用上下文來回答問題。語境提示是可以提高機器學習算法性能的重要信號。例如,假設你想檢查一個英文句子,並標記每個單詞的詞性。

傻傻的方法是將每個單詞單獨分類為“名詞”,“形容詞”等,而不確認其相鄰的單詞。單詞“努力”被用作動詞,但根據上下文,你也可以使用它作為一個形容詞,單純的詞性標注是一個需要努力的問題。

更好的方法是考慮上下文信息。為了向神經網絡提供上下文信息,我們可以使用稱為循環神經網絡的體係結構。

循環神經網絡(RNN)簡介

為了理解循環神經網絡(RNN),我們首先來看一下圖1所示的簡單架構。它將輸入向量Xt)作為輸入,並在某個時間(t)產生一個向量Yt)的輸出。中間的圓圈表示網絡的隱藏層。

79e1314601bc1d8d2daa9477f1e1da0bfa0ea5bc

1分別具有標記為Xk)和Yk)的輸入和輸出層的神經網絡

通過足夠的輸入/輸出示例,你可以在TensorFlow中了解網絡的參數。例如,我們將輸入權重稱為矩陣in,輸出權重作為矩陣out。假設有一個隱藏層,稱為向量Zt)。

如圖2所示,神經網絡的前半部分的特征在於函數Zt= Xt* W in,神經網絡的後半部分形式為Yt= Zt* W out。同樣,如果你願意,整個神經網絡可以是函數Yt=Xt* Win* W out

1a7944f8e7fd96be7b0cd64e302c141d391f64e4

2神經網絡的隱藏層可以被認為是數據的隱藏,由其輸入權重編碼並輸出權重解碼。

在微調神經網絡後,你可能希望在現實世界的場景中開始使用你所學習的模型。通常,這意味著你將多次調用該模型,甚至可能連續反複調用,如圖3所示。

3755f72519c9d32b1dfde817a1bc8949ae8584c2

3通常,我們會運行相同的神經網絡多次,而不考慮關於先前運行的隱藏狀態。

在每個時間t,當調用學習模型時,這種體係結構不考慮關於以前運行的結果經驗。就像預測股市走勢一樣,隻看當前的數據。循環神經網絡(RNN)與傳統神經網絡不同,因為它引入了轉移權重W來跨越時間傳遞信息。圖4顯示了必須在RNN中學習的三個加權矩陣。

acda61bfd9b93480cd8262d84b0db6a9c4d4c550

4循環神經網絡架構可以利用網絡的先前狀態來實現其優點。

理論上很好理解,但是你在這裏必須要親自動手做一下。讓我們來吧!接下來將介紹如何使用TensorFlow的內置RNN模型。我們將使用這個RNN在現實世界的時間數據來預測未來!

2.實施循環神經網絡

當我們實施RNN時,我們將使用TensorFlow。如圖4所示,你不需要手動構建網絡,因為TensorFlow庫中已經支持一些魯棒(robust)的RNN模型。

參考有關RNNTensorFlow庫信息,請參見https://www.tensorflow.org/tutorials/recurrent

RNN的一種類型模型被稱為長短期記憶網絡(LSTM)。我覺得這是一個有趣的名字。它聽起來也意味著:短期模式長期不會被遺忘。

LSTM的精確實現細節不在本文的範圍之內。相信我,如果隻學習LSTM模型會分散我們的注意力,因為它還沒有確定的標準。

進一步閱讀:為了了解如何從頭開始執行LSTM,我建議你閱讀以下的文章:https://apaszke.github.io/lstm-explained.html

我們現在開始我們的教程。首先從編寫我們的代碼開始,先創建一個新的文件,叫做simple_regression.py。導入相關的庫,如步驟1所示。

步驟1:導入相關庫

import numpy as np
import tensorflow as tf
from tensorflow.contrib import rnn

接著,定義一個類叫做SeriesPredictor。如步驟2所示,構造函數裏麵設置模型超參數,權重和成本函數。

步驟2:定義一個類及其構造函數

class SeriesPredictor:
     def __init__(self, input_dim, seq_size, hidden_dim=10):
        self.input_dim = input_dim //#A
        self.seq_size = seq_size  //#A
        self.hidden_dim = hidden_dim  //#A
        self.W_out = tf.Variable(tf.random_normal([hidden_dim, 1]),name='W_out') //#B
        self.b_out = tf.Variable(tf.random_normal([1]), name='b_out')  //#B
        self.x = tf.placeholder(tf.float32, [None, seq_size, input_dim]) //#B
        self.y = tf.placeholder(tf.float32, [None, seq_size]) //#B
        self.cost = tf.reduce_mean(tf.square(self.model() - self.y)) //#C
        self.train_op = tf.train.AdamOptimizer().minimize(self.cost) //#C
        self.saver = tf.train.Saver()  //#D

#A超參數。

#B權重變量和輸入占位符。

#C成本優化器(cost optimizer)。

#D輔助操作。

接下來,我們使用TensorFlow的內置RNN模型,名為BasicLSTMCellLSTM單元的隱藏維度是通過時間的隱藏狀態的維度。我們可以使用該rnn.dynamic_rnn函數處理這個單元格數據,以檢索輸出結果。步驟3詳細介紹了如何使用TensorFlow來實現使用LSTM的預測模型。

步驟3:定義RNN模型

def model(self):
         """
         :param x: inputs of size [T, batch_size, input_size]
         :param W: matrix of fully-connected output layer weights
         :param b: vector of fully-connected output layer biases
         """
         cell = rnn.BasicLSTMCell(self.hidden_dim)  #A
         outputs, states = tf.nn.dynamic_rnn(cell, self.x, dtype=tf.float32) #B
         num_examples = tf.shape(self.x)[0]
         W_repeated = tf.tile(tf.expand_dims(self.W_out, 0), [num_examples, 1, 1])#C
         out = tf.matmul(outputs, W_repeated) + self.b_out
         out = tf.squeeze(out)
         return out

#A創建一個LSTM單元。

#B運行輸入單元,獲取輸出和狀態的張量。

#C將輸出層計算為完全連接的線性函數。

通過定義模型和成本函數,我們現在可以實現訓練函數,該函數學習給定示例輸入/輸出對的LSTM權重。如步驟4所示,你打開會話並重複運行優化器。

另外,你可以使用交叉驗證來確定訓練模型的迭代次數。在這裏我們假設固定數量的epocs

訓練後,將模型保存到文件中,以便稍後加載使用。

步驟4:在一個數據集上訓練模型

def train(self, train_x, train_y):
         with tf.Session() as sess:
             tf.get_variable_scope().reuse_variables()
             sess.run(tf.global_variables_initializer())
             for i in range(1000):  #A
               		mse = sess.run([self.train_op, self.cost], feed_dict={self.x: train_x, self.y: train_y})
                 if i % 100 == 0:
                     print(i, mse)
             save_path = self.saver.save(sess, 'model.ckpt')
             print('Model saved to {}'.format(save_path))

#A訓練1000

我們的模型已經成功地學習了參數。接下來,我們想評估利用其他數據來評估以下預測模型的性能。步驟5加載已保存的模型,並通過饋送一些測試數據以此來運行模型。如果學習的模型在測試數據上表現不佳,那麼我們可以嚐試調整LSTM單元格的隱藏維數。

步驟5:測試學習的模型

def test(self, test_x):
         with tf.Session() as sess:
             tf.get_variable_scope().reuse_variables()
             self.saver.restore(sess, './model.ckpt')
             output = sess.run(self.model(), feed_dict={self.x: test_x})
             print(output)

但為了完善自己的工作,讓我們組成一些數據,並嚐試訓練預測模型。在步驟6中,我們將創建輸入序列,稱為train_x,和相應的輸出序列,稱為train_y

步驟6訓練並測試一些虛擬數據

if __name__ == '__main__':
     predictor = SeriesPredictor(input_dim=1, seq_size=4, hidden_dim=10)
     train_x = [[[1], [2], [5], [6]],
                [[5], [7], [7], [8]],
                [[3], [4], [5], [7]]]
     train_y = [[1, 3, 7, 11],
                [5, 12, 14, 15],
                [3, 7, 9, 12]]
     predictor.train(train_x, train_y)
       test_x = [[[1], [2], [3], [4]],  #A
               [[4], [5], [6], [7]]]  #B
     predictor.test(test_x)

#A預測結果應為1357

#B預測結果應為491113

你可以將此預測模型視為黑盒子,並用現實世界的時間數據進行測試。

這篇博文隻是我新書的一小部分,如果你想要學習更多的知識請移步:

Machine Learning with TensorFlow 

本文由北郵@愛可可-愛生活老師推薦,阿裏雲雲棲社區組織整理。

文章原標題:《Recurrent Neural Networks

作者:Nishant Shukla  機器學習布道者

譯者:虎說八道。審校:主題曲哥哥。

文章為簡譯,更為詳細的內容,請查看原文


最後更新:2017-10-10 14:33:30

  上一篇:go  軟件開發協同平台
  下一篇:go  30行代碼,帶你分分鍾創建神經網絡!(附工具&教程)