“全球人工智能”擁有十多萬AI產業(yè)用戶,10000多名AI技術專家。主要來自:北大,清華,中科院,麻省理工,卡內基梅隆,斯坦福,哈佛,牛津,劍橋...以及谷歌,騰訊,百度,臉譜,微軟,阿里,??低?,英偉達......等全球名校和名企。 摘要: 本文作者正在寫自己的新書Machine Learning with TensorFlow,這篇博文只是他新書的一小部分,作者用簡單的語言介紹了RNN,不用一個小例子介紹了如何使用Tensorflow中內置的RNN模型進行預測。 今天我們將研究一種名為循環(huán)神經網絡的神經網絡體系結構。它針對的不是自然語言數據,而是處理連續(xù)的時間數據,如股票市場價格。在本文結束之時,你將能夠對時間序列數據中的模式進行建模,以對未來的值進行預測。
1.上下文信息 回到學校,我的一個期中考試僅由真的或假的問題組成時。假設一半的答案是“真的”,而另一半則是“假的”。我想出了大部分問題的答案,剩下的是靠隨機猜測。我做了一件聰明的事情,也許你也可以嘗試一下這個策略。在計數了我的“真”的答案之后,我意識到它與“假”這個答案不成比例。于是我的大部分猜測是“假”的,這樣就可以平衡分配。 這竟然是有效的。在那一時刻我感覺到我是狡猾的。這是什么樣的判斷力,使我們對自己的決定那么有信心,我們又如何將這種判斷力給予神經網絡? 這個問題的一個答案是使用上下文來回答問題。語境提示是可以提高機器學習算法性能的重要信號。例如,假設你想檢查一個英文句子,并標記每個單詞的詞性。 傻傻的方法是將每個單詞單獨分類為“名詞”,“形容詞”等,而不確認其相鄰的單詞。單詞“努力”被用作動詞,但根據上下文,你也可以使用它作為一個形容詞,單純的詞性標注是一個需要努力的問題。 更好的方法是考慮上下文信息。為了向神經網絡提供上下文信息,我們可以使用稱為循環(huán)神經網絡的體系結構。 循環(huán)神經網絡(RNN)簡介
為了理解循環(huán)神經網絡(RNN),我們首先來看一下圖1所示的簡單架構。它將輸入向量X(t)作為輸入,并在某個時間(t)產生一個向量Y(t)的輸出。中間的圓圈表示網絡的隱藏層。
圖1分別具有標記為X(k)和Y(k)的輸入和輸出層的神經網絡 通過足夠的輸入/輸出示例,你可以在TensorFlow中了解網絡的參數。例如,我們將輸入權重稱為矩陣W in,輸出權重作為矩陣W out。假設有一個隱藏層,稱為向量Z(t)。
如圖2所示,神經網絡的前半部分的特征在于函數Z(t)= X(t)* W in,神經網絡的后半部分形式為Y(t)= Z(t)* W out。同樣,如果你愿意,整個神經網絡可以是函數Y(t)=(X(t)* Win)* W out。
圖2神經網絡的隱藏層可以被認為是數據的隱藏,由其輸入權重編碼并輸出權重解碼。 在微調神經網絡后,你可能希望在現實世界的場景中開始使用你所學習的模型。通常,這意味著你將多次調用該模型,甚至可能連續(xù)反復調用,如圖3所示。
圖3通常,我們會運行相同的神經網絡多次,而不考慮關于先前運行的隱藏狀態(tài)。 在每個時間t,當調用學習模型時,這種體系結構不考慮關于以前運行的結果經驗。就像預測股市走勢一樣,只看當前的數據。循環(huán)神經網絡(RNN)與傳統(tǒng)神經網絡不同,因為它引入了轉移權重W來跨越時間傳遞信息。圖4顯示了必須在RNN中學習的三個加權矩陣。
圖4循環(huán)神經網絡架構可以利用網絡的先前狀態(tài)來實現其優(yōu)點。 理論上很好理解,但是你在這里必須要親自動手做一下。讓我們來吧!接下來將介紹如何使用TensorFlow的內置RNN模型。我們將使用這個RNN在現實世界的時間數據來預測未來! 2.實施循環(huán)神經網絡 當我們實施RNN時,我們將使用TensorFlow。如圖4所示,你不需要手動構建網絡,因為TensorFlow庫中已經支持一些魯棒(robust)的RNN模型。 參考有關RNN的TensorFlow庫信息,請參見https://www./tutorials/recurrent。 RNN的一種類型模型被稱為長短期記憶網絡(LSTM)。我覺得這是一個有趣的名字。它聽起來也意味著:短期模式長期不會被遺忘。 LSTM的精確實現細節(jié)不在本文的范圍之內。相信我,如果只學習LSTM模型會分散我們的注意力,因為它還沒有確定的標準。 進一步閱讀:為了了解如何從頭開始執(zhí)行LSTM,我建議你閱讀以下的文章:https://apaszke./lstm-explained.html 我們現在開始我們的教程。首先從編寫我們的代碼開始,先創(chuàng)建一個新的文件,叫做
步驟1:導入相關庫 import numpy as npimport tensorflow as tffrom tensorflow.contrib import rnn 接著,定義一個類叫做 步驟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成本優(yōu)化器(cost optimizer)。 #D輔助操作。 接下來,我們使用TensorFlow的內置RNN模型,名為BasicLSTMCell。LSTM單元的隱藏維度是通過時間的隱藏狀態(tài)的維度。我們可以使用該 步驟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創(chuàng)建一個LSTM單元。 #B運行輸入單元,獲取輸出和狀態(tài)的張量。 #C將輸出層計算為完全連接的線性函數。 通過定義模型和成本函數,我們現在可以實現訓練函數,該函數學習給定示例輸入/輸出對的LSTM權重。如步驟4所示,你打開會話并重復運行優(yōu)化器。 另外,你可以使用交叉驗證來確定訓練模型的迭代次數。在這里我們假設固定數量的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中,我們將創(chuàng)建輸入序列,稱為 步驟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預測結果應為1,3,5,7。 #B預測結果應為4,9,11,13。 你可以將此預測模型視為黑盒子,并用現實世界的時間數據進行測試。 這篇博文只是我新書的一小部分,如果你想要學習更多的知識請移步: |
|