【nlp学习】ch1.A Neural Probabilistic Language Model论文笔记/代码

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 摘要
  • 一、Introduction
  • 二、A Neural Model
  • 代码


摘要

传统的统计语言模型有一些缺点:

1.由于维度灾难(特别是离散变量),在高维下,数据的稀缺性导致统计语言模型存在很多为0的条件概率,传统的统计语言模型也花费大量的精力来处理这个,包括平滑,插值,回退等方法

2.语言模型的参数个数随着阶数呈指数增长,所以一般这个模型的阶数不会很高,这样n-gram无法建立长远的关系

3.n-gram无法建模出多个相似词的关系,比如在训练集中有: the cat is walking in the bedroom,但是用n-gram预测时,遇到:the dog was running in a room这个句子,并不会因为两个句子相似就让该句子的概率变高

这篇NNLM使训练得到的模型比传统的统计语言模型使用n-gram能建模更远的关系,并且考虑到了词与词之间的相似性,一些相似的词获得了自然的平滑。前者是因为神经网络的结果使得,后者是因为使用了词向量。
————————————————
原文链接:https://blog.csdn.net/hx14301009/article/details/80345449


一、Introduction

语言的统计模型可以表示为给定所有先前单词的下一个单词的条件概率。

本质上,N-gram对词的表示是one-hot的离散表示,存在问题:

  1. 参数空间随着N成指数增长,当词典数量较大时存在维度灾难问题;
  2. 无法理解词与词之间的内在联系,无法建模出多个相似词的关系。

词向量的引入使得n-gram的离散空间变成了连续空间,并且两个相似的词之间他们的词向量也相似,所以当训练完毕后,一个句子和其他相似的句子都获得了概率。引入词向量的好处:

  1. one-hot向量维度大小与词典成正比,稠密向量大小是固定值(50~300);
  2. 稠密向量各维度值是实数,不限于0和1,可以表示连续空间,可以通过计算距离度量词与词之间的相似度。类似的思想还有IR中的向量空间模型(VSM)。

二、A Neural Model

模型架构图
【nlp学习】ch1.A Neural Probabilistic Language Model论文笔记/代码_第1张图片
图中最下方的Wt-1 —Wt-n+1就是前n-1个词。现在需要根据这已知的n-1个词来预测下一个词Wt。

初始化:

  1. 对所有的文档提取单词制作一个词汇表,每个单词有一个唯一的索引,即词汇表每行代表一个单词的embedding
  2. 模型参数的初始化:神经网络的连接权重初始化以及词汇表的初始化

【nlp学习】ch1.A Neural Probabilistic Language Model论文笔记/代码_第2张图片
前向传播部分:

  1. 从文档中提取模型的输入,输入为3个单词的索引
  2. 模型根据输入的3个单词的索引从词汇表中拿出对应的embedding表示得到每个单词的词向量。假如我们打算将每个单词转换为1个50维的向量,此时3个单词就转换为3个向量,每个都是50维
  3. 将3个50维向量串在一起,变为一个150维的向量作为网络的输入层,传送给隐层
  4. 对于隐层的每个神经元,150维输入乘以与每个神经元链接的权重,求和后输入给tanh激活函数
  5. 激活函数的输出作为输出层(softmax)的输入,假设隐层的神经元数量为300个,则输出层的输入就是一个300维向量
  6. softmax层的单元数量为词汇表的单词数量|V|,对每个单元,输入的300维乘以与输出层连接的权重后求和,并计算各个单元输出的概率作为下一个单词是第i个单词的概率。在这里例子中为300维向量,则对第i个softmax单元,权重为1个300维向量,转置后与输入相乘
  7. 每一个softmax‘单元的输出为一个概率值,指示在词汇表中第i个单词为第四个单词的概率
  8. 整个softmax的输出为一个长度为词汇表长度的概率分布,其和为1

反向部分:

  1. 计算softmax的代价函数,用softmax的输出向量与真实的第四个单词的1-hot向量做点乘再取-log
    使用BP,一层一层求出网络连接权重的偏导数,并使用梯度下降更新
  2. 对词向量层也需要求偏导数使用梯度下降来更新词向量表,整个过程反复迭代,词汇表就得到了不断的更新

注:实际使用中隐层和softmax的输入还要加上一个bias
————————————————
版权声明:本文为CSDN博主「hx14301009」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hx14301009/article/details/80345449
【nlp学习】ch1.A Neural Probabilistic Language Model论文笔记/代码_第3张图片
【nlp学习】ch1.A Neural Probabilistic Language Model论文笔记/代码_第4张图片

代码

# %%
# code by Tae Hwan Jung @graykode
import torch
import torch.nn as nn
import torch.optim as optim

def make_batch():
    input_batch = []
    target_batch = []

    for sen in sentences:
        word = sen.split() # space tokenizer分词
        input = [word_dict[n] for n in word[:-1]] # create (1~n-1) as input输入前n-1个词的键
        target = word_dict[word[-1]] # create (n) as target, We usually call this 'casual language model'下一个词的键

        input_batch.append(input)
        target_batch.append(target)

    return input_batch, target_batch

# Model
class NNLM(nn.Module):
    def __init__(self):
        super(NNLM, self).__init__()
        self.C = nn.Embedding(n_class, m)#词向量
        self.H = nn.Linear(n_step * m, n_hidden, bias=False)#输入》隐藏层的权重矩阵
        self.d = nn.Parameter(torch.ones(n_hidden))#输入》隐藏层的偏置
        self.U = nn.Linear(n_hidden, n_class, bias=False)#隐藏层》输出层的权重矩阵
        self.W = nn.Linear(n_step * m, n_class, bias=False)#输入》输出的直连
        self.b = nn.Parameter(torch.ones(n_class))#隐层》输出层的偏置

    def forward(self, X):
        X = self.C(X) # X : [batch_size, n_step, m]词向量
        X = X.view(-1, n_step * m) # [batch_size, n_step * m]将得到的词向量拼接
        tanh = torch.tanh(self.d + self.H(X)) # [batch_size, n_hidden]激活函数
        output = self.b + self.W(X) + self.U(tanh) # [batch_size, n_class]
        return output

if __name__ == '__main__':
    n_step = 2 # number of steps, n-1 in paper
    n_hidden = 2 # number of hidden size, h in paper
    m = 2 # embedding size, m in paper

    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)}
    n_class = len(word_dict)  # number of Vocabulary

    model = NNLM()

    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(), lr=0.001)

    input_batch, target_batch = make_batch()
    input_batch = torch.LongTensor(input_batch)
    target_batch = torch.LongTensor(target_batch)

    # Training
    for epoch in range(5000):
        optimizer.zero_grad()#模型中的参数的梯度设为0
        output = model(input_batch)

        # output : [batch_size, n_class], target_batch : [batch_size]
        loss = criterion(output, target_batch)
        if (epoch + 1) % 1000 == 0:
            print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.6f}'.format(loss))

        loss.backward()
        optimizer.step()

    # Predict
    predict = model(input_batch).data.max(1, keepdim=True)[1]

    # Test
    print([sen.split()[:2] for sen in sentences], '->', [number_dict[n.item()] for n in predict.squeeze()])

【nlp学习】ch1.A Neural Probabilistic Language Model论文笔记/代码_第5张图片

你可能感兴趣的:(自然语言处理,学习,语言模型)