NLP-tutorial-1_神经网络语言模型(NNLM)

前言

最近看到一个Github内容不错,就当做个笔记。

神经语言模型(NNLM)

2003年,NNLM首次将神经网络应用到语言模型的问题中,从此深度学习就登上了NLP的舞台,并有把传统模型赶下去的趋势。
语言模型可以说是用前n-1个单词做为输入去预测第n个单词,也就是说第n个词是哪个单词的时候,才使得这句话像是正常的话,有正常的语序,使用正确且恰当的词。
NNLM经典图
下面我将结合代码理解NNLM。

代码简析

  1. 导入要用到的库。
import tensorflow as tf
import numpy as np
print(tf.__version__)
tf.reset_default_graph() # 重置图
  1. 使用三句话做为数据集,将数据集分词,每个词对应一个自然数形成word_dict字典。
sentences = [ "i like dog", "i love coffee", "i hate milk"]  # 数据集
word_list = " ".join(sentences).split()
word_list = list(set(word_list))
word_dict = {w: i for i, w in enumerate(word_list)}
number_dict = {i: w for i, w in enumerate(word_list)}
  1. NNLM模型用到的参数。
n_class = len(word_dict)   # 字典中词的种类
# NNLM Parameter
n_step = 2 # number of steps ['i like', 'i love', 'i hate']
n_hidden = 2 # number of hidden units
  1. 数据集中都是三个单词组组成,输入为前两个单词,标签是后一个单词。对数据进行one-hot编码,长度为n_class。
#  训练集是前两个词  标签是最后一个词 相当于one_hot
def make_batch(sentences):
   input_batch = []
   target_batch = []

   for sen in sentences:
       word = sen.split()
       input = [word_dict[n] for n in word[:-1]]
       target = word_dict[word[-1]]

       input_batch.append(np.eye(n_class)[input])
       target_batch.append(np.eye(n_class)[target])

   return input_batch, target_batch
  1. 模型的初始化,单层二个神经元的全连接前馈网络。
# Model 初始化
X = tf.placeholder(tf.float32, [None, n_step, n_class]) # [batch_size, number of steps, number of Vocabulary]
Y = tf.placeholder(tf.float32, [None, n_class])

input = tf.reshape(X, shape=[-1, n_step * n_class]) # [batch_size, n_step * n_class]
H = tf.Variable(tf.random_normal([n_step * n_class, n_hidden]))
d = tf.Variable(tf.random_normal([n_hidden]))
U = tf.Variable(tf.random_normal([n_hidden, n_class]))
b = tf.Variable(tf.random_normal([n_class]))

tanh = tf.nn.tanh(d + tf.matmul(input, H)) # [batch_size, n_hidden]
model = tf.matmul(tanh, U) + b # [batch_size, n_class]

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=model, labels=Y))
optimizer = tf.train.AdamOptimizer(0.001).minimize(cost)
prediction =tf.argmax(model, 1)   #  得到每行的最大值
  1. 训练
# Training
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

input_batch, target_batch = make_batch(sentences)  # 得到数据
print("input_batch ",input_batch,len(input_batch),"\n","target_batch", target_batch,len(target_batch))
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))
  1. 验证结果
predict =  sess.run([prediction], feed_dict={X: input_batch})
# Test
input = [sen.split()[:2] for sen in sentences]
print([sen.split()[:2] for sen in sentences], '->', [number_dict[n] for n in predict[0]])

结果

结果
我们发现最终预测的结果和之前标签完全符合。

总结

  • 本文实现的是简化版的NNLM,输入数据只是用了one-hot编码,缺点是当字典变得更长的时候one-hot的维度会非常大,NNLM使用了Embedding会减少维度,但是在优化参数的同时优化Embedding会导致参数变多。
  • 还有一点而且最后softmax得到的输出和之前的Embeddign也可以当做词向量。词向量可以说是语言模型的副产品,最终青出于蓝而胜于蓝了。
  • NNLM的缺点没有考虑词的顺序,也就是说两个词可能形成词组的问题。
  • 个人理解,欢迎指出错误

参考

参考的Github:https://github.com/graykode/nlp-tutorial
详细总结的代码:https://github.com/Clayygou/NLP/blob/master/NNLM.ipynb

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值