nlp-tutorial代码注释1-1,语言模型、n-gram简介
系列语:本系列是nlp-tutorial代码注释系列,github上原项目地址为:nlp-tutorial,本系列每一篇文章的大纲是相关知识点介绍 + 详细代码注释。
本文知识点介绍来自斯坦福大学CS224N课程lecture6语言模型部分
语言模型
语言模型可以预测一个序列接下来会出现什么词。即给定一个单词序列,语言模型计算出下一个单词是词汇表中各个词的概率分布。
还有一种理解是语言模型可以计算一个句子出现的概率,计算公式如下(条件概率):
n-gram语言模型:
含义:通过前(n-1)个词去预测某个单词。
n-gram有一个基本的假设:假设某个词的出现仅取决于它前面的n-1个单词。根据条件概率公式,某个词的出现概率计算公式为:
计算上图n-gram和(n-1)-gram的比例是通过计算他们在大型语料库中出现的次数的比例:
举个例子:As the proctor started the clock, the students open their ___. 预测这句话空格处的词,假设这里是一个4-gram的语言模型。那么就是通过前三个词:students open their去预测下一个词,语料库中students open their books出现的次数最多,故4-gram模型预测的空格处的词就应该是books。
然而回顾整个句子,前文出现了proctor,所以这个空是exams的概率应该最大,而4-gram模型只考虑前三个词,忽略了前面的词proctor,故导致预测错误。n-gram语言模型的一个缺点:每次预测时只考虑前n-1个词,忽略了再之前的上下文。
sparsity problem:
n-gram模型对于下图的计算式会出现两个问题:
1、分子为0,即语料库中没有相应的n元组,一个解决方法是在一开始给每一个单词增加很小的次数,这个方法叫smoothing;
2、分母为0,即语料库中没有相应的n-1元组,一个解决方法是退化成n-1-gram,即考虑所预测单词前n-2个单词出现的次数。
更糟的是,对于上一个问题,即每次只考虑前n-1个词而忽略了更之前的上下文,可能有个解决方法是增大N。而增大N会导致更严重的sparsity problem。通常N不超过5。
storage problem:
增加N会增加模型大小。
语言模型可以用作文本生成,以下是一个3-gram的语言模型生成的一段文本。但显然,这段文本非常的不连贯且奇怪,因为它的每个词仅仅是依据前两个词生成的,增大N可以改善这个问题,而增大N又会带来很多副作用:sparsity、storage problem。
利用n-gram训练词向量的代码详细注释:
(源代码为github上nlp-tutorial项目,项目地址:nlp-tutorial)
import numpy as np #引入numpy库
import torch #引入torch
import torch.nn as nn #torch.nn是torch的神经网络库
import torch.optim as optim #torch.optim是优化库,包含很多优化函数
from torch.autograd import Variable #现在的pytorch版本variable已经回归tensor了,直接用tensor即可dtype = torch.FloatTensorsentences = [ "i like dog", "i love coffee", "i hate milk"] #训练集word_list = " ".join(sentences).split() #先用" ".join(),以空格为分隔,将sentences中的句子连接起来,再用split()以空格为分割点,将每个词分出来
word_list = list(set(word_list)) #先用set合并重复的单词,再用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# NNLM Parameter
n_step = 2 # n-1 in paper #步长,即根据多少个词来预测下一个词,这里是根据前两个词预测第三个词
n_hidden = 2 # h in paper #隐藏层神经元个数
m = 2 # m in paper #词向量维度def make_batch(sentences): #作用是将训练集中的句子的最后一个词和前面的词分开input_batch = [] #空列表,用来存放输入target_batch = [] #存放一次输入对应的输出for sen in sentences: #对于训练集中的每个句子word = sen.split() #先将句子中每个单词按空格分开input = [word_dict[n] for n in word[:-1]] #[:-1]切片,即输入是一直到最后一个词,最后一个词不要target = word_dict[word[-1]] #target是最后一个词input_batch.append(input) #将分离出来的input添加到输入列表target_batch.append(target) #将分离出来的target添加到标记列表return input_batch, target_batch #返回输入和标记列表# Model
class NNLM(nn.Module):def __init__(self):super(NNLM, self).__init__()#文章中计算式为y = b + Wx + U * tanh(d + Hx),这里设置各个参数self.C = nn.Embedding(n_class, m) #C是词向量矩阵,行数是单词的数量,列数是词向量的维度#H是输入层到隐层的权重矩阵,维数是(输入的个数 * 隐层单元个数),输入的个数是(输入的单词个数 * 词向量维数),即n_step * mself.H = nn.Parameter(torch.randn(n_step * m, n_hidden).type(dtype))#W是一个直连输入层和输出层的权重矩阵,维数是(输入的个数 * 输出层单元个数)self.W = nn.Parameter(torch.randn(n_step * m, n_class).type(dtype))#d是输入层到隐层的偏置常数,维数是(n_hidden * 1)self.d = nn.Parameter(torch.randn(n_hidden).type(dtype))#U是隐层到输出层的权重矩阵,维数是(隐层单元个数 * 输出层单元个数),要输出词典中每一个单词是下一个词的概率,输出的个数应该是单词的个数self.U = nn.Parameter(torch.randn(n_hidden, n_class).type(dtype))#b是隐层到输出层的偏置常数,维数是(输出层单元个数 * 1)self.b = nn.Parameter(torch.randn(n_class).type(dtype))def forward(self, X): #前向传播,计算公式y = b + Wx + U * tanh(d + Hx)X = self.C(X) #输入的X是单词的序号,序号X对应的词向量是词向量矩阵C的第X行,取出此词向量X = X.view(-1, n_step * m) #reshape矩阵Xtanh = torch.tanh(self.d + torch.mm(X, self.H)) #torch.mm是矩阵相乘output = self.b + torch.mm(X, self.W) + torch.mm(tanh, self.U) #根据上述公式计算输出return outputmodel = NNLM()
criterion = nn.CrossEntropyLoss() #损失函数为交叉熵损失函数
optimizer = optim.Adam(model.parameters(), lr=0.001) #使用Adam算法进行优化
input_batch, target_batch = make_batch(sentences) #使用make_batch从训练集中获得输入和对应的标记input_batch = Variable(torch.LongTensor(input_batch)) #这两行是将输入变成variable,但现在的torch版本直接用tensor即可
target_batch = Variable(torch.LongTensor(target_batch))# Training
for epoch in range(5000): #训练5000次optimizer.zero_grad() #每次训练前清除梯度缓存output = model(input_batch) #对模型输入input_batch,获得输出output# output : [batch_size, n_class], target_batch : [batch_size] (LongTensor, not one-hot)loss = criterion(output, target_batch) #使用损失函数计算loss,损失函数的输入为模型的输出output和标记targetif (epoch + 1)%1000 == 0: #每优化1000次打印一次查看cost的变化print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.6f}'.format(loss))loss.backward() #反向传播、自动求导optimizer.step() #优化、更新参数# Predict
predict = model(input_batch).data.max(1, keepdim=True)[1] #用.max[1]挑出输出中最大的那一个# Test
print([sen.split()[:2] for sen in sentences], '->', [number_dict[n.item()] for n in predict.squeeze()])
nlp-tutorial代码注释1-1,语言模型、n-gram简介相关推荐
- nlp-tutorial代码注释笔记
系列语:本系列是nlp-tutorial代码注释系列,github上原项目地址为:nlp-tutorial,本系列每一篇文章的大纲是相关知识点介绍 + 详细代码注释. 传送门: nlp-tutoria ...
- nlp-tutorial代码注释3-3,双向RNN简介
系列语:本系列是nlp-tutorial代码注释系列,github上原项目地址为:nlp-tutorial,本系列每一篇文章的大纲是相关知识点介绍 + 详细代码注释. 前言:3-1节介绍了普通的RNN ...
- tensorflow笔记:流程,概念和简单代码注释
tensorflow是google在2015年开源的深度学习框架,可以很方便的检验算法效果.这两天看了看官方的tutorial,极客学院的文档,以及综合tensorflow的源码,把自己的心得整理了一 ...
- DeepLearning tutorial(4)CNN卷积神经网络原理简介+代码详解
FROM: http://blog.csdn.net/u012162613/article/details/43225445 DeepLearning tutorial(4)CNN卷积神经网络原理简介 ...
- nlp-tutorial代码注释3-2,LSTM简介
系列语:本系列是nlp-tutorial代码注释系列,github上原项目地址为:nlp-tutorial,本系列每一篇文章的大纲是相关知识点介绍 + 详细代码注释. 前言:上一节笔记是RNN相关,链 ...
- nlp-tutorial代码注释3-1,RNN简介
系列语:本系列是nlp-tutorial代码注释系列,github上原项目地址为:nlp-tutorial,本系列每一篇文章的大纲是相关知识点介绍 + 详细代码注释. 前言:针对之前n-gram等具有 ...
- 一步步读懂Pytorch Chatbot Tutorial代码(二) - 数据处理
文章目录 自述 代码出处 目录 代码 Create formatted data file (为了方便理解,把代码的顺序略微改一下, 此章节略长.) 1. `loadLines` 将文件的每一行拆分为 ...
- GraphDTA论文阅读小白笔记(附代码注释和复现流程)
目录 摘要 背景 数据和方法 GraphDTA概述 药物表征 蛋白表征 分子图的深度学习 GCN GAT GIN GAT-GCN 基准 模型解释 结果讨论 图模型的表现超过了其它模型 图模型发现已知药 ...
- ns3中first.cc~fourth.cc代码注释
参考博客: ubuntu 18.04安装NS-3教程(详细安装过程) ns-3脚本初识--点对点有线网络:first脚本 ns-3中的数据跟踪与采集--Tracing系统综述及fourth脚本 --- ...
最新文章
- unity 开启外部摄像头
- 24-移动端app数据爬取
- P2498 [SDOI2012]拯救小云公主
- SharePoint 跨域还原网站一则
- Clojure 的 Enlive 库尝试
- 电子元器件筛选公司/费用-电子元器件筛选方法与技术要求
- PyTorch 激励函数
- 邮件营销如何“爆增”潜在客户?
- Python标准库32个模块的整理
- vbs编程中 on error resume next的意思
- 四旋翼无人机PID调节(无数次实验总结经验和理论支持)
- 计算机如何设定远程,电脑远程控制功能怎么设置
- think php5 离线手册,thinkphp5.0离线手册下载
- 怎么改图片大小kb像素不变?一键快速修改jpg图片大小?
- java IO流之一 IO流介绍
- 如何测试一支笔之我见
- 自由曲面光学元件的OAM测量
- IOS 版 Opera 已不再更新
- c语言计算器开题报告,基于单片机的简易电子计算器设计开题报告.doc
- JavaWeb网上书城项目总结(初步1.0)
热门文章
- PHP 中 new static 和 new self 的区别
- algorithm design manual: 8-19
- cross apply
- 团队作业4——第一次项目冲刺(Alpha版本)2017.4.23
- cmd下运行java文件时,找不到或无法加载主类的解决方法
- Andriod Studio 使用心得,持续更新中
- 转:POJ先做完这50题再说
- [HttpPost] vs [AcceptVerbs(HttpVerbs.Post)]
- MyEclipse下开发Web Service(转)
- Redis入门之Redis安装、配置及常用指令