轉載請注明作者:夢里風林
Github工程地址:https://github.com/ahangchen/GDLnotes
歡迎star,有問題可以到Issue區討論
官方教程地址
視頻/字幕下載
text8中只包括27種字符:小寫的從a到z,和空格符。如果把它打出來,讀起來就像是去掉了所有標點的wikipedia。
達成隨機取數據的目標
embeddings = tf.Variable(
tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))
embed = tf.nn.embedding_lookup(embeddings, train_dataset)
loss = tf.reduce_mean(
tf.nn.sampled_softmax_loss(softmax_weights, softmax_biases, embed,
train_labels, num_sampled, vocabulary_size))
optimizer = tf.train.AdagradOptimizer(1.0).minimize(loss)
自適應梯度調理器,調理embedding列表的數據,使得偏差最小
預測,并用cos值計算預測向量與實際數據的夾角作為預測準確度(類似度)指標
data_index = (data_index + 1) % len(data)
實現代碼見word2vec.py
上面訓練的是Skip-gram模型,是根據目標辭匯預測上下文,而word2vec還有1種方式,CBOW,根據上下文預測目標辭匯。
實際上就是將Skip-gram中的輸入輸出反過來。
修改截取數據的方式
分別從embeding里找到train_data里每一個word對應的vector,用tf.reduce_sum將其相加,將相加結果與train_label比較
# Look up embeddings for inputs.
embed = tf.nn.embedding_lookup(embeddings, train_dataset)
# sum up vectors on first dimensions, as context vectors
embed_sum = tf.reduce_sum(embed, 0)
代碼見:
cbow.py
整體思路是,以1個文本中的1個詞作為train data,后續的所有詞作為train label,從而能夠根據1個給定詞,預測后續的片斷。
input_gate = sigmoid(i * ix + o * im + ib)
- 給輸入乘1個vocabulary_size * num_nodes大小的矩陣,給輸出乘1個num_nodes * num_nodes大小的矩陣;
- 用這兩個矩陣調理對輸入數據的取舍程度
- 用sigmoid這個非線性函數進行激活
forget_gate = sigmoid(i * fx + o * fm + fb)
思路同輸入門,用以對歷史數據做取舍
output_gate = sigmoid(i * ox + o * om + ob)
思路同輸入門,用以對輸出狀態做取舍
update = i * cx + o * cm + cb
state = forget_gate * state + input_gate * tanh(update)
lstm_cell = output_gate * tanh(state)
- 用一樣的方式構造新狀態update
- 用遺忘門處理歷史狀態state
- 用tanh激活新狀態update
- 用輸入門處理新狀態update
- 整合新舊狀態,再用tanh激活狀態state
- 用輸出門處理state
上面的cell中,update,output_gate,forget_gate,input_gate計算方法都是1樣的,
可以把4組參數分別合并,1次計算,再分別取出:
values = tf.split(1, gate_count, tf.matmul(i, input_weights) + tf.matmul(o, output_weights) + bias)
input_gate = tf.sigmoid(values[0])
forget_gate = tf.sigmoid(values[1])
update = values[2]
再將lstm-cell的輸出扔到1個WX+b中調劑作為輸出
實現代碼見singlew_lstm.py
實現代碼見lstm.py
上面的流程里,每次都是以1個字符作為單位,可使用多1點的字符做預測,取最高幾率的那個,避免特殊情況致使的誤判
在這里我們增加字符為2個,構成bigram,代碼見:bigram_lstm.py
主要通過BigramBatchGenerator類實現
由于bigram情況下,vocabulary_size變成 27*27個,使用one-hot encoding 做predict的話會產生非常稀疏的矩陣,浪費算力,計算速度慢
因此引入embedding_lookup,代碼見embed_bigram_lstm.py
def create_model(sess, forward_only):
model = seq2seq_model.Seq2SeqModel(source_vocab_size=vocabulary_size,
target_vocab_size=vocabulary_size,
buckets=[(20, 21)],
size=256,
num_layers=4,
max_gradient_norm=5.0,
batch_size=batch_size,
learning_rate=1.0,
learning_rate_decay_factor=0.9,
use_lstm=True,
forward_only=forward_only)
return model
覺得我的文章對您有幫助的話,無妨點個star?