想想自己未來也能建個 model 來訓練自己打傳說對決,輕鬆上S排,就迫不及待想成為AI 的專家(誤...)
使用循環神經網絡(LSTM)生成文本,要怎麼做到呢?
首先,要先了解生成文本是屬於哪一類的問題?
訓練生成文本的模型,基本上也是輸入一堆的文本資料,讓模型學到文字間的分佈關係,接著輸出是預測一段文字接著要放入哪個文字的機率,ex. 我今天很開__ ,__應該預測填入"心",這種給定前面的標記(token),能夠對下一個標記的概率進行建模的網絡叫作語言模型(language model)。語言模型能夠捕捉到語言的潛在空間(latent space),即語言的統計結構。
總之,就是一個機率的問題,也是多分類的問題,損失函數(loss function)使用categorical_crossentropy。如果模型的輸出是對所有可能的字符做 softmax,得到下一個字符的概率分佈。這個 LSTM 叫作字符級的神經語言模型(character-level neural language model),如下圖,如果是對單詞,則為單詞級的神經語言模型(word-level neural language model)。
在生成文本的時候,在預測生成下一個字符或單詞要如何選擇,有兩個方法:
來實際練習字符級的LSTM 文本生成,書中使用範例是尼采 Nietzsche 的文學作品
可以看到訓練過程中,每個epochs 會隨機生成一段種子文本,然後經由模型預測生成後面的文章。隨著temperature的不同,會產生不一樣的文章。
舉例,在某一次生成的文本中
temperature=0.2 所產出的文章的其中一段"the mankind to the sense of the sense of the presence and the really the best the"
temperature=0.5 "the same noursely and the dease and person which be been an ential the great"
temperature=1.0 "may wild pain immanced to times the and turning way only his egolees lead one for bace regreelens"
可以看到隨著temperature 越大,生成的文章越有創造性,且重複性越低。一定要嘗試多種採樣策略!在學到的結構與隨機性之間,巧妙的平衡能夠讓生成的序列非常有趣。
總之,就是一個機率的問題,也是多分類的問題,損失函數(loss function)使用categorical_crossentropy。如果模型的輸出是對所有可能的字符做 softmax,得到下一個字符的概率分佈。這個 LSTM 叫作字符級的神經語言模型(character-level neural language model),如下圖,如果是對單詞,則為單詞級的神經語言模型(word-level neural language model)。
(圖片來源)
在生成文本的時候,在預測生成下一個字符或單詞要如何選擇,有兩個方法:
- greedy sampling,貪婪採樣,在生成過程只選擇可能性最大的,意即只有某個特定字符的概率為 1,其他字符概率都為 0,這樣做會讓生成的文章更接近真實文章,同時也會讓文章重複率提高,使文章變得無趣。
- stochastic sampling,隨機採樣,在概率分佈中隨機選擇其中一個,我們無法控制生成的字符,會讓文章看起來有點無俚頭,但是這樣可以讓模型產生更有意思的句子,是我們無法想像的。
來實際練習字符級的LSTM 文本生成,書中使用範例是尼采 Nietzsche 的文學作品
#下載並解析初始文本文件
import keras
import numpy as np
path = keras.utils.get_file('nietzsche.txt', origin='https://s3.amazonaws.com/text-datasets/nietzsche.txt')
text = open(path).read().lower()
print('Corpus length:', len(text))
#將字符序列向量化
maxlen = 60 #提取60 個字符組成的序列
step = 3 #每3個字符採樣一個新序列
sentences = [] #保存所提取的序列
next_chars = [] #保存目標(即下一個字符)
for i in range(0, len(text) - maxlen, step):
sentences.append(text[i: i + maxlen])
next_chars.append(text[i + maxlen])
print('Number of sequences:', len(sentences))
chars = sorted(list(set(text)))
print('Unique characters:', len(chars))
char_indices = dict((char, chars.index(char)) for char in chars)
print('Vectorization...')
x = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)
y = np.zeros((len(sentences), len(chars)), dtype=np.bool)
for i, sentence in enumerate(sentences):
for t, char in enumerate(sentence):
x[i, t, char_indices[char]] = 1
y[i, char_indices[next_chars[i]]] = 1
#建構網絡模型
from keras import layers
model = keras.models.Sequential()
model.add(layers.LSTM(128, input_shape=(maxlen, len(chars))))
model.add(layers.Dense(len(chars), activation='softmax'))
#編譯器,優化器&損失函數
optimizer = keras.optimizers.RMSprop(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)
#給定模型預測,採樣下一個字符的函數
def sample(preds, temperature=1.0):
preds = np.asarray(preds).astype('float64')
preds = np.log(preds) / temperature
exp_preds = np.exp(preds)
preds = exp_preds / np.sum(exp_preds)
probas = np.random.multinomial(1, preds, 1)
return np.argmax(probas)
#生成文本循環
import random
import sys
for epoch in range(1, 60):
print('epoch', epoch)
model.fit(x, y, batch_size=128, epochs=1)
start_index = random.randint(0, len(text) - maxlen - 1)
generated_text = text[start_index: start_index + maxlen]
print('--- Generating with seed: "' + generated_text + '"')
model.save_weights('LSTM_gen_model.h5') #將model 保存起來
for temperature in [0.2, 0.5, 1.0]:
print('------ temperature:', temperature,"\n")
sys.stdout.write(generated_text)
for i in range(400):
sampled = np.zeros((1, maxlen, len(chars)))
for t, char in enumerate(generated_text):
sampled[0, t, char_indices[char]] = 1.
preds = model.predict(sampled, verbose=0)[0]
next_index = sample(preds, temperature)
next_char = chars[next_index]
generated_text += next_char
generated_text = generated_text[1:]
sys.stdout.write(next_char)
可以看到訓練過程中,每個epochs 會隨機生成一段種子文本,然後經由模型預測生成後面的文章。隨著temperature的不同,會產生不一樣的文章。
舉例,在某一次生成的文本中
temperature=0.2 所產出的文章的其中一段"the mankind to the sense of the sense of the presence and the really the best the"
temperature=0.5 "the same noursely and the dease and person which be been an ential the great"
temperature=1.0 "may wild pain immanced to times the and turning way only his egolees lead one for bace regreelens"
可以看到隨著temperature 越大,生成的文章越有創造性,且重複性越低。一定要嘗試多種採樣策略!在學到的結構與隨機性之間,巧妙的平衡能夠讓生成的序列非常有趣。
沒有留言:
張貼留言