原創帖子,轉載請說明出處html
1、RNN神經網絡結構python
RNN隱藏層神經元的鏈接方式和普通神經網路的鏈接方式有一個很是明顯的區別,就是同一層的神經元的輸出也成爲了這一層神經元的輸入。固然同一時刻的輸出是不可能做爲這個時刻的輸入的。因此是前一個時刻(t-1)的輸出做爲這個時刻(t)的輸入。算法
序列結構展開示意圖,s爲隱藏層,o爲輸出層,x爲輸入層,U爲輸入層到隱層的權重矩陣,V則是隱層到輸出層的權重矩陣,這個網絡在t時刻接收到輸入 以後,隱藏層的值是
,輸出值是
。關鍵一點是,
的值不只僅取決於
,還取決於
。數據庫
2、RNN應用範圍網絡
RNNs主要用於處理NLP類的問題,如詞向量表達、語句合法性檢查、詞性標註等。在RNNs中,目前使用最普遍最成功的模型即是LSTMs(Long Short-Term Memory,長短時記憶模型)模型,該模型一般比vanilla RNNs可以更好地對長短時依賴進行表達,該模型相對於通常的RNNs,只是在隱藏層作了手腳。下篇文章會對LSTM進行介紹。數據結構
3、使用RNN進行影評情感分析函數
0x00 實驗環境性能
tensorflow2.0,此版本的keras已經被包含到tf中,導入keras時注意加入tensorflow前綴,若是想關閉vision2.0版本的特性的話,可使用:學習
import tensorflow.compat.v1 as tf tf.disable_v2_behavior()
0x01 數據預處理測試
導入數據集和相應的庫,這裏使用imdb數據集
#導入imdb影評庫 from tensorflow.keras.datasets import imdb from tensorflow.keras.preprocessing import sequence
以後咱們對數據集與訓練集進行劃分,下面的vocab_num表明着我要從imdb數據庫中導入10000條數據,第二行的左括號與右括號表明訓練集與測試集的劃分
#劃分訓練集與測試集 #label中的0表明消極,1表明積極 vocab_num=10000 (X_train,y_train),(X_test,y_test)=imdb.load_data(num_words=vocab_num) print("----review----") print(X_train[5]) print("----label-----") print(y_train[5])
打印結果
----review---- [1, 6740, 365, 1234, 5, 1156, 354, 11, 14, 5327, 6638, 7, 1016, 2, 5940, 356, 44, 4, 1349, 500, 746, 5, 200, 4, 4132, 11, 2, 9363, 1117, 1831, 7485, 5, 4831, 26, 6, 2, 4183, 17, 369, 37, 215, 1345, 143, 2, 5, 1838, 8, 1974, 15, 36, 119, 257, 85, 52, 486, 9, 6, 2, 8564, 63, 271, 6, 196, 96, 949, 4121, 4, 2, 7, 4, 2212, 2436, 819, 63, 47, 77, 7175, 180, 6, 227, 11, 94, 2494, 2, 13, 423, 4, 168, 7, 4, 22, 5, 89, 665, 71, 270, 56, 5, 13, 197, 12, 161, 5390, 99, 76, 23, 2, 7, 419, 665, 40, 91, 85, 108, 7, 4, 2084, 5, 4773, 81, 55, 52, 1901] ----label----- 1
上面打印結果顯示的數字表明着字典中對應單詞的索引,咱們使用下面的代碼來找出每一個索引對應的詞
word2id = imdb.get_word_index() id2word = {i: word for word,i in word2id.items()} print('---review with word---') print([id2word.get(i, '') for i in X_train[6]])
爲了讓數據可以輸入 RNN 模型,全部的輸入文檔必須有相同的長度。咱們須要設置max_words變量來限制評論的最大長度,超過該長度的評論將被截斷,不足該長度的評論將被填充空值(0)。在 Keras 中,咱們可使用pad_sequences()函數來達到此目標。如今設置max_words變量的值爲 500。
from tensorflow.keras.preprocessing.sequence import pad_sequences max_words=500 X_train = pad_sequences(X_train, maxlen=max_words) X_test = pad_sequences(X_test, maxlen=max_words)
0x02 模型創建
from tensorflow.keras import Sequential from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout embedding_size = 32 model=Sequential() model.add(Embedding(vocab_num,embedding_size, input_length= max_words)) model.add(LSTM(100)) model.add(Dense(1, activation='sigmoid')) print(model.summary())
這裏逐個解釋一下每一個參數的狀況。這幾步爲創建神經網絡的基本流程。
(1)首先,embedding_size,是第六行嵌入層的一個參數,嵌入層,要了解它,首先要知道詞嵌入,這裏以https://juejin.im/entry/5acc23f26fb9a028d1416bb3 這篇文章來簡單介紹一下詞嵌入以及embedding層的做用。詞嵌入是對傳統的詞袋模型編碼方案的改進,詞袋模型能夠看這篇http://www.javashuo.com/article/p-hvjqhyxj-dg.html ,
在嵌入中,單詞由密集向量表示,其中向量表示將單詞投影到連續向量空間中。向量空間中的單詞的位置是從文本中學習的,而且基於在使用單詞時圍繞單詞的單詞。學習到的向量空間中的單詞的位置被稱爲它的嵌入:Embedding。通俗的說,就是以一種比較準確的方式表達詞的位置。
Keras提供了一個嵌入層,適用於文本數據的神經網絡。它要求輸入數據是整數編碼的,因此每一個字都用一個惟一的整數表示。例如咱們這篇文章說到的imdb的詞庫中每一個數字表明的詞。嵌入層用隨機權重進行初始化,並將學習訓練數據集中全部單詞的嵌入。
嵌入層被定義爲網絡的第一個隱藏層。它必須指定3個參數:
所以,這裏的embedding_size就是嵌入單詞的向量空間大小,同時,嵌入層的輸出是一個二維向量,每一個單詞在輸入文本(輸入文檔)序列中嵌入一個。
(2)sequential()
Keras有兩種類型的模型,序貫模型(Sequential)和函數式模型(Model),函數式模型應用更爲普遍,序貫模型是函數式模型的一種特殊狀況。sequential model就是那種最簡單的結構的模型。按順序一層一層訓練,一層一層往前的那種。沒有什麼環的結構。好比像前饋網絡那樣。Keras 的核心數據結構是「模型」,模型是一種組織網絡層的方式。Keras 中主要的模型是 Sequential 模型,Sequential 是一系列網絡層按順序構成的棧。
(3) 以後加入LSTM
Keras中的LSTM函數參數能夠參考這篇文章:https://blog.csdn.net/jiangpeng59/article/details/77646186 ,這裏的100是指輸出維度爲100
(4)Dense層
這裏的DENSE層添加了激活函數爲sigmoid,Dense層的詳細知識能夠見:https://blog.csdn.net/m0_37592397/article/details/79982601
(5)model.summary是指展現model的層數現狀,這裏的顯示結果爲:
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding (Embedding) (None, 500, 32) 320000 _________________________________________________________________ lstm (LSTM) (None, 100) 53200 _________________________________________________________________ dense (Dense) (None, 1) 101 ================================================================= Total params: 373,301 Trainable params: 373,301 Non-trainable params: 0 _________________________________________________________________ None
0x03 模型訓練
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) from tensorflow.keras.callbacks import EarlyStopping #from tensorboardcolab import TensorBoardColab #tbc = TensorBoardColab() es = EarlyStopping(monitor = "val_loss", patience = 10) batch_size = 64 num_epochs = 10 X_valid, y_valid = X_train[:batch_size], y_train[:batch_size] X_train2, y_train2 = X_train[batch_size:], y_train[batch_size:] model.fit(X_train2, y_train2, validation_data=(X_valid, y_valid), batch_size=batch_size, epochs=num_epochs, callbacks = [es])
(1)model.compile
這個函數主要爲設置損失函數和優化器及評估標準。參數設置以下:
rmsprop
或 adagrad
,也能夠是 Optimizer 類的實例。詳見:optimizers。categorical_crossentropy
或 mse
,也能夠是一個目標函數。詳見:losses。metrics = ['accuracy']
。評估標準能夠是現有的標準的字符串標識符,也能夠是自定義的評估標準函數(2)earlystipping
這個爲keras封裝的回調函數,具體信息能夠查看https://keras.io/zh/callbacks/,具體的做用爲當被監測的數量再也不提高,則中止訓練
(3)batch_size,num_epochs
簡單說,epochs 指的就是訓練過程當中數據將被「輪詢」多少次。
深度學習的優化算法,說白了就是梯度降低。每次的參數更新有兩種方式。
第一種,遍歷所有數據集算一次損失函數,而後算函數對各個參數的梯度,更新梯度。這種方法每更新一次參數都要把數據集裏的全部樣本都看一遍,計算量開銷大,計算速度慢,不支持在線學習,這稱爲批梯度降低(Batch gradient descent)。
另外一種,每看一個數據就算一下損失函數,而後求梯度更新參數,這個稱爲隨機梯度降低(stochastic gradient descent)。這個方法速度比較快,可是收斂性能不太好,可能在最優勢附近晃來晃去,達不到最優勢。兩次參數的更新也有可能互相抵消掉,形成目標函數震盪的比較劇烈。
爲了克服兩種方法的缺點,如今通常採用的是一種折中手段,小批的梯度降低(mini-batch gradient decent),這種方法把數據分爲若干個批,按批來更新參數,這樣,一個批中的一組數據共同決定了本次梯度的方向,降低起來就不容易跑偏,減小了隨機性。另外一方面由於批的樣本數與整個數據集相比小了不少,因此計算量也不是很大。基本上如今的梯度降低都是基於 mini-batch 的,因此 Keras 的模塊中常常會出現 batch_size
,就是指這個。
(4)model.fit函數啓動訓練
0x04 模型評估
scores = model.evaluate(X_test, y_test, verbose=0) print('Test accuracy:', scores[1])
(1)verbose
verbose:日誌顯示,verbose = 0 爲不在標準輸出流輸出日誌信息,verbose = 1 爲輸出進度條記錄,verbose = 2 爲每一個epoch輸出一行記錄
0x05 所有代碼
由於懶因此麻煩各位本身複製整合了
4、總結
RNN的基本實踐流程如上,這是網咯上大部分文章共同流傳的一個python代碼的例子,我這裏將每一行代碼進行講解,適用於具有一丁點ML或者DL基礎的旁友觀看。