<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 用Python中的長短期內存網絡演示內存 > 原文: [https://machinelearningmastery.com/memory-in-a-long-short-term-memory-network/](https://machinelearningmastery.com/memory-in-a-long-short-term-memory-network/) 長短期記憶(LSTM)網絡是一種能夠學習長序列的循環神經網絡。 這使它們與沒有記憶的常規多層神經網絡區分開來,并且只能學習輸入和輸出模式之間的映射。 重要的是要理解像LSTM這樣的復雜神經網絡在小型設計問題上的能力,因為這種理解將幫助您將網絡擴展到大型甚至是非常大的問題。 在本教程中,您將發現LSTM記憶和回憶的功能。 完成本教程后,您將了解: * 如何定義一個小序列預測問題,只有像LSTM這樣的RNN可以使用內存來解決。 * 如何轉換問題表示,使其適合LSTM學習。 * 如何設計LSTM來正確解決問題。 讓我們開始吧。 ![A Demonstration of Memory in a Long Short-Term Memory Network](img/c25fa76217d2aaa3d066421ffc6a5238.jpg) 在長期短期記憶網絡中的記憶演示 照片由 [crazlei](https://www.flickr.com/photos/leifeng/4175290209/) ,保留一些權利。 ## 環境 本教程假設您使用帶有TensorFlow或Theano后端的SciPy,Keras 2.0或更高版本的Python 2或3環境。 有關設置Python環境的幫助,請參閱帖子: * [如何使用Anaconda設置用于機器學習和深度學習的Python環境](http://machinelearningmastery.com/setup-python-environment-machine-learning-deep-learning-anaconda/) ## 序列問題描述 問題是一次預測一個序列的值。 給定序列中的一個值,模型必須預測序列中的下一個值。例如,給定值“0”作為輸入,模型必須預測值“1”。 模型必須學習和正確預測有兩種不同的序列。 皺紋是兩個序列之間存在沖突的信息,并且模型必須知道每個一步預測的上下文(例如,它當前正在預測的序列),以便正確地預測每個完整序列。 這種皺紋對于防止模型記憶每個序列中的每個單步輸入 - 輸出值對非常重要,因為序列未知模型可能傾向于這樣做。 要學習的兩個序列如下: * 3,0,1,2,3 * 4,0,1,2,4 我們可以看到序列的第一個值重復作為序列的最后一個值。這是指示器為模型提供關于它正在處理的序列的上下文。 沖突是從每個序列中的第二個項目到最后一個項目的過渡。在序列1中,給出“2”作為輸入并且必須預測“3”,而在序列2中,給出“2”作為輸入并且必須預測“4”。 這是多層感知器和其他非循環神經網絡無法學習的問題。 這是“_實驗2_ ”的簡化版本,用于證明Hochreiter和Schmidhuber 1997年論文[長期短期記憶](http://dl.acm.org/citation.cfm?id=1246450)( [PDF](http://www.bioinf.jku.at/publications/older/2604.pdf) )中的LSTM長期記憶能力。 ## 問題表征 本節分為3部分;他們是: 1. 一個熱編碼 2. 輸入輸出對 3. 重塑數據 ### 一個熱編碼 我們將使用一個熱編碼來表示LSTM的學習問題。 也就是說,每個輸入和輸出值將表示為具有5個元素的二進制向量,因為問題的字母表是5個唯一值。 例如,[0,1,2,3,4]的5個值表示為以下5個二進制向量: ```py 0: [1, 0, 0, 0, 0] 1: [0, 1, 0, 0, 0] 2: [0, 0, 1, 0, 0] 3: [0, 0, 0, 1, 0] 4: [0, 0, 0, 0, 1] ``` 我們可以使用一個簡單的函數來執行此操作,該函數將獲取序列并返回序列中每個值的二進制向量列表。下面的函數 _encode()_實現了這種行為。 ```py # binary encode an input pattern, return a list of binary vectors def encode(pattern, n_unique): encoded = list() for value in pattern: row = [0.0 for x in range(n_unique)] row[value] = 1.0 encoded.append(row) return encoded ``` 我們可以在第一個序列上測試它并打印結果的二進制向量列表。下面列出了完整的示例。 ```py # binary encode an input pattern, return a list of binary vectors def encode(pattern, n_unique): encoded = list() for value in pattern: row = [0.0 for x in range(n_unique)] row[value] = 1.0 encoded.append(row) return encoded seq1 = [3, 0, 1, 2, 3] encoded = encode(seq1, 5) for vector in encoded: print(vector) ``` 運行該示例打印每個二進制向量。請注意,我們使用浮點值0.0和1.0,因為它們將用作模型的輸入和輸出。 ```py [0.0, 0.0, 0.0, 1.0, 0.0] [1.0, 0.0, 0.0, 0.0, 0.0] [0.0, 1.0, 0.0, 0.0, 0.0] [0.0, 0.0, 1.0, 0.0, 0.0] [0.0, 0.0, 0.0, 1.0, 0.0] ``` ### 輸入輸出對 下一步是將一系列編碼值拆分為輸入 - 輸出對。 這是問題的監督學習表示,使得機器學習問題可以學習如何將輸入模式( _X_ )映射到輸出模式( _y_ )。 例如,第一個序列具有以下要學習的輸入 - 輸出對: ```py X, y 3, 0 0, 1 1, 2 2, 3 ``` 我們必須從一個熱編碼的二進制向量中創建這些映射對,而不是原始數字。 例如,3-&gt; 0的第一輸入 - 輸出對將是: ```py X, y [0, 0, 0, 1, 0] [1, 0, 0, 0, 0] ``` 下面是一個名為 _to_xy_pairs()_的函數,它將在給定編碼二進制向量列表的情況下創建 _X_ 和 _y_ 模式的列表。 ```py # create input/output pairs of encoded vectors, returns X, y def to_xy_pairs(encoded): X,y = list(),list() for i in range(1, len(encoded)): X.append(encoded[i-1]) y.append(encoded[i]) return X, y ``` 我們可以將它與上面的一個熱編碼函數放在一起,并打印第一個序列的編碼輸入和輸出對。 ```py # binary encode an input pattern, return a list of binary vectors def encode(pattern, n_unique): encoded = list() for value in pattern: row = [0.0 for x in range(n_unique)] row[value] = 1.0 encoded.append(row) return encoded # create input/output pairs of encoded vectors, returns X, y def to_xy_pairs(encoded): X,y = list(),list() for i in range(1, len(encoded)): X.append(encoded[i-1]) y.append(encoded[i]) return X, y seq1 = [3, 0, 1, 2, 3] encoded = encode(seq1, 5) X, y = to_xy_pairs(encoded) for i in range(len(X)): print(X[i], y[i]) ``` 運行該示例將打印序列中每個步驟的輸入和輸出對。 ```py [0.0, 0.0, 0.0, 1.0, 0.0] [1.0, 0.0, 0.0, 0.0, 0.0] [1.0, 0.0, 0.0, 0.0, 0.0] [0.0, 1.0, 0.0, 0.0, 0.0] [0.0, 1.0, 0.0, 0.0, 0.0] [0.0, 0.0, 1.0, 0.0, 0.0] [0.0, 0.0, 1.0, 0.0, 0.0] [0.0, 0.0, 0.0, 1.0, 0.0] ``` ### 重塑數據 最后一步是重新整形數據,以便LSTM網絡可以直接使用它。 Keras LSTM期望輸入模式(X)為具有[_樣本,時間步長,特征_]維度的三維NumPy陣列。 在一個輸入數據序列的情況下,維度將是[4,1,5],因為我們有4行數據,每行有1個時間步長,每行有5列。 我們可以從X模式列表中創建2D NumPy數組,然后將其重新整形為所需的3D格式。例如: ```py df = DataFrame(X) values = df.values array = values.reshape(4, 1, 5) ``` 我們還必須將輸出模式列表(y)轉換為2D NumPy數組。 下面是一個名為 _to_lstm_dataset()_的函數,它將序列作為輸入和序列字母表的大小,并返回準備使用的 _X_ 和 _y_ 數據集與LSTM。它在重新整形數據之前執行所需的序列轉換為單熱編碼和輸入輸出對。 ```py # convert sequence to x/y pairs ready for use with an LSTM def to_lstm_dataset(sequence, n_unique): # one hot encode encoded = encode(sequence, n_unique) # convert to in/out patterns X,y = to_xy_pairs(encoded) # convert to LSTM friendly format dfX, dfy = DataFrame(X), DataFrame(y) lstmX = dfX.values lstmX = lstmX.reshape(lstmX.shape[0], 1, lstmX.shape[1]) lstmY = dfy.values return lstmX, lstmY ``` 可以使用以下每個序列調用此函數: ```py seq1 = [3, 0, 1, 2, 3] seq2 = [4, 0, 1, 2, 4] n_unique = len(set(seq1 + seq2)) seq1X, seq1Y = to_lstm_dataset(seq1, n_unique) seq2X, seq2Y = to_lstm_dataset(seq2, n_unique) ``` 我們現在擁有為LSTM準備數據的所有部分。 ## 使用LSTM學習序列 在本節中,我們將定義LSTM以學習輸入序列。 本節分為4個部分: 1. LSTM配置 2. LSTM訓練 3. LSTM評估 4. LSTM完整示例 ### LSTM配置 我們希望LSTM進行一步預測,我們已經在數據集的格式和形狀中定義了這些預測。我們還希望在每個時間步之后更新LSTM錯誤,這意味著我們需要使用批量大小的一個。 默認情況下,Keras LSTM在批次之間不具有狀態。我們可以通過將LSTM層上的_有狀態_參數設置為 _True_ 并手動管理訓練時期來確保LSTM的內部狀態在每個序列之后被重置,從而使它們成為有狀態。 我們必須使用 _batch_input_shape_ 參數定義批次的形狀,其中3維[_批量大小,時間步長和特征_]分別為1,1和5。 網絡拓撲將配置一個具有20個單元的隱藏LSTM層和一個具有5個輸出的普通密集層,用于輸出模式中的每個5列。由于二進制輸出,將在輸出層上使用sigmoid(邏輯)激活函數,并且將在LSTM層上使用默認的tanh(雙曲正切)激活函數。 由于二進制輸出,因此在擬合網絡時將優化對數(交叉熵)損失函數,并且將使用有效的ADAM優化算法與所有默認參數。 下面列出了為此問題定義LSTM網絡的Keras代碼。 ```py model = Sequential() model.add(LSTM(20, batch_input_shape=(1, 1, 5), stateful=True)) model.add(Dense(5, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='adam') ``` ### LSTM訓練 我們必須一次手動擬合模型一個時期。 在一個時期內,我們可以在每個序列上擬合模型,確保在每個序列之后重置狀態。 鑒于問題的簡單性,該模型不需要長時間訓練;在這種情況下,只需要250個迭代。 下面是一個示例,說明模型如何適應所有時期的每個序列。 ```py # train LSTM for i in range(250): model.fit(seq1X, seq1Y, epochs=1, batch_size=1, verbose=1, shuffle=False) model.reset_states() model.fit(seq2X, seq2Y, epochs=1, batch_size=1, verbose=0, shuffle=False) model.reset_states() ``` 我希望在安裝網絡時能看到關于損失函數的一些反饋,因此從其中一個序列開啟詳細輸出,而不是另一個序列。 ### LSTM評估 接下來,我們可以通過預測學習序列的每個步驟來評估擬合模型。 我們可以通過預測每個序列的輸出來做到這一點。 _predict_classes()_函數可以用于直接預測類的LSTM模型。它通過在輸出二進制向量上執行 _argmax()_并返回具有最大輸出的預測列的索引來完成此操作。輸出索引完美地映射到序列中使用的整數(通過上面的仔細設計)。下面列出了進行預測的示例: ```py result = model.predict_classes(seq1X, batch_size=1, verbose=0) ``` 我們可以進行預測,然后在輸入模式的上下文和序列的每個步驟的預期輸出模式中打印結果。 ### LSTM完整示例 我們現在可以將整個教程結合在一起。 完整的代碼清單如下。 首先,準備數據,然后擬合模型并打印兩個序列的預測。 ```py from pandas import DataFrame from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM # binary encode an input pattern, return a list of binary vectors def encode(pattern, n_unique): encoded = list() for value in pattern: row = [0.0 for x in range(n_unique)] row[value] = 1.0 encoded.append(row) return encoded # create input/output pairs of encoded vectors, returns X, y def to_xy_pairs(encoded): X,y = list(),list() for i in range(1, len(encoded)): X.append(encoded[i-1]) y.append(encoded[i]) return X, y # convert sequence to x/y pairs ready for use with an LSTM def to_lstm_dataset(sequence, n_unique): # one hot encode encoded = encode(sequence, n_unique) # convert to in/out patterns X,y = to_xy_pairs(encoded) # convert to LSTM friendly format dfX, dfy = DataFrame(X), DataFrame(y) lstmX = dfX.values lstmX = lstmX.reshape(lstmX.shape[0], 1, lstmX.shape[1]) lstmY = dfy.values return lstmX, lstmY # define sequences seq1 = [3, 0, 1, 2, 3] seq2 = [4, 0, 1, 2, 4] # convert sequences into required data format n_unique = len(set(seq1 + seq2)) seq1X, seq1Y = to_lstm_dataset(seq1, n_unique) seq2X, seq2Y = to_lstm_dataset(seq2, n_unique) # define LSTM configuration n_neurons = 20 n_batch = 1 n_epoch = 250 n_features = n_unique # create LSTM model = Sequential() model.add(LSTM(n_neurons, batch_input_shape=(n_batch, 1, n_features), stateful=True)) model.add(Dense(n_unique, activation='sigmoid')) model.compile(loss='binary_crossentropy', optimizer='adam') # train LSTM for i in range(n_epoch): model.fit(seq1X, seq1Y, epochs=1, batch_size=n_batch, verbose=1, shuffle=False) model.reset_states() model.fit(seq2X, seq2Y, epochs=1, batch_size=n_batch, verbose=0, shuffle=False) model.reset_states() # test LSTM on sequence 1 print('Sequence 1') result = model.predict_classes(seq1X, batch_size=n_batch, verbose=0) model.reset_states() for i in range(len(result)): print('X=%.1f y=%.1f, yhat=%.1f' % (seq1[i], seq1[i+1], result[i])) # test LSTM on sequence 2 print('Sequence 2') result = model.predict_classes(seq2X, batch_size=n_batch, verbose=0) model.reset_states() for i in range(len(result)): print('X=%.1f y=%.1f, yhat=%.1f' % (seq2[i], seq2[i+1], result[i])) ``` 運行該示例提供關于模型在每個時期的第一序列上的損失的反饋。 在運行結束時,每個序列都在預測的上下文中打印。 ```py ... 4/4 [==============================] - 0s - loss: 0.0930 Epoch 1/1 4/4 [==============================] - 0s - loss: 0.0927 Epoch 1/1 4/4 [==============================] - 0s - loss: 0.0925 Sequence 1 X=3.0 y=0.0, yhat=0.0 X=0.0 y=1.0, yhat=1.0 X=1.0 y=2.0, yhat=2.0 X=2.0 y=3.0, yhat=3.0 Sequence 2 X=4.0 y=0.0, yhat=0.0 X=0.0 y=1.0, yhat=1.0 X=1.0 y=2.0, yhat=2.0 X=2.0 y=4.0, yhat=4.0 ``` 結果顯示了兩件重要的事情: * LSTM一次一步地正確學習每個序列。 * LSTM使用每個序列的上下文來正確地解析沖突的輸入對。 本質上,LSTM能夠記住3個時間步前序列開始處的輸入模式,以正確預測序列中的最后一個值。 這種記憶和LSTM能夠及時關聯觀測的能力是使LSTM如此強大以及它們如此廣泛使用的關鍵能力。 雖然這個例子很簡單,但LSTM能夠在100秒甚至1000秒的時間步長中展示出同樣的能力。 ## 擴展 本節列出了本教程中示例擴展的思路。 * **調整**。經過一些試驗和錯誤后,選擇了LSTM(時期,單位等)的配置。更簡單的配置可能會在此問題上獲得相同的結果。需要搜索一些參數。 * **任意字母**。 5個整數的字母表是任意選擇的。這可以更改為其他符號和更大的字母。 * **長序列**。本例中使用的序列非常短。 LSTM能夠在更長的100s和1000s時間步長序列上展示相同的能力。 * **隨機序列**。本教程中使用的序列呈線性增長。可以創建新的隨機值序列,允許LSTM設計一個通用解決方案,而不是專門用于本教程中使用的兩個序列的解決方案。 * **批量學習**。每個時間步后都對LSTM進行了更新。探索使用批量更新,看看這是否會改善學習。 * **Shuffle Epoch** 。序列在訓練期間的每個時期以相同的順序顯示,并且在評估期間再次顯示。隨機化序列的順序,使得序列1和2適合一個時期,這可以改善模型對具有相同字母表的新看不見的序列的概括。 你有沒有探索過這些擴展? 在下面的評論中分享您的結果。我很想看看你想出了什么。 ## 進一步閱讀 我強烈建議閱讀Hochreiter和Schmidhuber的1997年原始LSTM論文;這很棒。 * [長期短記憶](http://www.mitpressjournals.org/doi/abs/10.1162/neco.1997.9.8.1735),1997 [ [PDF](http://www.bioinf.jku.at/publications/older/2604.pdf) ] ## 摘要 在本教程中,您發現了LSTM能夠記住多個時間步的關鍵功能。 具體來說,你學到了: * 如何定義一個小序列預測問題,只有像LSTM這樣的RNN可以使用內存來解決。 * 如何轉換問題表示,使其適合LSTM學習。 * 如何設計LSTM來正確解決問題。 你有任何問題嗎? 在下面的評論中發表您的問題,我會盡力回答。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看