手把手教你实现基于LSTM的情感分析(LSTM-based Sentiment) Classification
首先推荐一个Jupyter环境,是由Google提供的colab(https://colab.research.google.com/),有免费的GPU可以使用
第一次使用需要在实验环境中下载相关的python库
!pip install torch
!pip install torchtext
!python -m spacy download en
我们初步的设想是,首先将一个句子输入到LSTM,这个句子有多少个单词,就有多少个输出,然后将所有输出通过一个Linear Layer,这个Linear Layer的out_size是1,起到Binary Classification的作用
然后对于每个输入,我们需要先要进行Embedding,把每个单词转换成固定长度的vector,再送到LSTM里面去,假设每个单词我们都用一个长度为100的vector来表示,每句话有seq个单词(动态的,每句话的seq长度不一定一样),那么输入的shape就是[seq, b, 100]
。最终通过Linear Layer输出的
的shape就是
[b]
我们使用的数据集是torchtext库里面的IMDB数据集
import torch
from torch import nn, optim
from torchtext import data, datasetsprint("GPU:",torch.cuda.is_available())
torch.manual_seed(123)TEXT = data.Field(tokenize='spacy')
LABEL = data.LabelField(dtype=torch.float)
train_data, test_data = datasets.IMDB.splits(TEXT, LABEL)print('len of train data:', len(train_data))
print('len of test data:', len(test_data))print(train_data.examples[15].text)
print(train_data.examples[15].label)# word2vec, glove
TEXT.build_vocab(train_data, max_size=10000, vectors='glove.6B.100d')
LABEL.build_vocab(train_data)batch_size = 30
device = torch.device('cuda')
train_iterator, test_iterator = data.BucketIterator.splits((train_data, test_data),batch_size = batch_size,device = device
)
上面这些代码里面有些参数不懂不要紧,因为只是加载数据集而已,不是很重要。如果想要了解torchtext,可以看这篇文章(https://blog.csdn.net/u012436149/article/details/79310176)
接下来比较重要,定义网络结构
class RNN(nn.Module):def __init__(self, vocab_size, embedding_dim, hidden_dim):super(RNN, self).__init__()# [0-10001] => [100]self.embedding = nn.Embedding(vocab_size, embedding_dim)# [100] => [200]self.rnn = nn.LSTM(embedding_dim, hidden_dim, num_layers=2,bidirectional=True, dropout=0.5)# [256*2] => [1]self.fc = nn.Linear(hidden_dim*2, 1)self.dropout = nn.Dropout(0.5)def forward(self, x):# [seq, b, 1] => [seq, b, 100]embedding = self.dropout(self.embedding(x))# output: [seq, b, hid_dim*2]# hidden/h: [num_layers*2, b, hid_dim]# cell/c: [num_layers*2, b, hid_dim]output, (hidden, cell) = self.rnn(embedding)# [num_layers*2, b, hid_dim] => 2 of [b, hid_dim] => [b, hid_dim*2]hidden = torch.cat([hidden[-2], hidden[-1]], dim=1)# [b, hid_dim*2] => [b, 1]hidden = self.dropout(hidden)out = self.fc(hidden)return out
nn.embedding(m, n)
其中m表示单词的总数目,n表示词嵌入的维度(每个单词编码为长度为n的vector)
然后就是LSTM本身,这里就不做过多解释了,参数介绍可以查看我的这篇文章(https://wmathor.com/index.php/archives/1400/),其中有一点之前的文章中没有提到,就是这个bidirectional
参数,设置为True表示这个LSTM是双向的,很好理解,之前学过的RNN都是单向的,很有局限,例如下面这句话
我今天不舒服,我打算___一天
如果是单向RNN,这个空肯定会填"医院"或者"睡觉"之类的,但是如果是双向的,它就能知道后面跟着"一天",这时"请假","休息"之类的被选择的概率就会更大
最后的Fully Connected Layer可以理解为把所有输出的信息做个综合,转化为一个一维的tensor
rnn = RNN(len(TEXT.vocab), 100, 256)
pretrained_embedding = TEXT.vocab.vectors
print('pretrained_embedding:', pretrained_embedding.shape)
rnn.embedding.weight.data.copy_(pretrained_embedding)
print('embedding layer inited.')
Embedding层如果不初始化,生成的权值是随机的,所以必须要初始化,这个权值是通过下载Glove编码方式得到的,下载得到的其实就是个weight,直接覆盖掉embedding里面的weight,通过rnn.embedding.weight.data.copy_(pretrained_embedding)
的方式
然后我们看一下怎么Train这个网络
import numpy as npdef binary_acc(preds, y):"""get accuracy"""preds = torch.round(torch.sigmoid(preds))correct = torch.eq(preds, y).float()acc = correct.sum() / len(correct)return accdef train(rnn, iterator, optimizer, criteon):avg_acc = []rnn.train()for i, batch in enumerate(iterator):# [seq, b] => [b, 1] => [b]pred = rnn(batch.text).squeeze()loss = criteon(pred, batch.label)acc = binary_acc(pred, batch.label).item()avg_acc.append(acc)optimizer.zero_grad()loss.backward()optimizer.step()if i%10 == 0:print(i, acc)avg_acc = np.array(avg_acc).mean()print('avg acc:', avg_acc)
Train其实很简单了,就是把text丢进去,然后返回一个shape为[b, 1]
的output,利用squeeze()
函数,去掉其中维数为1的维度,shape变成[b]
,方便与label进行比较
同样的道理,Test也非常简单
def eval(rnn, iterator, criteon):avg_acc = []rnn.eval()with torch.no_grad():for batch in iterator:# [b, 1] => [b]pred = rnn(batch.text).squeeze()loss = criteon(pred, batch.label)acc = binary_acc(pred, batch.label).item()avg_acc.append(acc)avg_acc = np.array(avg_acc).mean()print(">>test:", avg_acc)
最后定义一下loss和optimizer
optimizer = optim.Adam(rnn.parameters(), lr=1e-3)
criteon = nn.BCEWithLogitsLoss().to(device)
rnn.to(device)
其中BCEWithLogitsLoss()
主要用于二分类问题。nn.BCELoss()
是针对二分类用的交叉熵,这俩都是用于二分类,有什么区别呢?区别在于BCEWithLogitsLoss
将Sigmoid层和BCELoss合并在了一起。如果还是觉得不理解,可以看下这篇博客(https://blog.csdn.net/qq_22210253/article/details/85222093)
ipynb版本代码(https://github.com/wmathor/file/blob/master/LSTM.ipynb)
py版本代码(https://github.com/wmathor/file/blob/master/LSTM.py)
往期精彩回顾适合初学者入门人工智能的路线及资料下载机器学习在线手册深度学习在线手册AI基础下载(pdf更新到25集)备注:加入本站微信群或者qq群,请回复“加群”获取一折本站知识星球优惠券,请回复“知识星球”喜欢文章,点个在看
手把手教你实现基于LSTM的情感分析(LSTM-based Sentiment) Classification相关推荐
- 手把手教你:基于LSTM的股票预测系统
系列文章 第七章.手把手教你:基于深度残差网络(ResNet)的水果分类识别系统 第六章.手把手教你:人脸识别的视频打码 第五章.手把手教你:基于深度学习的滚动轴承故障诊断 目录 系列文章 一.项目简 ...
- 手把手教你:基于TensorFlow的语音识别系统
系列文章 第十章.手把手教你:基于Django的用户画像可视化系统 第九章.手把手教你:个人信贷违约预测模型 第八章.手把手教你:基于LSTM的股票预测系统 目录 系列文章 一.项目简介 二.语音数据 ...
- 手把手教你:基于Django的用户画像可视化系统
系列文章 第九章.手把手教你:个人信贷违约预测模型 第八章.手把手教你:基于LSTM的股票预测系统 第七章.手把手教你:基于深度残差网络(ResNet)的水果分类识别系统 目录 系列文章 一.项目简介 ...
- 论文浅尝 | 嵌入常识知识的注意力 LSTM 模型用于特定目标的基于侧面的情感分析...
MaY, Peng H, Cambria E. Targeted aspect-based sentiment analysis via embedding commonsense knowledge ...
- 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接
转自即时通讯网:http://www.52im.net/ 本文原作者:"水晶虾饺",原文由"玉刚说"写作平台提供写作赞助,原文版权归"玉刚说" ...
- 手把手教你:基于深度残差网络(ResNet)的水果分类识别系统
系列文章 手把手教你:图像识别的垃圾分类系统 手把手教你:人脸识别考勤系统 手把手教你:基于粒子群优化算法(PSO)优化卷积神经网络(CNN)的文本分类 目录 系列文章 一.项目简介 二.水果分类结果 ...
- garch预测 python_【2019年度合辑】手把手教你用Python做股票量化分析
引言 不知不觉,2019年已接近尾声,Python金融量化公众号也有一年零两个月.公众号自设立以来,专注于分享Python在金融量化领域的应用,发布了四十余篇原创文章,超过两万人关注.这一路走来,有过 ...
- 基于Python实现情感分析实验
资源下载地址:https://download.csdn.net/download/sheziqiong/86764011 资源下载地址:https://download.csdn.net/downl ...
- 论文浅尝 - ICLR2020 | 知道什么、如何以及为什么:基于方面的情感分析的近乎完整的解决方案...
论文笔记整理:余海阳,浙江大学硕士,研究方向为知识图谱.自然语言处理. 链接:https://arxiv.org/abs/1911.01616 动机 基于目标的情感分析或基于方面的情感分析(ABSA) ...
- [NLP]基于IMDB影评情感分析之BERT实战-测试集上92.24%
系列文章目录 深度学习NLP(一)之Attention Model; 深度学习NLP(二)之Self-attention, Muti-attention和Transformer; 深度学习NLP(三) ...
最新文章
- 解决LaTex中插入Visio画图有多余边框的问题
- SQL server注入
- 提示以下的错误信息:“未能在设计视图中打开, 块中,以不同方式将值括起来 ”...
- QT5开发的程序打包发布
- c++用什么软件编程_学习编程用什么做笔记比较好?
- [概率论与数理统计] 常用定义与公式
- 【工匠大道】博客园小技巧
- 毕向东_JavaScript视频教程_javascript编程
- 希捷DM002-500G固件问题解决方法
- libcef(二)基于VS2019编写CEF简单样例
- uni-app小程序实现图片上传和压缩
- 方差分析 交互效应和无交互效应
- 使用Hexo + Gitee Pages搭建个人博客
- 使用FFMpeg从mp4中提取mp3
- 2012美国大选献金项目数据分析(有史以来最全面)
- 新人如何通过小红书赚第一桶金?
- mysql aix版本查看_AIX 查看aio状态
- 基于GoLang的MMO游戏服务器(二)
- 梦行扫码付(收银台条码支付 微信钱包条码支付 支付宝二维码支付 手机APP钱包支付 PHP扫码支付 )
- Readme文件写法
热门文章
- SSM(Spring4.x.x+SpringMVC4.x.x+Mybatis3.4.x)框架整合
- CentOS中安装mysql
- maven下载spring
- CMMI for Development读书笔记-目录
- 游戏中的数学与物理学 第二版_在游戏中启蒙幼儿的数学能力和逻辑思维能力...
- python获取月份字符串_python 正则表达式获取字符串中所有的日期和时间
- 随机对照试验设计的原理
- 超实用资源,SCI写作到投稿全阶段模板
- C语言 | 基于51单片机实现MPU6050的卡尔曼滤波算法(代码类2)
- jquery在thymeleaf循环的按钮元素中不能直接用id选择器