PyTorch快速入门教程八(使用word embedding做自然语言处理的词语预测)
2017-07-02 00:00
841 查看
摘要: 前面一篇文章中,我们简单的介绍了自然语言处理中最简单的词向量 word embedding,这一篇文章我们将介绍如何使用word embedding做自然语言处理的词语预测。
知道了我们想要做的事情之后,我们就可以引出 N-Gram 模型了。先给出其公式
这就是一个条件概率,也就是我们给定想要预测的单词的前面几个单词,然后最大化我们想要预测的这个单词的概率。
接下来我们需要将数据整理好,也就是我们需要将单词三个分组,每个组前两个作为传入的数据,而最后一个作为预测的结果。
接下来需要给每个单词编码,也就是用数字来表示每个单词,这样才能够传入
这个模型需要传入的参数是所有的单词数,预测单词需要的前面单词数,即
然后在向前传播中,首先传入单词得到词向量,比如在该模型中传入两个词,得到的词向量是(2, 100),然后将词向量展开成(1, 200),然后传入一个线性模型,经过relu激活函数再传入一个线性模型,输出的维数是单词总数,可以看成一个分类问题,要最大化预测单词的概率,最后经过一个log softmax激活函数。
然后定义好模型、loss以及优化函数。
接着进行训练,一共跑100个epoch,在每个epoch中,word代表着预测单词的前面两个词,label表示要预测的词,然后记住需要将他们转换成Variable,接着进入网络得到结果,然后通过loss函数得到loss进行反向传播,更新参数。
训练完100个epoch后的结果如下
我们发现loss已经降到了0.37,也可以通过预测来检测我们的模型是否有效
得到的如下结果
可以发现我们能够准确地预测这个单词。
以上我们介绍了如何通过最简单的单边
在这里,我整理发布了Pytorch中文文档,方便大家查询使用,同时也准备了中文论坛,欢迎大家学习交流!
Pytorch中文文档
Pytorch中文论坛
Pytorch中文文档已经发布,完美翻译,更加方便大家浏览:
Pytorch中文网:https://ptorch.com/
Pytorch中文文档:https://ptorch.com/docs/1/
N-Gram language Modeling
首先我们介绍一下 N-Gram 模型。在一篇文章中,每一句话有很多单词组成,而对于一句话,这些单词的组成顺序也是很重要的,我们想要知道在一篇文章中我们是否可以给出几个词然后预测这些词后面的一个单词,比如’I lived in France for 10 years, I can speak _ .’那么我们想要做的就是预测最后这个词是French。知道了我们想要做的事情之后,我们就可以引出 N-Gram 模型了。先给出其公式
这就是一个条件概率,也就是我们给定想要预测的单词的前面几个单词,然后最大化我们想要预测的这个单词的概率。
数据预处理
首先我们给出了一段文章作为我们的训练集CONTEXT_SIZE = 2 EMBEDDING_DIM = 10 # We will use Shakespeare Sonnet 2 test_sentence = """When forty winters shall besiege thy brow, And dig deep trenches in thy beauty's field, Thy youth's proud livery so gazed on now, Will be a totter'd weed of small worth held: Then being asked, where all thy beauty lies, Where all the treasure of thy lusty days; To say, within thine own deep sunken eyes, Were an all-eating shame, and thriftless praise. How much more praise deserv'd thy beauty's use, If thou couldst answer 'This fair child of mine Shall sum my count, and make my old excuse,' Proving his beauty by succession thine! This were to be new made when thou art old, And see thy blood warm when thou feel'st it cold.""".split()
CONTEXT_SIZE表示我们想由前面的几个单词来预测这个单词,这里设置为2,就是说我们希望通过这个单词的前两个单词来预测这一个单词。
EMBEDDING_DIM表示
word embedding的维数,上一篇已经介绍过了。
trigram = [((test_sentence[i], test_sentence[i+1]), test_sentence[i+2]) for i in range(len(test_sentence)-2)]
接下来我们需要将数据整理好,也就是我们需要将单词三个分组,每个组前两个作为传入的数据,而最后一个作为预测的结果。
vocb = set(test_sentence) # 通过set将重复的单词去掉 word_to_idx = {word: i for i, word in enumerate(vocb)} idx_to_word = {word_to_idx[word]: word for word in word_to_idx}
接下来需要给每个单词编码,也就是用数字来表示每个单词,这样才能够传入
word embeding得到词向量。
定义模型
class NgramModel(nn.Module): def __init__(self, vocb_size, context_size, n_dim): super(NgramModel, self).__init__() self.n_word = vocb_size self.embedding = nn.Embedding(self.n_word, n_dim) self.linear1 = nn.Linear(context_size*n_dim, 128) self.linear2 = nn.Linear(128, self.n_word) def forward(self, x): emb = self.embedding(x) emb = emb.view(1, -1) out = self.linear1(emb) out = F.relu(out) out = self.linear2(out) log_prob = F.log_softmax(out) return log_prob ngrammodel = NgramModel(len(word_to_idx), CONTEXT_SIZE, 100) criterion = nn.NLLLoss() optimizer = optim.SGD(ngrammodel.parameters(), lr=1e-3)
这个模型需要传入的参数是所有的单词数,预测单词需要的前面单词数,即
CONTEXT_SIZE,词向量的维度。
然后在向前传播中,首先传入单词得到词向量,比如在该模型中传入两个词,得到的词向量是(2, 100),然后将词向量展开成(1, 200),然后传入一个线性模型,经过relu激活函数再传入一个线性模型,输出的维数是单词总数,可以看成一个分类问题,要最大化预测单词的概率,最后经过一个log softmax激活函数。
然后定义好模型、loss以及优化函数。
训练
for epoch in range(100): print('epoch: {}'.format(epoch+1)) print('*'*10) running_loss = 0 for data in trigram: word, label = data word = Variable(torch.LongTensor([word_to_idx[i] for i in word])) label = Variable(torch.LongTensor([word_to_idx[label]])) # forward out = ngrammodel(word) loss = criterion(out, label) running_loss += loss.data[0] # backward optimizer.zero_grad() loss.backward() optimizer.step() print('Loss: {:.6f}'.format(running_loss / len(word_to_idx)))
接着进行训练,一共跑100个epoch,在每个epoch中,word代表着预测单词的前面两个词,label表示要预测的词,然后记住需要将他们转换成Variable,接着进入网络得到结果,然后通过loss函数得到loss进行反向传播,更新参数。
训练完100个epoch后的结果如下
我们发现loss已经降到了0.37,也可以通过预测来检测我们的模型是否有效
word, label = trigram[3] word = Variable(torch.LongTensor([word_to_idx[i] for i in word])) out = ngrammodel(word) _, predict_label = torch.max(out, 1) predict_word = idx_to_word[predict_label.data[0][0]] print('real word is {}, predict word is {}'.format(label, predict_word))
得到的如下结果
可以发现我们能够准确地预测这个单词。
以上我们介绍了如何通过最简单的单边
N-Gram模型预测单词,还有一种复杂一点的
N-Gram模型通过双边的单词来预测中间的单词,这种模型有个专门的名字,叫
Continuous Bag-of-Words model (CBOW),具体的内容差别不大,就不再细讲了,代码的实现放在了github上面。
在这里,我整理发布了Pytorch中文文档,方便大家查询使用,同时也准备了中文论坛,欢迎大家学习交流!
Pytorch中文文档
Pytorch中文论坛
Pytorch中文文档已经发布,完美翻译,更加方便大家浏览:
Pytorch中文网:https://ptorch.com/
Pytorch中文文档:https://ptorch.com/docs/1/
相关文章推荐
- PyTorch快速入门教程九(使用LSTM来做判别每个词的词性)
- PyTorch快速入门教程九(使用LSTM来做判别每个词的词性)
- PyTorch快速入门教程六(使用LSTM做图片分类)
- PyTorch快速入门教程七(pytorch下RNN如何做自然语言处理)
- PyTorch快速入门教程四(cnn:卷积神经网络 )
- PyTorch快速入门教程五(rnn)
- PyTorch快速入门教程一(环境配置)
- PyTorch快速入门教程二(线性回归以及logistic回归)
- PyTorch快速入门教程四(cnn:卷积神经网络 )
- PyTorch快速入门教程三(神经网络)
- PyTorch快速入门教程五(rnn)
- Spring MVC 教程,快速入门,深入分析――如何使用拦截器
- JUnit4使用教程-快速入门
- webAppbuilder微件使用教程1 快速入门
- 1 pytorch60分钟入门教程
- Spring快速入门教程 - 1 - 使用 Maven 创建工程 - 修改0次
- Thrust快速入门教程(二)——Vector的使用
- JUnit4使用教程-快速入门
- JUnit4使用教程-快速入门
- pytorch教程[2] Tensor的使用