Реализация NNLM tensorflow1.14

глубокое обучение

Оригинальная ссылка находится на городской почте:Ву Ву Две сестры.org/papers/Vol U…

Идея использования NNLM: языковая модель, которая вводит последовательность предложений и предсказывает следующее слово (английский) или слово (китайский).

Этапы операции следующие (в качестве примера возьмем английские предложения, китайские аналогичны):

avatar

  1. Входной слой: сегментация слов, индексы слов сопоставляются друг с другом, целевое слово используется в качестве метки, а первые n-1 слов выше используются в качестве входных данных.

  2. Слой проекции: в слое проекции look_up выполняется для векторов слов V*m, где V — размер словаря, а m — размерность вектора слова. Каждая строка в C используется как распределенное представление слов, и каждое слово преобразуется в вектор слов через таблицу C. Векторы слов n-1 пишутся от начала до конца и преобразуются в матрицу пространственного вектора (n-1)*m.

  3. Скрытый слой: Рассчитывается по формуле hidden = tanh(d+X*H), этот слой представляет собой нелинейный полносвязный слой tanh, а H и d можно понимать как весовые параметры и параметры смещения скрытого слоя.

  4. Выходной слой: вычисляется по формуле 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']