当前位置:   article > 正文

语言模型(NNLM)

nnlm

本文主要学习神经网络语言模型,并在文末给出简单的代码demo,便于学习,整体上主要是从表示学习的发展方面展开;

一 .表示学习

数据表示

面对复杂的概念,可以找到一个表达,化繁从简。机器学习中,找到对于原始数据更好的表达,方便后续任务(分类、序列标注、匹配等)

 特征学习(feature learning),又叫表示学习(representation learning)或者表征学习,一般指的是自动学习有用的数据特征,采用模型自动学习数据的隐式特征,不依赖专家经验,需要较大的数据训练集

特征工程(feature engineering),主要指对于数据的人为处理提取,依靠专家提取显示特征,特征选取的好坏直接决定数据表示质量,影响后续任务

 one-hot编码

前期的统计学习方法中,较为常见的表示是使用离散的符号表示词信息,如独热表示(one-hot)

 (1).简单直接,易于计算

 (2).矩阵每一个维度的长度等于字典的长度,只有一个1,其他为0,非常稀疏,容易造成维度灾难

 (3).只能表示词语本身 ,无法体现单词语义信息,以及单词之间的关系

词嵌入  (word-embedding)

word-embedding 是词的分布式嵌入表示,使用多维度信息联合表示一个词语

 

(1).多维度联合表示一个词语,每一个维度反应潜在语义信息

(2).语义相似的词在向量空间上也能表现出来

(3).缓解数据稀疏影响,获得更好的泛化能力

二 .语言模型

主要是用来计算一个句子出现的概率

通俗点说,就是计算一句话 看起来是否像人说的话,比如,“我喜欢读书”、“我读书喜欢”。那么后者看起来就不像是一句话,前者计算的概率值较大。上面的计算公式,依据的是条件概率的计算公式。

 每一项的P(w)的计算使用的是单词的频率计算,后面会讲到

 针对以上问题,引入马尔可夫假设,给定当前知识情况下,过去(即以前的历史状态)对于预测将来(即当前以后的未来状态)是无关的

1.一元语言模型(n = 1),也叫做unigram

当前的word不依赖任何word,每个word 都是独立

2.二元语言模型(n = 2),也叫做bigram

当前的word依赖前一个word

3.三元语言模型(n = 3),也叫做trigram

当前的word依赖前两个word

总结下:

总体来说,bigram 和trigram 语言模型使用较多,unigram 使用很少,基本不怎么使用,主要是一元语言模型相对二元和三元语言模型,很难度量不相似句子

例子:

sentence1 = 我想吃苹果,sentence2 = 我想喝苹果

一元语言模型,计算的 sentence1 结果为 P1= P(我) *  P(想) * P(吃) * P(苹) * P(果)

计算的 sentence2 结果为 P2= P(我) *  P(想) * P(喝) * P(苹) * P(果)

由于都是使用频次统计P的概率,所以最终 P1 和 P2 相等,其实大家知道,sentence1和sentence2的区别还挺大的

二元语言模型例子

利用极大似然估计,得到条件概率计算公式如下:

二元语言模型和三元语言模型能比一元语言模型更好的get到两个词语之间的关系信息

三.神经网络语言模型(NNLM)

利用前n-1个词汇,预测第n个词汇

上图中的最右边的矩阵是通过参数学习获取的

具体的过程是以下几步:

(1). 输入n-1个词语,每一个词语进行one-hot 编码 1xV

(2).每一个词语(1xV) 与矩阵Q相乘得到 1xm 表示

(3).得到所有的词向量 (n-1) x m的矩阵,concat后得到 (n-1)*m x 1的向量x

(4).具体公式如下

四 代码示例

  1. import torch
  2. import torch.nn as nn
  3. import torch.optim as optim
  4. import pdb
  5. def make_batch():
  6. input_batch = []
  7. target_batch = []
  8. for sen in sentences:
  9. word = sen.split() # space tokenizer
  10. input = [word_dict[n] for n in word[:-1]] # create (1~n-1) as input
  11. target = word_dict[word[-1]] # create (n) as target, We usually call this 'casual language model'
  12. input_batch.append(input)
  13. target_batch.append(target)
  14. return input_batch, target_batch
  15. # Model
  16. class NNLM(nn.Module):
  17. def __init__(self):
  18. super(NNLM, self).__init__()
  19. self.C = nn.Embedding(n_class, m) ### 矩阵Q (V x m) V 表示word的字典大小, m 表示词向量的维度
  20. self.H = nn.Linear(n_step * m, n_hidden, bias=False) ###
  21. self.d = nn.Parameter(torch.ones(n_hidden))
  22. self.U = nn.Linear(n_hidden, n_class, bias=False)
  23. self.W = nn.Linear(n_step * m, n_class, bias=False)
  24. self.b = nn.Parameter(torch.ones(n_class))
  25. def forward(self, X):
  26. X = self.C(X) # X : [batch_size, n_step, m]
  27. X = X.view(-1, n_step * m) # [batch_size, n_step * m]
  28. tanh = torch.tanh(self.d + self.H(X)) # [batch_size, n_hidden]
  29. output = self.b + self.W(X) + self.U(tanh) # [batch_size, n_class]
  30. return output
  31. if __name__ == '__main__':
  32. n_step = 2 # number of steps, n-1 in paper,根据前两个单词预测第三个
  33. n_hidden = 2 # number of hidden size, h in paper,隐层个数
  34. m = 2 # embedding size, m in paper ,词向量的维度 m =2
  35. sentences = ["i like dog", "i love coffee", "i hate milk"] ###训练数据
  36. word_list = " ".join(sentences).split() ### 按照空格分词,统计 sentences的分词的个数
  37. word_list = list(set(word_list)) ### 去重 统计词典个数
  38. word_dict = {w: i for i, w in enumerate(word_list)} ### {word : index ,词典}
  39. number_dict = {i: w for i, w in enumerate(word_list)} ### {index : word ,词典}
  40. n_class = len(word_dict) # number of Vocabulary 词典的个数,也是softmax 最终分类的个数
  41. # pdb.set_trace()
  42. model = NNLM()
  43. ### 损失函数定义
  44. criterion = nn.CrossEntropyLoss() ### 交叉熵损失函数
  45. ### 采用 Adam 优化算法 学习率定义为 0.001
  46. optimizer = optim.Adam(model.parameters(), lr=0.001)
  47. input_batch, target_batch = make_batch() ###构建输入数据和 target label
  48. input_batch = torch.LongTensor(input_batch) ### 模型输入 tensor 形式
  49. target_batch = torch.LongTensor(target_batch)
  50. # Training 迭代 5000次
  51. for epoch in range(5000):
  52. optimizer.zero_grad() ###梯度归零
  53. output = model(input_batch)
  54. # output : [batch_size, n_class], target_batch : [batch_size]
  55. loss = criterion(output, target_batch)
  56. if (epoch + 1) % 1000 == 0:
  57. print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.6f}'.format(loss))
  58. loss.backward() ### 反向传播计算 每个参数的梯度值
  59. optimizer.step() ### 每一个参数的梯度值更新
  60. # Predict
  61. predict = model(input_batch).data.max(1, keepdim=True)[1]
  62. # Test
  63. print([sen.split()[:2] for sen in sentences], '->', [number_dict[n.item()] for n in predict.squeeze()])

Reference:

https://zhuanlan.zhihu.com/p/28080127

Statistical language model 统计语言模型_a635661820的博客-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/734611
推荐阅读
相关标签
  

闽ICP备14008679号