lstm 代码实现

# -*- coding: utf-8 -*-
# @FileName : 1.py


# Copyright (c) 2025 YGQ16. All rights reserved.
# Licensed under the MIT license.
# Description:


import numpy as np
import pandas as pd

# 1. 加载数据集
data = pd.read_csv('第二题数据.csv')

# 2. 平衡样本的均衡(正负各取500)
label_0 = data[data['label'] == 0].head(500)
label_1 = data[data['label'] == 1].head(500)
data = pd.concat([label_0, label_1])

# 提取文本和标签
x = data['text']
y = data['label']

# 3. 进行数据处理,完成向量化(使用TF-IDF + 字符 ngram)
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer(max_features=200, max_df=0.8, analyzer='char', ngram_range=(1, 3))
x = tf.fit_transform(x).toarray()  # 转换为TF-IDF特征向量

# 4. 转换为PyTorch Tensor,准备输入模型
import torch
x = torch.FloatTensor(x)           # 转成 float tensor
x = torch.unsqueeze(x, dim=1)      # 增加一个维度,变成三维 
y = torch.LongTensor(y)            # 标签转成 long tensor,适配CrossEntropyLoss

# 5. 划分训练集和测试集
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=42)

# 获取输出类别数
output = len(np.unique(y))

# 6. 定义模型,采用双向LSTM + 全连接分类层
class Bi_lstm(torch.nn.Module):
    def __init__(self) -> None:
        super().__init__()
        self.lstm = torch.nn.LSTM(
            input_size=x.shape[-1],     # 特征维度
            hidden_size=64,             # 隐藏层大小
            dropout=0.2,                # dropout防止过拟合
            batch_first=True,           # 输入格式 (batch, seq, feature)
            bidirectional=True          # 双向LSTM
        )
        self.fc = torch.nn.Linear(in_features=64 * 2, out_features=output)  # 输出层

    def forward(self, x):
        x, _ = self.lstm(x)              # LSTM输出是 (batch, seq_len, hidden_size * 2)
        out = self.fc(x[:, -1, :])       # 取最后时间步的输出作为特征输入全连接层
        return out

# 7. 实例化模型、定义优化器和损失函数
model = text_lstm()
optim = torch.optim.Adam(model.parameters(), lr=0.01)
loss_ = torch.nn.CrossEntropyLoss()

# 8. 训练模型
model.train()
for i in range(500):
    optim.zero_grad()               # 清空梯度
    h = model(x_train)             # 前向传播
    loss = loss_(h, y_train)       # 计算损失
    loss.backward()                # 反向传播
    optim.step()                   # 参数更新
    if i % 10 == 0:
        print(i, loss)

# 9. 模型评估
model.eval()
with torch.no_grad():              # 不计算梯度,提高评估效率
    h = model(x_test)
    pre = np.argmax(h, axis=1)     # 取每行最大概率的类别索引

    from sklearn.metrics import classification_report
    print(classification_report(y_test, pre))  # 打印精度、召回率、F1等

# 10. 保存模型
torch.save(model, 'model')

LSTM的输入层为什么是最后一个维度开始?

Lstm 的工作机制:LSTM单元在每个时间步并更新内部状态 ,在每个时间步 它需要处理当前时间步的特征向量,最后一个维度的每个元素代表了该时间步的特征向量,最后一个维度的每个元素代表了该时间步上的一个特征。
LSTM 通过门控机制(遗忘门、输入门、输出门)逐步更新细胞状态和隐藏状态 他的重要性程度较大 权重系数较高 都会累计传送到最后 所以取到最后一个时间步
在使用长短期记忆网络(LSTM)时,输入数据通常具有三维形状(样本数, 时间步长, 特征数)

除了adam优化器还有什么优化器?

1. SGD(随机梯度下降)
SGD 是最基础的优化器,其原理是在每次迭代时计算单个样本或小批量样本的梯度,然后按照梯度的反方向更新模型参数。
优点:概念简单,易于理解和实现,当数据量很大时,能较快收敛。
缺点:收敛速度较慢,容易陷入局部最优解,学习率的选择对其性能影响较大。
2. Momentum
Momentum 优化器在 SGD 的基础上引入了动量的概念,通过积累之前梯度的信息,使得在更新参数时能够更快地跨越局部最优解,朝着全局最优解前进。
优点:加快收敛速度,尤其是在面对高曲率、小但一致的梯度或带噪声的梯度时表现出色。
缺点:需要额外调整动量参数,若设置不当可能导致模型不稳定。
3. Adagrad
Adagrad 是一种自适应学习率的优化器,它会为每个参数分配不同的学习率,对于经常更新的参数,学习率会逐渐减小;而对于不经常更新的参数,学习率会相对较大。
优点:无需手动调整学习率,能自适应地调整每个参数的学习率,适合处理稀疏数据。
缺点:随着训练的进行,学习率会逐渐减小,可能导致后期学习速度过慢。
4. Adadelta
Adadelta 是对 Adagrad 的改进,它解决了 Adagrad 学习率衰减过快的问题。Adadelta 不需要手动设置全局学习率,而是通过指数移动平均来动态调整学习率。
优点:不需要手动设置学习率,能自适应地调整每个参数的学习率,避免了 Adagrad 学习率过快衰减的问题。
缺点:计算复杂度相对较高,需要维护额外的状态信息。
5. RMSprop
RMSprop 也是一种自适应学习率的优化器,它通过对梯度平方的指数移动平均来调整学习率,使得模型在不同方向上的学习率能够自适应地调整。
优点:能够自适应地调整每个参数的学习率,对于非平稳目标函数表现良好,在处理深度学习模型时效果较好。
缺点:需要调整衰减率参数,若设置不当可能影响模型性能。

变量 定义:变量是存储数据的容器,其值在程序运行过程中可以被改变 作用:不同类型的变量可以存储不同类型的数据。

常量 常量也是存储数据的容器,但与变量不同的是,常量的值在定义后就不能被改变 作用:常量通常用于存储那些在程序运行过程中不会改变的值

张量 :一维张量就是向量,二维张量就是矩阵,三维及以上的张量就是更高维度的数组。作用:数据通常以张量的形式进行表示和处理。神经网络的输入、输出以及中间层的特征图都是张量

input_size = x.shape[-1]#获取输入数据 x 的特征数量
hidden_size= 128 #代表有128个神经元 可以设置低维度 ,维度高增加过拟合风险
out_size = len(np.unique(y))#计算不同类别的数量
        x = self.linear(x[:,-1,:])
x 是一个多维数组(例如 3D 数组)。
: 表示“选择所有行元素”。
-1 表示“最后一个维度(或索引)的元素”。
: 再次用于指定该维度内的所有元素 例元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值