近年來,循環(huán)神經(jīng)網(wǎng)絡(luò) (RNN) 受到了廣泛關(guān)注,因為它在許多自然語言處理任務(wù)中顯示出了巨大的前景。 盡管它們很受歡迎,但解釋如何使用最先進的工具實現(xiàn)簡單而有趣的應(yīng)用程序的教程數(shù)量有限。在本系列中,我們將使用循環(huán)神經(jīng)網(wǎng)絡(luò)來訓(xùn)練 AI 程序員,該程序員可以像真正的程序員一樣編寫 Java 代碼(希望如此)。將涵蓋以下內(nèi)容:
3. 改進 AI 程序員 - 使用不同的網(wǎng)絡(luò)結(jié)構(gòu)(這篇文章)
在之前的文章中,我們分別使用字符和標(biāo)記作為訓(xùn)練數(shù)據(jù)構(gòu)建了一個基本的 AI 程序員。這兩種方法都使用一個簡單的 1 層 LSTM 神經(jīng)網(wǎng)絡(luò)。更具體地說,網(wǎng)絡(luò)使用多對一的結(jié)構(gòu),如下圖所示:
對于序列到序列的預(yù)測,還有其他結(jié)構(gòu),例如一對多和多對多。在這篇文章中,我們將實現(xiàn)一個簡單的多對多網(wǎng)絡(luò)結(jié)構(gòu),如下所示。代碼被推送到 GitHub 上的同一個存儲庫(本文末尾提供了鏈接)。
由于代碼的大部分與上一篇文章相同,我在這里只強調(diào)不同之處。
1.準(zhǔn)備訓(xùn)練數(shù)據(jù)
由于這次我們將預(yù)測一個序列而不是下一個標(biāo)記,因此 ?y
? 也應(yīng)該是一個序列。?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. 構(gòu)建多對多循環(huán)神經(jīng)網(wǎng)絡(luò)
這是構(gòu)建多對多循環(huán)網(wǎng)絡(luò)的代碼。
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)絡(luò)結(jié)構(gòu):
_________________________________________________________________ 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(jié)構(gòu)所做的那樣,我們也可以輕松地多堆疊一層 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)絡(luò)結(jié)構(gòu)是這樣的:
_________________________________________________________________ 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. 結(jié)果
經(jīng)過幾次迭代,結(jié)果看起來比之前的多對一網(wǎng)絡(luò)要好。我強烈建議你在運行代碼能夠有自己的觀察并思考原因。那將是一個很好的練習(xí)。
runattributes = numberelements [ i ] . offsets [ currindex ] ;
patternentry ucompactintarray ;
import sun . util . oldstart ;
4. 下一步是什么?
在這篇文章中,我使用了多對多結(jié)構(gòu)的網(wǎng)絡(luò)來訓(xùn)練模型,模型預(yù)測令牌序列。也許為了好玩,你也可以嘗試一對多網(wǎng)絡(luò)。此外,我們還可以調(diào)整許多其他參數(shù),以加快訓(xùn)練速度并使 AI Programmer 變得更好。