基于pytorch的循环神经网络情感分析系统

news2024/11/16 12:48:18

任务目标

基于给定数据集,进行数据预处理,搭建以LSTM为基本单元的模型,以Adam优化器对模型进行训练,使用训练后的模型进行预测并计算预测分类的准确率。

数据简介

IMDB数据集是一个对电影评论标注为正向评论与负向评论的数据集,共有25000条文本数据作为训练集,25000条文本数据作为测试集。

已知数据集中数据格式如下

1、读取数据

在这里插入图片描述

2、数据预处理

首先,对于创建词汇表,记录每一个单词出现的频率,并由此将特征数据集转为特征向量。最后转化为tensor格式

在这里插入图片描述
由于数据量庞大,这里先用PCA将数据降维,这里选择降到20个维度

在这里插入图片描述
将特征数据集和标签进行匹配,并每两个数据作为一个批次,全部数据进行随机的打乱

在这里插入图片描述

模型构建

这里采用pytorch中的LSTM来得到LSTM层的状态
在这里插入图片描述
LSTM层总共设置4层,传入初始隐藏状态的细胞内容和输入内容。最后取得最后的时间步的输出

模型训练

损失函数选择均方误差函数,优化器选择了Adam优化,总共训练4个epoch

在这里插入图片描述

损失值变化图像

绘制出损失值的变化图像

在这里插入图片描述

模型评估

将测试集的内容导入并做和训练集一样的预处理,然后将测试集放入模型中,将均方误差作为评价标准,计算平均误差。

在这里插入图片描述
并绘制出误差图像

误差都在0.003到0.005之间,说明模型能够正确预测情感。

完整代码

 
import gzip
import pandas as pd
from io import StringIO
import torch
import torch.nn as nn
import torch.optim as optim
 
 
feat_file_path = 'labeledBow.feat'
 
with open(feat_file_path, 'r') as file:
    lines = file.readlines()  # 逐行读取文件内容
 
 
# 显示部分文件内容(可根据需要调整)
# for line in lines[990:1000]:  # 显示前10行内容
#     print(line)
 
 
# In[2]:
 
 
labels = []
features = []
 
for line in lines:
    parts = line.split(' ')
    labels.append(int(parts[0]))
    feats = {}
    for part in parts[1:]:
        index, value = part.split(':')
        feats[int(index)] = float(value)
    features.append(feats)
 
 
# In[3]:
 
 
# 1. 创建词汇表
vocab = {}
for feat_dict in features:
    vocab.update(feat_dict)
 
# 创建特征索引到新的连续索引的映射
feature_idx = {feat: idx for idx, feat in enumerate(sorted(vocab.keys()))}
 
# 2. 创建特征向量
max_features = len(vocab)
feature_vectors = []
for feat_dict in features:
    # 初始化特征向量
    vector = [0.0] * max_features
    
    # 填充特征向量
    for feat_idx, feat_value in feat_dict.items():
        vector[feature_idx[feat_idx]] = feat_value
    
    feature_vectors.append(vector)
 
# 3. 转换为张量
features_tensor = torch.tensor(feature_vectors, dtype=torch.float32)
 
# 检查张量形状
print(features_tensor.shape)
 
 
# In[4]:
 
 
from sklearn.decomposition import PCA
import torch
 
# features_tensor 是特征张量,大小为 torch.Size([25000, 89527])
# 这里将其转换为 NumPy 数组
features_np = features_tensor.numpy()
 
# 初始化PCA,选择需要降维的维度,这里假设降到100维
pca = PCA(n_components=20)
 
# 用PCA拟合数据
features_reduced = pca.fit_transform(features_np)
 
# 将降维后的数据转换回张量形式
features_reduced_tensor = torch.tensor(features_reduced)
 
# 打印降维后的数据大小
print(features_reduced_tensor.size())
 
 
# In[5]:
 
 
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
 
labels_tensor = torch.tensor(labels, dtype=torch.float32)
features_reduced = features_reduced_tensor.unsqueeze(1) 
labels_t = labels_tensor.unsqueeze(1) 
 
train_data = TensorDataset(features_reduced, labels_t)
train_loader = DataLoader(train_data, batch_size=2, shuffle=True)
 
class LSTMModel(nn.Module):
    def __init__(self, input_size, hidden_size, output_size, num_layers=4):
        super(LSTMModel, self).__init__()
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)
 
    def forward(self, x):
        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
        c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
        out, _ = self.lstm(x, (h0, c0))
        out = self.fc(out[:, -1, :])  # 取最后一个时间步的输出
        return out
 
# 定义模型参数
input_size = 20
hidden_size = 128
num_layers = 4
output_size = 1
 
# 初始化模型、损失函数和优化器
model = LSTMModel(input_size, hidden_size, output_size, num_layers)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.0001)
losses = []  # 存储损失值
# 训练模型
num_epochs = 5
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
 
for epoch in range(num_epochs):
    for i, (inputs, targets) in enumerate(train_loader):
        inputs, targets = inputs.to(device), targets.to(device)
        
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs.squeeze(), targets.squeeze())
 
        loss.backward()
        optimizer.step()
        losses.append(loss.item())  # 记录损失值
        if (i+1) % 2 == 0:
            print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item()}')
 
 
 
 
# In[6]:
 
 
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
import matplotlib.pyplot as plt
# 绘制损失值变化图
plt.plot(losses, label='Training Loss')
plt.xlabel('Training Steps')
plt.ylabel('Loss')
plt.title('Training Loss over Steps')
plt.legend()
plt.show()
 
 
# In[7]:
 
 
feat_file_path = 'labeledBow_test.feat'
 
with open(feat_file_path, 'r') as file:
    lines = file.readlines()  # 逐行读取文件内容
 
labels_test = []
features_test = []
 
for line in lines:
    parts = line.split(' ')
    labels_test.append(int(parts[0]))
    feats = {}
    for part in parts[1:]:
        index, value = part.split(':')
        feats[int(index)] = float(value)
    features_test.append(feats)
 
 
# In[8]:
 
 
# 1. 创建词汇表
vocab = {}
for feat_dict in features_test:
    vocab.update(feat_dict)
 
# 创建特征索引到新的连续索引的映射
feature_idx = {feat: idx for idx, feat in enumerate(sorted(vocab.keys()))}
 
# 2. 创建特征向量
max_features = len(vocab)
feature_vectors = []
for feat_dict in features_test:
    # 初始化特征向量
    vector = [0.0] * max_features
    
    # 填充特征向量
    for feat_idx, feat_value in feat_dict.items():
        vector[feature_idx[feat_idx]] = feat_value
    
    feature_vectors.append(vector)
 
# 3. 转换为张量
features_tensor = torch.tensor(feature_vectors, dtype=torch.float32)
 
# 检查张量形状
print(features_tensor.shape)
 
 
# In[9]:
 
 
from sklearn.decomposition import PCA
import torch
 
# features_tensor 是特征张量,大小为 torch.Size([25000, 89527])
# 这里将其转换为 NumPy 数组
features_np = features_tensor.numpy()
 
# 初始化PCA,选择需要降维的维度,这里假设降到100维
pca = PCA(n_components=20)
 
# 用PCA拟合数据
features_reduced = pca.fit_transform(features_np)
 
# 将降维后的数据转换回张量形式
features_reduced_tensor = torch.tensor(features_reduced)
 
# 打印降维后的数据大小
print(features_reduced_tensor.size())
 
 
# In[14]:
 
 
from torch.utils.data import DataLoader, TensorDataset
 
labels_tensor = torch.tensor(labels_test, dtype=torch.float32)
features_reduced = features_reduced_tensor.unsqueeze(1) 
labels_t = labels_tensor.unsqueeze(1) 
 
train_data = TensorDataset(features_reduced, labels_t)
train_loader = DataLoader(train_data, batch_size=2, shuffle=True)
 
losses = []
 
for epoch in range(num_epochs):
    for i, (inputs, targets) in enumerate(train_loader):
        inputs, targets = inputs.to(device), targets.to(device)
        outputs = model(inputs)
        loss = criterion(outputs.squeeze(), targets.squeeze())
        losses.append(loss.item()/len(train_loader))
        if (i+1) % 2 == 0:
            print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item()/len(train_loader)}')
 
 
# In[15]:
 
 
plt.plot(losses, label='Training Loss')
plt.xlabel('Training Steps')
plt.ylabel('Loss')
plt.title('Training Loss over Steps')
plt.legend()
plt.show()
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1376730.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Android开发】不同Activity之间的数据回传实例(一)摘桃子游戏

一、功能介绍 该项目实现的功能主要有: 在首页显示一个按钮点击该按钮跳转到桃园页面在桃园页面,点击桃子会弹窗显示摘到几个桃子,同时被点击桃子消失,总桃子数1点击退出桃园会返回首页,首页桃子数会根据点击的桃子数…

伐木工 - 华为OD统一考试

OD统一考试 题解: Java / Python / C++ 题目描述 一根X米长的树木,伐木工切割成不同长度的木材后进行交易,交易价格为每根木头长度的乘积。规定切割后的每根木头长度都为正整数,也可以不切割,直接拿整根树木进行交易。请问伐木工如何尽量少的切割,才能使收益最大化? 输…

一、docker的安装与踩坑

目录 一、安装docker(centos7安装docker)1.安装环境前期准备2.参考官网安装前准备3.参考官网安装步骤开始安装docker4.运行首个容器 二、安装一些软件的踩坑1.启动docker踩坑2.安装mysql踩坑3.罕见问题 三、关于我的虚拟机 一、安装docker(ce…

销售团队如何实现业绩增长?CRM系统的线索管理功能有什么用?

随着“以客户为中心”观念的逐渐普及,销售团队的客户比过去更复杂,交易周期更久,竞争也更激烈。假如没有明确的销售计划,团队可能陷入混乱,最后导致客户&公司之间的负面结果。在这种情况下,人工智能驱动…

FineBI实战项目一(21):不同支付方式订单总额分析开发

点击新建组件,创建不同支付方式订单总额组件。 选择饼图,拖拽total_money到角度,拖拽pay_type到颜色,调节内径。 修改颜色的标识文字。 将组件拖拽到仪表板。 结果如下:

时至今日,编制与大厂到底怎么选?

我觉得这可能是一个辩论三天三夜也不会有结论的话题。 说实话,2023年已经过去,真的没有感觉赚钱更容易,反而是周边失业的同事不少。 现在感觉,是不是选择早点进入编制可能更加稳定?你们又怎么看?

Java中的多线程

进程和线程的概念 进程是应用程序的执行实例有独立的内存空间和系统资源。 线程是进程中执行运算的最小单位,可完成一个独立的顺序控制流程 一。一个进程可以包含多个线程,每个线程都独立执行特定的任务, 是CPU调度和分派的基本单位。 多线…

【AT 指令开发】软件框架与接口

目录 1 软件逻辑2.代码2.1 at_command.h2.2 at_command.c本文主要用于记录纯MCU无OS下,AT 指令开发软件框架 1 软件逻辑 2.代码 2.1 at_command.h #ifndef AT_COMMAND_H #define AT_COMMAND_Hvoid AT_CMD_Process(uint8_t *uartBuffer, uint8_t dataLen);/*描述AT指令返回值…

第二百五十九回

文章目录 知识回顾示例代码经验总结 我们在上一章回中介绍了MethodChannel的使用方法,本章回中将介绍EventChannel的使用方法.闲话休提,让我们一起Talk Flutter吧。 知识回顾 我们在前面章回中介绍了通道的概念和作用,并且提到了通道有不同的…

PyCharm中配置安装PyQt5、QtDesigner

PyCharm中配置安装PyQt5 使用 pip install PyQt5 命令安装。 安装pyqt5-tools:pip install pyqt5-tools 安装PyQt5Designer:pip install PyQt5Designer 上述三个都安装好之后,输入 pip list 查看一下 有如下内容就安装成功啦!…

四、C++内存管理

1 C/C内存分布 在学习C的内存管理方式之前&#xff0c;我们先来看一道有关C/C内存分布的题目&#xff1a; 阅读下面的代码&#xff0c;回答相关问题&#xff1a; #include <iostream> using namespace std; int globalVar 1; static int staticGlobalVar 1; int main…

1.6计算机网络的性能指标

1.6计算机网络的性能指标 常用的计算机网络的性能指标有7个&#xff1a;速率、带宽、吞吐量、时延、往返时间、利用率、丢包率 1.6.1速率 计算机发送的信号是以二进制数字形式的。一个二进制数字就是一个比特(bit&#xff0c;binary digit)字节:Byte&#xff0c;1Byte8bit(1…

在海绵城市建设中,低功耗遥测终端有哪些独特的优势?

近年来&#xff0c;随着物联网技术的迅猛发展&#xff0c;数据监测和传输已经成为各行各业不可或缺的环节。在诸多特殊环境中因供电问题、潮湿、不便进入等诸多原因&#xff0c;需要一款功耗低、数据传输稳定&#xff0c;防潮抗锈蚀的低功耗遥测终端。 为满足这一需求&#xf…

太强了!腾讯开源!多模态AppAgent自主操作智能手机应用程序!

AppAgent是一款基于大型语言模型&#xff08;LLMs&#xff09;的新型多模态智能代理框架&#xff0c;专为操作智能手机应用而设计。它结合了GPT-4V的先进视觉理解能力&#xff0c;通过“眼睛”观察手机界面&#xff0c;模仿人类的点击和滑动交互方式来学习操作应用程序。这种方…

小红书种草类型有哪些,小红书营销攻略

我们都知道小红书是个内容平台。用户来这可以看到各种类型的笔记&#xff0c;从笔记中获取自己想要了解的内容。这也就意味着平台上有着许多种不同的笔记类型。今天我们和大家分享下小红书种草类型有哪些&#xff0c;小红书营销攻略&#xff01; 1. 明星带货类 顾名思义&#x…

vivado IP Revision Control

2020.2 只需要git 管理 prj.xpr 和 prj.srcs/ https://china.xilinx.com/video/hardware/ip-revision-control.html https://www.xilinx.com/video/hardware/vivado-design-suite-revision-control.html

网络编程的理论基础

文章目录 1 重点知识2 应用层3 再谈 "协议"4 HTTP协议4.1 认识URL4.2 urlencode和urldecode4.3 HTTP协议格式4.4 HTTP的方法4.5 HTTP的状态码4.6 HTTP常见Header4.7 最简单的HTTP服务器 3 传输层4 再谈端口号4.1 端口号范围划分4.2 认识知名端口号(Well-Know Port Nu…

EOCR电机保护器485通讯协议概念

Modbus是由Modicon&#xff08;现为施耐德电气公司的一个品牌&#xff09;在1979年发明的&#xff0c;是全球第一个真正用于工业现场的总线协议。为更好地普及和推动Modbus在基于以太网上的分布式应用&#xff0c;目前施耐德公司已将Modbus协议的所有权移交给IDA&#xff08;In…

IMS中如何区分initial INVITE和re-INVITE?

这里就要先看下Dialog的定义。 dialog是两个UA之间持续一段时间的点对点 SIP关系。dialog通过SIP消息建立&#xff0c;例如对 INVITE request的 2xx response。dialog由Call-ID、local tag和remote tag来区分&#xff0c;也就是Call-ID 、from-tag和to-tag就可以确定一个dialog…

2024年阿里云服务器怎么买便宜?

2024年阿里云服务器租用费用&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;ECS云服务器e系列2核2G配置99元一年、2核4G服务器30元3个月、2核4G配置…