PyTorch深度学习实战 | 基于RNN的情感识别任务

🌞欢迎来到深度学习实战的世界 
🌈博客主页:卿云阁

💌欢迎关注🎉点赞👍收藏⭐️留言📝

🌟本文由卿云阁原创!

📆首发时间:🌹2025年2月12日🌹

✉️希望可以和大家一起完成进阶之路!

🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!


目录

RNN介绍

手算模拟

实战

 RNN介绍

       RNN(Recurrent Neural Network) 是一种用于处理序列数据的神经网络模型,特别适用于

处理时间序列、语音、文本等具有顺序关系的数据。

      简单的神经网络都是水平方向的延申,RNN可以关联不同的时刻,RNN的输出不仅取决于当前

时刻的输出还取决于上一时刻隐藏层的输出。(神经网络具有某种记忆的能力)

举个例子(使用RNN进行情感分类)


手算模拟

代码实现
import torch
import torch.nn as nn

# 设置随机种子保证结果可复现
torch.manual_seed(42)

# 定义超参数
input_size = 1  # 输入特征数 (单个数)
hidden_size = 2  # 隐藏层大小 (两个神经元)
num_layers = 1  # RNN 层数
seq_length = 3  # 序列长度 (3 个时间步)
batch_size = 1  # 只有 1 个样本

# 创建 RNN
rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True)

# 人工设定权重和偏置(方便计算)
with torch.no_grad():
    rnn.weight_ih_l0.copy_(torch.tensor([[0.5], [-0.5]], dtype=torch.float32))  # 输入到隐藏层的权重
    rnn.weight_hh_l0.copy_(torch.tensor([[0.3, -0.3], [0.6, -0.6]], dtype=torch.float32))  # 隐藏层到隐藏层
    rnn.bias_ih_l0.zero_()  # 输入层偏置设为 0
    rnn.bias_hh_l0.zero_()  # 隐藏层偏置设为 0

# 输入数据 (时间步数为 3)
X = torch.tensor([[[1.0], [2.0], [3.0]]])  # 形状 (batch_size, seq_length, input_size)

# 初始化隐藏状态 (全零)
h0 = torch.zeros(num_layers, batch_size, hidden_size)

# 进行前向传播
out, hn = rnn(X, h0)

# 打印输出
print("隐藏状态 Ht (每个时间步):\n", out.detach().numpy())  # 所有时间步的隐藏状态
print("\n最终隐藏状态 hn:\n", hn.detach().numpy())  # 最后一个时间步的隐藏状态


实战

# --------------------------
# 修正 NumPy 中已废弃的别名(np.object、np.bool、np.int)
# --------------------------
import numpy as np

np.object = object
np.bool = bool
np.int = int

# --------------------------
# 导入所需的库
# --------------------------
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.model_selection import train_test_split
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences

# --------------------------
# 1. 生成中文情感分类数据集
# --------------------------
# 简单数据集包含正面和负面句子
texts = [
    "我喜欢这个产品", "这真是太棒了", "我讨厌这个商品", "质量差劲",
    "简直太棒了", "最糟糕的购买", "我对这个感觉很好", "不好",
    "我对这个很满意", "这个真糟糕", "我喜欢使用这个", "非常失望"
]
# 标签:1表示正面,0表示负面
labels = [1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0]

# 划分训练集和测试集(70%训练,30%测试)
X_train, X_test, y_train, y_test = train_test_split(texts, labels, test_size=0.3, random_state=42)

# --------------------------
# 2. 文本预处理:使用 Keras 的 Tokenizer 进行向量化和序列填充
# --------------------------
# 定义最大词数,构建 Tokenizer 对象
tokenizer = Tokenizer(num_words=10000)
tokenizer.fit_on_texts(X_train)

# 将文本转换为数字序列
X_train_seq = tokenizer.texts_to_sequences(X_train)
X_test_seq = tokenizer.texts_to_sequences(X_test)

# 对序列进行填充,使得所有句子长度一致(此处设为10)
maxlen = 10
X_train_pad = pad_sequences(X_train_seq, padding='post', maxlen=maxlen)
X_test_pad = pad_sequences(X_test_seq, padding='post', maxlen=maxlen)

# --------------------------
# 3. 将数据转换为 PyTorch Tensor
# --------------------------
X_train_tensor = torch.tensor(X_train_pad, dtype=torch.long)
X_test_tensor = torch.tensor(X_test_pad, dtype=torch.long)
y_train_tensor = torch.tensor(y_train, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test, dtype=torch.float32)


# --------------------------
# 4. 定义 RNN 模型(使用 PyTorch 构建)
# --------------------------
class RNNModel(nn.Module):
    def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim):
        super(RNNModel, self).__init__()
        # 嵌入层:将词索引转换为词向量
        self.embedding = nn.Embedding(vocab_size, embedding_dim)
        # RNN 层:这里使用 nn.RNN,参数 batch_first=True 保证输入维度为 (batch, seq, feature)
        self.rnn = nn.RNN(embedding_dim, hidden_dim, batch_first=True)
        # 全连接层,将 RNN 的输出映射到情感分类(1维输出)
        self.fc = nn.Linear(hidden_dim, output_dim)
        # Sigmoid 激活函数,将输出转换为 0~1 之间的概率
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        # x: (batch_size, seq_length)
        x = self.embedding(x)  # 输出形状: (batch_size, seq_length, embedding_dim)
        out, _ = self.rnn(x)  # out: (batch_size, seq_length, hidden_dim)
        out = out[:, -1, :]  # 取最后一个时刻的输出: (batch_size, hidden_dim)
        out = self.fc(out)  # 全连接层映射: (batch_size, output_dim)
        out = self.sigmoid(out)  # 输出概率: (batch_size, output_dim)
        return out


# 定义超参数
vocab_size = 10000  # 词汇表大小
embedding_dim = 128  # 嵌入层维度
hidden_dim = 64  # RNN 隐藏层维度
output_dim = 1  # 输出维度(1 表示二分类任务)

# 初始化模型
model = RNNModel(vocab_size, embedding_dim, hidden_dim, output_dim)
print("模型结构:")
print(model)

# --------------------------
# 5. 训练模型
# --------------------------
# 定义损失函数(BCELoss 适用于二分类任务)和优化器(Adam)
criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

num_epochs = 5
batch_size = 4  # 此示例中数据集较小,可直接一次性传入

for epoch in range(num_epochs):
    model.train()
    optimizer.zero_grad()

    # 前向传播
    outputs = model(X_train_tensor)  # 输出形状: (batch_size, 1)
    outputs = outputs.squeeze(1)  # 去除多余维度 -> (batch_size)
    loss = criterion(outputs, y_train_tensor)

    # 反向传播和更新参数
    loss.backward()
    optimizer.step()

    print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')

# --------------------------
# 6. 评估模型在测试集上的表现
# --------------------------
model.eval()
with torch.no_grad():
    test_outputs = model(X_test_tensor).squeeze(1)
    # 将概率转换为 0/1 标签,阈值设置为 0.5
    predicted = (test_outputs > 0.5).float()
    correct = (predicted == y_test_tensor).sum().item()
    accuracy = correct / len(y_test_tensor)
    print(f'模型在测试集上的准确率: {accuracy * 100:.2f}%')

# --------------------------
# 7. 使用模型对新文本进行预测
# --------------------------
new_texts = ["我非常喜欢我的购买", "这个产品真的很糟糕"]
new_seq = tokenizer.texts_to_sequences(new_texts)
new_pad = pad_sequences(new_seq, padding='post', maxlen=maxlen)
new_tensor = torch.tensor(new_pad, dtype=torch.long)

model.eval()
with torch.no_grad():
    predictions = model(new_tensor).squeeze(1)
    predicted_labels = (predictions > 0.5).float()
    print("新文本预测结果:", predicted_labels.numpy())

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卿云阁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值