近年來,循環(huán)神經網(wǎng)絡 (RNN) 受到了廣泛關注,因為它在許多自然語言處理任務中顯示出了巨大的前景。 盡管它們很受歡迎,但解釋如何使用最先進的工具實現(xiàn)簡單而有趣的應用程序的教程數(shù)量有限。在本系列中,我們將使用循環(huán)神經網(wǎng)絡來訓練 AI 程序員,該程序員可以像真正的程序員一樣編寫 Java 代碼(希望如此)。將涵蓋以下內容:
3. 改進 AI 程序員 - 使用不同的網(wǎng)絡結構(這篇文章)
在之前的文章中,我們分別使用字符和標記作為訓練數(shù)據(jù)構建了一個基本的 AI 程序員。這兩種方法都使用一個簡單的 1 層 LSTM 神經網(wǎng)絡。更具體地說,網(wǎng)絡使用多對一的結構,如下圖所示:
對于序列到序列的預測,還有其他結構,例如一對多和多對多。在這篇文章中,我們將實現(xiàn)一個簡單的多對多網(wǎng)絡結構,如下所示。代碼被推送到 GitHub 上的同一個存儲庫(本文末尾提供了鏈接)。
由于代碼的大部分與上一篇文章相同,我在這里只強調不同之處。
1.準備訓練數(shù)據(jù)
由于這次我們將預測一個序列而不是下一個標記,因此 ?y
? 也應該是一個序列。?y
? 是從 ?X
? 左移 ?1
?的序列。
NUM_INPUT_TOKENS = 10
step = 3
sequences = []
for i in range(0, len(tokenized) - NUM_INPUT_TOKENS-1, step):
sequences.append(tokenized[i: i + NUM_INPUT_TOKENS+1])
print('# of training sequences:', len(sequences))
X_temp = np.zeros((len(sequences), NUM_INPUT_TOKENS + 1, len(uniqueTokens)), dtype=np.bool)
X = np.zeros((len(sequences), NUM_INPUT_TOKENS, len(uniqueTokens)), dtype=np.bool)
y = np.zeros((len(sequences), NUM_INPUT_TOKENS, len(uniqueTokens)), dtype=np.bool)
for i, sequence in enumerate(sequences):
for t, char in enumerate(sequence):
X_temp[i, t, token_indices[char]] = 1
num_sequences = len(X_temp)
for i, vec in enumerate(X_temp):
y[i] = vec[1:]
X[i]= vec[:-1]
2. 構建多對多循環(huán)神經網(wǎng)絡
這是構建多對多循環(huán)網(wǎng)絡的代碼。
model = Sequential()
model.add(LSTM(128, input_shape=(NUM_INPUT_TOKENS, len(uniqueTokens)), return_sequences=True))
model.add(TimeDistributed(Dense(len(uniqueTokens))))
model.add(Activation('softmax'))
optimizer = RMSprop(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)
print(model.summary())
你可以打印網(wǎng)絡結構:
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= lstm_1 (LSTM) (None, 10, 128) 670208 _________________________________________________________________ time_distributed_1 (TimeDist (None, 10, 1180) 152220 _________________________________________________________________ activation_1 (Activation) (None, 10, 1180) 0 =================================================================
就像我們?yōu)槎鄬σ唤Y構所做的那樣,我們也可以輕松地多堆疊一層 LSTM,如下所示:
model = Sequential()
model.add(LSTM(128, return_sequences=True, input_shape=(NUM_INPUT_TOKENS, len(uniqueTokens))))
model.add(LSTM(128, return_sequences=True))
model.add(TimeDistributed(Dense(len(uniqueTokens))))
model.add(Activation('softmax'))
optimizer = RMSprop(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)
print(model.summary())
網(wǎng)絡結構是這樣的:
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= lstm_1 (LSTM) (None, 10, 128) 670208 _________________________________________________________________ lstm_2 (LSTM) (None, 10, 128) 131584 _________________________________________________________________ time_distributed_1 (TimeDist (None, 10, 1180) 152220 _________________________________________________________________ activation_1 (Activation) (None, 10, 1180) 0 =================================================================
3. 結果
經過幾次迭代,結果看起來比之前的多對一網(wǎng)絡要好。我強烈建議你在運行代碼能夠有自己的觀察并思考原因。那將是一個很好的練習。
runattributes = numberelements [ i ] . offsets [ currindex ] ;
patternentry ucompactintarray ;
import sun . util . oldstart ;
4. 下一步是什么?
在這篇文章中,我使用了多對多結構的網(wǎng)絡來訓練模型,模型預測令牌序列。也許為了好玩,你也可以嘗試一對多網(wǎng)絡。此外,我們還可以調整許多其他參數(shù),以加快訓練速度并使 AI Programmer 變得更好。