转载请注明作者:梦里风林
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还有一种方式,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
整体思路是,以一个文本中的一个词作为train data,后续的所有词作为train label,从而能够根据一个给定词,预测后续的片段。
input_gate = sigmoid(i * ix + o * im + ib)
- 给输入乘一个vocabulary_size * num_nodes大小的矩阵,给输出乘一个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计算方法都是一样的,
可以把四组参数分别合并,一次计算,再分别取出:
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的输出扔到一个WX+b中调整作为输出
实现代码见singlew_lstm.py
实现代码见lstm.py
上面的流程里,每次都是以一个字符作为单位,可以使用多一点的字符做预测,取最高概率的那个,防止特殊情况导致的误判
在这里我们增加字符为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?
土豪可以打赏支持,一分也是爱: