BiLSTM的PyTorch应用

本文介绍一下如何使用BiLSTM(基于PyTorch)解决一个实际问题,实现给定一个长句子预测下一个单词

如果不了解LSTM的同学请先看我的这两篇文章LSTMPyTorch中的LSTM。下面直接开始代码讲解

导库

'''
  code by Tae Hwan Jung(Jeff Jung) @graykode, modify by wmathor
'''
import torch
import numpy as np
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as Data

dtype = torch.FloatTensor

准备数据

sentence = (
    'GitHub Actions makes it easy to automate all your software workflows '
    'from continuous integration and delivery to issue triage and more'
)

word2idx = {w: i for i, w in enumerate(list(set(sentence.split())))}
idx2word = {i: w for i, w in enumerate(list(set(sentence.split())))}
n_class = len(word2idx) # classification problem
max_len = len(sentence.split())
n_hidden = 5

我水平不佳,一开始看到这个 sentence 不懂这种写法是什么意思,如果你调用 type(sentence) 以及打印 sentence 就会知道,这其实就是个字符串,就是将上下两行字符串连接在一起的一个大字符串

数据预处理,构建dataset,定义dataloader

def make_data(sentence):
    input_batch = []
    target_batch = []

    words = sentence.split()
    for i in range(max_len - 1):
        input = [word2idx[n] for n in words[:(i + 1)]]
        input = input + [0] * (max_len - len(input))
        target = word2idx[words[i + 1]]
        input_batch.append(np.eye(n_class)[input])
        target_batch.append(target)

    return torch.Tensor(input_batch), torch.LongTensor(target_batch)

# input_batch: [max_len - 1, max_len, n_class]
input_batch, target_batch = make_data(sentence)
dataset = Data.TensorDataset(input_batch, target_batch)
loader = Data.DataLoader(dataset, 16, True)

这里面的循环还是有点复杂的,尤其是 inputinput_batch 里面存的东西,很难理解。所以下面我会详细解释

首先开始循环,input 的第一个赋值语句会将第一个词 Github 对应的索引存起来。input 的第二个赋值语句会将剩下的 max_len - len(input) 都用0去填充

第二次循环,input 的第一个赋值语句会将前两个词 GithubActions 对应的索引存起来。input 的第二个赋值语句会将剩下的 max_len - len(input) 都用0去填充

每次循环,inputtarget 中所存的索引转换成word如下图所示,因为我懒得去查看每个词对应的索引是什么,所以干脆直接写出存在其中的词

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0YDav3VD-1593652305962)(https://i.loli.net/2020/06/28/sYDJSiUTlRo1EN6.png#shadow)]

从上图可以看出,input 的长度永远保持 max_len(=21),并且循环了max_len-1次,所以最终 input_batch 的维度是[max_len - 1, max_len, n_class]

定义网络架构

class BiLSTM(nn.Module):
    def __init__(self):
        super(BiLSTM, self).__init__()
        self.lstm = nn.LSTM(input_size=n_class, hidden_size=n_hidden, bidirectional=True)
        # fc
        self.fc = nn.Linear(n_hidden * 2, n_class)

    def forward(self, X):
        # X: [batch_size, max_len, n_class]
        batch_size = X.shape[0]
        input = X.transpose(0, 1)  # input : [max_len, batch_size, n_class]

        hidden_state = torch.randn(1*2, batch_size, n_hidden)   # [num_layers(=1) * num_directions(=2), batch_size, n_hidden]
        cell_state = torch.randn(1*2, batch_size, n_hidden)     # [num_layers(=1) * num_directions(=2), batch_size, n_hidden]

        outputs, (_, _) = self.lstm(input, (hidden_state, cell_state))
        outputs = outputs[-1]  # [batch_size, n_hidden * 2]
        model = self.fc(outputs)  # model : [batch_size, n_class]
        return model

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

Bi-LSTM的网络结构图如下所示,其中Backward Layer意思不是"反向传播",而是将"句子反向输入"。具体流程就是,现有有由四个词构成的一句话"i like your friends"。常规单向LSTM的做法就是直接输入"i like your",然后预测出"friends",而双向LSTM会同时输入"i like your"和"your like i",然后将Forward Layer和Backward Layer的output进行concat(这样做可以理解为同时"汲取"正向和反向的信息),最后预测出"friends"

而正因为多了一个反向的输入,所以整个网络结构中很多隐藏层的输入和输出的某些维度会变为原来的两倍,具体如下图所示。对于双向LSTM来说,num_directions = 2

训练&测试

# Training
for epoch in range(10000):
    for x, y in loader:
      pred = model(x)
      loss = criterion(pred, y)
      if (epoch + 1) % 1000 == 0:
          print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.6f}'.format(loss))

      optimizer.zero_grad()
      loss.backward()
      optimizer.step()

# Pred
predict = model(input_batch).data.max(1, keepdim=True)[1]
print(sentence)
print([idx2word[n.item()] for n in predict.squeeze()])
<p> 本课程<span>隶属于自然语言处理</span>(NLP)<span>实战系列。自然语言处理</span>(NLP)<span>是数据科学里一个分支,它主要覆盖内容是:以一种智能与高效方式,对文本数据进行系统化分析、理解与信息提取过程。通过使用</span>NLP以及它组件,我们可以管理非常大块文本数据,或者执行大量自动化任务,并且解决各式各样问题,如自动摘要,机器翻译,命名实体识别,关系提取,情感分析,语音识别,以及主题分割等等。 </p> <p> <span>一般情况下一个初级</span>NLP工程师工资从15<span>万</span>-35<span>万不等,所以掌握</span>NLP技术,对于人工智能学习者来讲是非常关键一个环节。 </p> <p> <br /> </p> <p> <br /> </p> <p> <span style="background-color:#FFE500;">【超实用课程内容】</span> </p> <p> <span>课程从自然语言处理基本概念与基本任务出发,对目前主流自然语言处理应用进行全面细致讲解,</span><span>包括文本分类,文本摘要提取,文本相似度,文本情感分析,文本特征提取等,同时算法方面包括经典算法与深度学习算法结合,例如</span><span>LSTMBiLSTM等,并结合京东电商评论分类、豆瓣电影摘要提取、今日头条舆情挖掘、饿了么情感分析等过个案例,帮助大家熟悉自然语言处理工程师在工作中会接触到</span><span>常见应用实施基本实施流程,从</span><span>0-1入门变成自然语言处理研发工程师。</span> </p> <p style="color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <br /> </p> <p style="color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <span style="background-color:#FFE500;">【课程如何观看?】</span> </p> <p style="color:#3A4151;font-size:14px;background-color:#FFFFFF;"> PC端:<a href="https://edu.csdn.net/course/detail/26277"></a><a href="https://edu.csdn.net/course/detail/25649">https://edu.csdn.net/course/detail/25649</a> </p> <p style="color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 移动端:CSDN 学院APP(注意不是CSDN APP哦) </p> <p style="color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 本课程为录播课,课程2年有效观看时长,大家可以抓紧时间学习后一起讨论哦~ </p> <p> <br /> </p> <p> <strong><span style="background-color:#FFE500;">【学员专</span><span style="background-color:#FFE500;">享增值服务】</span></strong> </p> <p> 源码开放 </p> <p> 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化 </p> <p> 下载方式:电脑登录<a href="https://edu.csdn.net/course/detail/26277"></a><a href="https://edu.csdn.net/course/detail/25649">https://edu.csdn.net/course/detail/25649</a>,点击右下方课程资料、代码、课件等打包下载 </p> <p> <br /> </p> <p> 通过第二课时下载材料<span></span> </p> <p> <br /> </p> <p> <br /> </p>
相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值