当前位置: 首页 > backend >正文

R4打卡——pytorch实现LSTM预测火灾

   🍨 本文为🔗365天深度学习训练营中的学习记录博客

  • 🍖 原作者:K同学啊

1.检查GPU

import torch.nn.functional as F
import numpy  as np
import pandas as pd
import torch
from torch    import nndata = pd.read_csv("data/woodpine2.csv")data#设置GPU训练
device=torch.device("cuda" if torch.cuda.is_available() else "cpu")
device

2.查看数据

import matplotlib.pyplot as plt
import seaborn as snsplt.rcParams['savefig.dpi'] = 500 #图片像素
plt.rcParams['figure.dpi']  = 500 #分辨率fig, ax =plt.subplots(1,3,constrained_layout=True, figsize=(14, 3))sns.lineplot(data=data["Tem1"], ax=ax[0])
sns.lineplot(data=data["CO 1"], ax=ax[1])
sns.lineplot(data=data["Soot 1"], ax=ax[2])
plt.show()dataFrame = data.iloc[:,1:]
dataFrame

​​

3.划分数据集

from sklearn.preprocessing import MinMaxScalerdataFrame = data.iloc[:,1:].copy()
sc  = MinMaxScaler(feature_range=(0, 1)) #将数据归一化,范围是0到1for i in ['CO 1', 'Soot 1', 'Tem1']:dataFrame[i] = sc.fit_transform(dataFrame[i].values.reshape(-1, 1))dataFrame.shapewidth_X = 8
width_y = 1width_X = 8
width_y = 1##取前8个时间段的Tem1、CO 1、Soot 1为X,第9个时间段的Tem1为y。
X = []
y = []in_start = 0for _, _ in data.iterrows():in_end  = in_start + width_Xout_end = in_end   + width_yif out_end < len(dataFrame):X_ = np.array(dataFrame.iloc[in_start:in_end , ])y_ = np.array(dataFrame.iloc[in_end  :out_end, 0])X.append(X_)y.append(y_)in_start += 1X = np.array(X)
y = np.array(y).reshape(-1,1,1)X.shape, y.shapeX_train = torch.tensor(np.array(X[:5000]), dtype=torch.float32).to(device)
y_train = torch.tensor(np.array(y[:5000]), dtype=torch.float32)X_test  = torch.tensor(np.array(X[5000:]), dtype=torch.float32).to(device)
y_test  = torch.tensor(np.array(y[5000:]), dtype=torch.float32)
X_train.shape, y_train.shapefrom torch.utils.data import TensorDataset, DataLoadertrain_dl = DataLoader(TensorDataset(X_train, y_train),batch_size=64, shuffle=False)test_dl  = DataLoader(TensorDataset(X_test, y_test),batch_size=64, shuffle=False)

​​​

​​​​​

4.创建模型与编译训练

class model_lstm(nn.Module):def __init__(self):super(model_lstm, self).__init__()self.lstm0 = nn.LSTM(input_size=3 ,hidden_size=320, num_layers=1, batch_first=True)self.lstm1 = nn.LSTM(input_size=320 ,hidden_size=320, num_layers=1, batch_first=True)self.fc0   = nn.Linear(320, 1)def forward(self, x):out, hidden1 = self.lstm0(x) out, _ = self.lstm1(out, hidden1) out    = self.fc0(out) return out[:, -1:, :]   #取1个预测值,否则经过lstm会得到8*1个预测model = model_lstm()
model

​​​​5.编译及训练模型

# 训练循环
import copy
def train(train_dl, model, loss_fn, opt, lr_scheduler=None):size        = len(train_dl.dataset)  num_batches = len(train_dl)   train_loss  = 0  # 初始化训练损失和正确率for x, y in train_dl:  x, y = x.to(device), y.to(device)# 计算预测误差pred = model(x)          # 网络输出loss = loss_fn(pred, y)  # 计算网络输出和真实值之间的差距# 反向传播opt.zero_grad()  # grad属性归零loss.backward()  # 反向传播opt.step()       # 每一步自动更新# 记录losstrain_loss += loss.item()if lr_scheduler is not None:lr_scheduler.step()print("learning rate = {:.5f}".format(opt.param_groups[0]['lr']), end="  ")train_loss /= num_batchesreturn train_lossdef test (dataloader, model, loss_fn):size        = len(dataloader.dataset)  # 测试集的大小num_batches = len(dataloader)          # 批次数目test_loss   = 0# 当不进行训练时,停止梯度更新,节省计算内存消耗with torch.no_grad():for x, y in dataloader:x, y = x.to(device), y.to(device)# 计算lossy_pred = model(x)loss        = loss_fn(y_pred, y)test_loss += loss.item()test_loss /= num_batchesreturn test_loss#训练模型
model = model_lstm()
model = model.to(device)
loss_fn    = nn.MSELoss() # 创建损失函数
learn_rate = 1e-1   # 学习率
opt        = torch.optim.SGD(model.parameters(),lr=learn_rate,weight_decay=1e-4)
epochs     = 50
train_loss = []
test_loss  = []
lr_scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(opt,epochs, last_epoch=-1) for epoch in range(epochs):model.train()epoch_train_loss = train(train_dl, model, loss_fn, opt, lr_scheduler)model.eval()epoch_test_loss = test(test_dl, model, loss_fn)train_loss.append(epoch_train_loss)test_loss.append(epoch_test_loss)template = ('Epoch:{:2d}, Train_loss:{:.5f}, Test_loss:{:.5f}')print(template.format(epoch+1, epoch_train_loss,  epoch_test_loss))print("="*20, 'Done', "="*20)


​​​​​

6.结果可视化

import matplotlib.pyplot as plt
from datetime import datetime
current_time = datetime.now() # 获取当前时间plt.figure(figsize=(5, 3),dpi=120)plt.plot(train_loss    , label='LSTM Training Loss')
plt.plot(test_loss, label='LSTM Validation Loss')plt.title('Training and Validation Loss')
plt.xlabel(current_time) # 打卡请带上时间戳,否则代码截图无效
plt.legend()
plt.show()# 将模型输出移至CPU后再转换为NumPy数组
predicted_y_lstm = sc.inverse_transform(model(X_test).cpu().detach().numpy().reshape(-1,1))
y_test_1 = sc.inverse_transform(y_test.reshape(-1,1))
y_test_one = [i[0] for i in y_test_1]
predicted_y_lstm_one = [i[0] for i in predicted_y_lstm]plt.figure(figsize=(5, 3),dpi=120)
# 画出真实数据和预测数据的对比曲线
plt.plot(y_test_one[:2000], color='red', label='real_temp')
plt.plot(predicted_y_lstm_one[:2000], color='blue', label='prediction')plt.title('Title')
plt.xlabel('X')
plt.ylabel('Y')
plt.legend()
plt.show()

​​​​​

​​​​​7.模型评估

from sklearn import metrics# 确保预测值和真实值维度匹配
predicted_y_lstm = predicted_y_lstm.squeeze()  # 压缩到一维,例如从 (100, 1, 1) 变为 (100,)
y_test = y_test.squeeze()                       # 同理处理真实值# 计算指标
RMSE_lstm = metrics.mean_squared_error(predicted_y_lstm, y_test)**0.5
R2_lstm = metrics.r2_score(predicted_y_lstm, y_test)print('均方根误差: %.5f' % RMSE_lstm)
print('R2: %.5f' % R2_lstm)

​​​​​​​​​​​​​​​​​​​​​

总结:

 

1. 背景与目标

 通过实现一个基于LSTM(长短期记忆网络)的深度学习模型,对时间序列数据进行预测。具体任务是从给定的数据集中提取特征(Tem1, CO 1, Soot 1),并利用前8个时间段的数据预测第9个时间段的目标变量(Tem1)。整个过程涵盖了数据预处理、模型构建、训练、评估和结果可视化等关键步骤。


2. 代码流程概述
(1)检查GPU
  • 使用 torch.device 检查是否有可用的GPU资源,并设置为默认设备。
  • GPU加速可以显著提升模型训练效率,尤其是在处理大规模数据时。
(2)查看数据
  • 数据集包含三列:Tem1(目标变量)、CO 1 和 Soot 1
  • 使用 seaborn 和 matplotlib 对数据进行可视化,观察各特征的时间序列趋势。
  • 数据预处理包括归一化操作,将所有特征值缩放到 [0, 1] 范围内,以便模型更好地收敛。
(3)划分数据集
  • 将数据划分为输入特征 X 和目标变量 y
    • 输入 X 包含连续的8个时间步的特征值。
    • 输出 y 是第9个时间步的目标值。
  • 数据集进一步划分为训练集和测试集,并转化为 PyTorch 张量格式,方便后续模型训练。
(4)创建模型
  • 定义了一个两层 LSTM 网络模型:
    • 第一层 LSTM 的隐藏单元数为320,接收3个特征作为输入。
    • 第二层 LSTM 进一步提取时间序列特征。
    • 最后通过全连接层输出单个预测值。
  • 模型的设计考虑了时间序列数据的特点,能够捕捉长期依赖关系。
(5)编译与训练模型
  • 使用均方误差(MSE)作为损失函数,随机梯度下降(SGD)作为优化器。
  • 训练过程中,采用余弦退火学习率调度器动态调整学习率。
  • 每个 epoch 后分别计算训练集和测试集的损失,并记录结果以供后续分析。
(6)结果可视化
  • 绘制了训练集和测试集的损失曲线,直观地展示了模型的收敛情况。
  • 对比了真实值与预测值的时间序列曲线,验证了模型的预测能力。
  • 使用反归一化操作将预测结果还原到原始数据范围,便于解释。
(7)模型评估
  • 使用均方根误差(RMSE)和决定系数(R²)评估模型性能:
    • RMSE 衡量预测值与真实值之间的偏差。
    • R² 反映模型对数据变化的拟合程度。
  • 结果表明,模型在测试集上具有一定的预测能力,但仍存在改进空间。

3. 代码亮点
  • 数据预处理:通过归一化处理和滑动窗口方法,有效地构造了适合LSTM模型的输入数据。
  • 模型设计:采用了双层LSTM结构,能够更好地捕捉时间序列中的复杂模式。
  • 动态学习率:引入余弦退火学习率调度器,提升了模型的训练效果。
  • 结果分析:结合可视化和定量指标,全面评估了模型的性能。
http://www.xdnf.cn/news/63.html

相关文章:

  • 《vue3学习手记4》
  • openai发布今天发布了o3和o4-mini。
  • Vue 3 reactive 和 ref 区别及 失去响应性问题
  • 大数据常见的模型定义及应用场景建议╮(╯▽╰)╭
  • 深入理解常见排序算法:从原理到实践
  • 视频剪辑入门
  • 深入了解v-model的原理:v-model拆分为value属性和input事件,表单类组件的封装并用v-model简化代码
  • 是德科技E5080B网络分析仪深度评测:5G/车载雷达测试实战指南
  • 零基础上手Python数据分析 (16):DataFrame 常用统计分析方法
  • 【2025“华中杯”大学生数学建模挑战赛】C题:就业状态分析与预测 详细解题思路
  • ffmpeg 添加 nvenc支持
  • Layout 路由
  • 202520读书笔记|《我要按自己喜欢的方式去生活》——面对可能到来的裁员,那就等正式通知吧
  • SAP系统青果糖无法报工
  • 前沿要塞:Vue组件安全工程的防御体系重构与技术突围
  • 介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
  • 第十六届蓝桥杯大赛软件赛省赛 C++ 大学 B 组 部分题解
  • 解锁智能制造:PLC远程下载如何让设备运维效率提升10倍?
  • 【APM】Build an environment for Traces, Metrics and Logs of App by OpenTelemetry
  • Python网络爬虫设计(二)
  • DP 32bit位宽数据扰码实现和仿真
  • Oracle 19c部署之初始化实例(三)
  • [图论]Prim
  • docker的基础知识
  • 多模态大模型的算力需求预测:从理论FLOPs到实际集群配置(搭建算力成本评估模型的方法论)
  • 每日OJ_牛客_ruby和薯条_排序+二分/滑动窗口_C++_Java
  • 知识库Qanyting部署问题总结
  • 个人博客系统后端 - 用户信息管理功能实现指南(上)
  • Ubuntu利用docker搭建Java相关环境记录(二)
  • C++学习:六个月从基础到就业——面向对象编程:重载运算符(下)