# -*- 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 表示“最后一个维度(或索引)的元素”。
: 再次用于指定该维度内的所有元素 例元素