Оригинальная ссылка находится на городской почте:Ву Ву Две сестры.org/papers/Vol U…
Идея использования NNLM: языковая модель, которая вводит последовательность предложений и предсказывает следующее слово (английский) или слово (китайский).
Этапы операции следующие (в качестве примера возьмем английские предложения, китайские аналогичны):
-
Входной слой: сегментация слов, индексы слов сопоставляются друг с другом, целевое слово используется в качестве метки, а первые n-1 слов выше используются в качестве входных данных.
-
Слой проекции: в слое проекции look_up выполняется для векторов слов V*m, где V — размер словаря, а m — размерность вектора слова. Каждая строка в C используется как распределенное представление слов, и каждое слово преобразуется в вектор слов через таблицу C. Векторы слов n-1 пишутся от начала до конца и преобразуются в матрицу пространственного вектора (n-1)*m.
-
Скрытый слой: Рассчитывается по формуле hidden = tanh(d+X*H), этот слой представляет собой нелинейный полносвязный слой tanh, а H и d можно понимать как весовые параметры и параметры смещения скрытого слоя.
-
Выходной слой: вычисляется по формуле y=b+X*W+ hidden*U , этот слой является выходным слоем softmax, и соответствующие предсказанные слова могут быть получены в соответствии с вероятностью, U — параметр выходного слоя, b — смещение выходного слоя. W — параметр того, что вектор слов напрямую связан с выходным путем, но матрица не обязательна и может быть равна 0.
import tensorflow as tf import numpy as np tf.reset_default_graph() sentences = ['i like damao','i hate meng','i love maga'] words = " ".join(sentences).split() words = list(set(words)) word2idx = {v:k for k,v in enumerate(words)} idx2word = {k:v for k,v in enumerate(words)} n_step = 2 # 窗口大小 dim = 50 # 词向量维度 n_hidden = 10 # 隐藏层大小 V = len(words) # 词库大小 # 生成输入和标签 def make_batch(sentences): input_batch = [] target_batch = [] for sentence in sentences: words = sentence.split() input = [word2idx[word] for word in words[:-1]] # 将除了最后一个字的所有单词都加入 input target = word2idx[words[-1]] # 将要预测的单词加入 target input_batch.append(input) target_batch.append(np.eye(V)[target]) # 这里是对 target 做热独编码,在下面计算 softmax_cross_entropy_with_logits_v2 会用到 return input_batch, target_batch X = tf.placeholder(tf.int64, [None, n_step]) Y = tf.placeholder(tf.int64, [None, V]) embedding = tf.get_variable(name="embedding", shape=[V, dim], initializer= tf.random_normal_initializer()) # 随机生成词向量 XX = tf.nn.embedding_lookup(embedding, X) # 词嵌入 # 根据 y=b+X*W+tanh(d+X*H)*U 写代码 input = tf.reshape(XX, shape=[-1, n_step*dim]) H = tf.Variable(tf.random_normal([n_step*dim, n_hidden])) d = tf.Variable(tf.random_normal([n_hidden])) U = tf.Variable(tf.random_normal([n_hidden, V])) b = tf.Variable(tf.random_normal([V])) W = tf.Variable(tf.random_normal([n_step*dim, V])) A = tf.nn.tanh(tf.matmul(input, H) + d) B = tf.matmul(input, W) + tf.matmul(A, U) + b # 计算损失并进行优化 cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=B, labels=Y)) optimizer = tf.train.AdamOptimizer(0.001).minimize(cost) # 预测结果 prediction = tf.argmax(B, 1) # tf 初始化 init = tf.global_variables_initializer() sess = tf.Session() sess.run(init) # 开始训练 input_batch, target_batch = make_batch(sentences) for epoch in range(5000): _, loss = sess.run([optimizer, cost], feed_dict={X:input_batch, Y:target_batch}) if (epoch+1)%1000==0: print('epoch:','%04d'%(epoch+1), 'cost =', '{:.6f}'.format(loss)) # 使用训练样本进行简单的预测 predict = sess.run([prediction], feed_dict={X:input_batch}) print(predict) print([sen.split()[:2] for sen in sentences], '->', [idx2word[i] for i in predict[0]])
Результат печати следующий:
epoch: 1000 cost = 0.001325 epoch: 2000 cost = 0.000391 epoch: 3000 cost = 0.000178 epoch: 4000 cost = 0.000094 epoch: 5000 cost = 0.000053 [['i', 'like'], ['i', 'hate'], ['i', 'love']] -> ['damao', 'meng', 'maga']