工业数学模型——高炉煤气发生量预测(三)

1、工业场景

冶金过程中生产的各种煤气,例如高炉煤气、焦炉煤气、转炉煤气等。作为重要的副产品和二次能源,保证它们的梯级利用和减少放散是煤气能源平衡调控的一项紧迫任务,准确的预测煤气的发生量是实现煤气系统在线最优调控的前提。

2、数学模型

本次研究主要采用了长短记忆模型(LSTM)预测了正常工况下的高炉煤气发生量。后续研究方向希望将正常工况扩展到变化工况条件下,例如休风、减产、停产、检修等条件下煤气发生量,并引入更多特征维度,例如:焦比、煤比、风量、富氧、风温、风压、炉内压差等。下面重点介绍一下LSTM网络结构。

长短期记忆网络(LSTM,Long Short-Term Memory)是一种时间循环神经网络,是为了解决一般的RNN(循环神经网络)存在的长期依赖问题而专门设计出来的,所有的RNN都具有一种重复神经网络模块的链式形式。
在这里插入图片描述这张图片是经典的LSTM网络结构的图片,但是不好理解,图片把多维的空间结构压缩成了二维图片,所以需要大家脑补一下,回放到立体空间中去理解。相对比RNN 通过时间步骤地更新隐藏状态和输出结果。而LSTM 通过输入门、遗忘门和输出门来控制隐藏状态的更新和输出。在这里不过多的去讲解模型结构,大家可以从网上了解一下,LSTM网络模型作为世纪霸主被广泛应用于自然语言处理、语音识别、图像处理等领域。总之很厉害!

3、数据准备

本次数据收集了1#高炉从4月12日0点到4月16日0点72小时的煤气累计发生量数据,时间间隔为60000ms也就是1分钟一次点位数据,通过计算获取5760个分钟级的煤气发生量数据。
如图:第一个字段是数采时序库中的点位标识,第二个字段是时间,第三个字段是当前煤气发生量累计值,第四个字段是计算获得的当前分钟内煤气发生量。

在这里插入图片描述

4、模型构建

class LSTM(nn.Module):"""LSMT网络搭建"""def __init__(self, input_size, hidden_size, num_layers, output_size, batch_size):super().__init__()self.input_size = input_sizeself.hidden_size = hidden_sizeself.num_layers = num_layersself.output_size = output_sizeself.num_directions = 1  # 单向LSTMself.batch_size = batch_sizeself.lstm = nn.LSTM(self.input_size, self.hidden_size, self.num_layers, batch_first=True)self.linear = nn.Linear(self.hidden_size, self.output_size)def forward(self, input_seq):batch_size, seq_len = input_seq.shape[0], input_seq.shape[1]h_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size)c_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size)output, _ = self.lstm(input_seq, (h_0, c_0))pred = self.linear(output)pred = pred[:, -1, :]return pred

5、模型训练

①数据预处理:加载数据文件,原始数据文件为csv(通过1#高炉84小时内煤气发生量累计值,时间间隔为60000ms,计算出84小时内每分钟的发生量)将数据分为训练集:验证集:测试集=3:1:1。

def load_data(file_name):"""加载数据文件,原始数据文件为csv(通过1#高炉24小时内煤气发生量累计值,时间间隔为60000ms,计算出24小时内每分钟的发生量):param file_name csv文件的绝对路径:return 训练集、验证集、测试集、训练集中最大值、训练集中最小值训练集:验证集:测试集=3:1:1"""dataset = pd.read_csv('D:\\LIHAOWORK\\' + file_name, encoding='gbk')train = dataset[:int(len(dataset) * 0.6)]val = dataset[int(len(dataset) * 0.6):int(len(dataset) * 0.8)]test = dataset[int(len(dataset) * 0.8):len(dataset)]max, nin = np.max(train[train.columns[3]]), np.min(train[train.columns[3]])  # 分钟内发生量是csv中第四个字段return train, val, test, max, nin

②数据组装:把数据组装成训练、验证、测试需要的格式。实质是90个顺序数据为一组作为输入值x,第91个作为真实发生值y,如此循环。

def process_data(data, batch_size, shuffle, m, n, k):"""数据处理:param data 待处理数据:param batch_size 批量大小:param shuffle 是否打乱:param m 最大值:param n 最小值:param k 序列长度:return 处理好的数据"""data_3 = data.iloc[0:, [3]].to_numpy().reshape(-1)  #data_3 = data_3.tolist()data = data.values.tolist()data_3 = (data_3 - n) / (m - n)feature = []label = []for i in range(len(data) - k):train_seq = []train_label = []for j in range(i, i + k):x = [data_3[j]]train_seq.append(x)train_label.append(data_3[i + k])feature.append(train_seq)label.append(train_label)feature_tensor = torch.FloatTensor(feature)label_tensor = torch.FloatTensor(label)data = TensorDataset(feature_tensor, label_tensor)data_loader = DataLoader(dataset=data, batch_size=batch_size, shuffle=shuffle, num_workers=0, drop_last=True)return data_loader

③模型训练:输入大小为1;隐藏层大小为128,隐藏层数为1,输出大小为1,批量大小为5,学习率为0.01,训练次数3。

def train(Dtr, Val, path):"""训练:param Dtr 训练集:param Val 验证集:param path 模型保持路劲"""input_size = 1hidden_size = 128num_layers = 1output_size = 1epochs = 5model = LSTM(input_size, hidden_size, num_layers, output_size, batch_size=5)loss_function = nn.MSELoss()optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=1e-4)# optimizer = torch.optim.SGD(model.parameters(), lr=0.05, momentum=0.9, weight_decay=1e-4)scheduler = StepLR(optimizer, step_size=30, gamma=0.1)# start trainingfor epoch in tqdm(range(epochs)):train_loss = []for (seq, label) in Dtr:y_pred = model(seq)loss = loss_function(y_pred, label)train_loss.append(loss.item())optimizer.zero_grad()loss.backward()optimizer.step()scheduler.step()# validationmodel.eval()val_loss = []for seq, label in Val:y_pred = model(seq)loss = loss_function(y_pred, label)val_loss.append(loss.item())print('epoch {:03d} train_loss {:.8f} val_loss {:.8f}'.format(epoch, np.mean(train_loss), np.mean(val_loss)))model.train()state = {'models': model.state_dict()}torch.save(state, path)

训练过程如下:
在这里插入图片描述

④模型测试:

def test(Dte, path, m, n):"""测试:param Dte 测试集:param path 模型:param m 最大值:param n 最小值"""pred = []y = []input_size = 1hidden_size = 128num_layers = 1output_size = 1model = LSTM(input_size, hidden_size, num_layers, output_size, batch_size=5)model.load_state_dict(torch.load(path)['models'])model.eval()for (seq, target) in tqdm(Dte):y.extend(target)with torch.no_grad():y_pred = model(seq)pred.extend(y_pred)y, pred = np.array(y), np.array(pred)y = (m - n) * y + npred = (m - n) * pred + n# 出图x = [i for i in range(len(y))]x_smooth = np.linspace(np.min(x), np.max(x), 1000)y_smooth = make_interp_spline(x, y)(x_smooth)plt.plot(x_smooth, y_smooth, c='green', marker='*', ms=1, alpha=1, label='true')y_smooth = make_interp_spline(x, pred)(x_smooth)plt.plot(x_smooth, y_smooth, c='red', marker='o', ms=1, alpha=1, label='pred')plt.grid(axis='y')plt.legend()plt.show()

直接对比图:红色线为模型在测试数据集上的预测值,绿色线为真实的发生值。
在这里插入图片描述有点密密麻麻,我们可以看一下局部
在这里插入图片描述在这里插入图片描述⑤滚动测试30分钟内发生值,利用前90分钟的真实发生值预测第91分钟的发生值,再将第91分钟的发生值加入到输入中,预测第92分钟的发生值,以此类推,预测30分钟内的高炉煤气发生量。

def test_rolling(Dte, path, m, n):"""滚动测试,预测30条:param Dte 测试集:param path 模型:param m 最大值:param n 最小值"""pred = []y = []input_size = 1hidden_size = 128num_layers = 1output_size = 1model = LSTM(input_size, hidden_size, num_layers, output_size, batch_size=1)model.load_state_dict(torch.load(path)['models'])model.eval()i = 0  # 控制滚动预测的长度,这里计划通过前90分钟内的发生量预测后30分钟内的发生量for (seq, target) in tqdm(Dte):y.extend(target)with torch.no_grad():seq = seq.numpy().tolist()[0]seq.extend(pred)  # 预测值追加到后面seq = seq[-90:]   # 截取后90条数据,滚动预测seq = torch.tensor(seq).resize(1, 90, 1)y_pred = model(seq)pred.extend(y_pred)i = i + 1if i >= 30:  # 控制滚动预测的长度,这里计划通过前90分钟内的发生量预测后30分钟内的发生量breaky, pred = np.array(y), np.array(pred)y = (m - n) * y + npred = (m - n) * pred + n# 出图x = [i for i in range(len(y))]x_smooth = np.linspace(np.min(x), np.max(x), 1000)y_smooth = make_interp_spline(x, y)(x_smooth)plt.plot(x_smooth, y_smooth, c='green', marker='*', ms=1, alpha=1, label='true')y_smooth = make_interp_spline(x, pred)(x_smooth)plt.plot(x_smooth, y_smooth, c='red', marker='o', ms=1, alpha=1, label='pred')plt.grid(axis='y')plt.legend()plt.show()

出图
在这里插入图片描述有点过分拟合
调整参数num_layers = 2 增加dropout=0.3 后
在这里插入图片描述整体效果不是很理想,可能再调一下参会好一些。
目前的完整代码如下:

import pandas as pd
import numpy as np
import torch
from matplotlib import pyplot as plt
from scipy.interpolate import make_interp_spline
from torch import nn
from torch.optim.lr_scheduler import StepLR
from torch.utils.data import DataLoader, TensorDataset
from tqdm import tqdmdef load_data(file_name):"""加载数据文件,原始数据文件为csv(通过1#高炉24小时内煤气发生量累计值,时间间隔为60000ms,计算出24小时内每分钟的发生量):param file_name csv文件的绝对路径:return 训练集、验证集、测试集、训练集中最大值、训练集中最小值训练集:验证集:测试集=3:1:1"""dataset = pd.read_csv('D:\\LIHAOWORK\\' + file_name, encoding='gbk')train = dataset[:int(len(dataset) * 0.6)]val = dataset[int(len(dataset) * 0.6):int(len(dataset) * 0.8)]test = dataset[int(len(dataset) * 0.8):len(dataset)]max, nin = np.max(train[train.columns[3]]), np.min(train[train.columns[3]])  # 分钟内发生量是csv中第四个字段return train, val, test, max, nindef process_data(data, batch_size, shuffle, m, n, k):"""数据处理:param data 待处理数据:param batch_size 批量大小:param shuffle 是否打乱:param m 最大值:param n 最小值:param k 序列长度:return 处理好的数据"""data_3 = data.iloc[0:, [3]].to_numpy().reshape(-1)  #data_3 = data_3.tolist()data = data.values.tolist()data_3 = (data_3 - n) / (m - n)feature = []label = []for i in range(len(data) - k):train_seq = []train_label = []for j in range(i, i + k):x = [data_3[j]]train_seq.append(x)train_label.append(data_3[i + k])feature.append(train_seq)label.append(train_label)feature_tensor = torch.FloatTensor(feature)label_tensor = torch.FloatTensor(label)data = TensorDataset(feature_tensor, label_tensor)data_loader = DataLoader(dataset=data, batch_size=batch_size, shuffle=shuffle, num_workers=0, drop_last=True)return data_loaderclass LSTM(nn.Module):"""LSMT网络搭建"""def __init__(self, input_size, hidden_size, num_layers, output_size, batch_size):super().__init__()self.input_size = input_sizeself.hidden_size = hidden_sizeself.num_layers = num_layersself.output_size = output_sizeself.num_directions = 1  # 单向LSTMself.batch_size = batch_sizeself.lstm = nn.LSTM(self.input_size, self.hidden_size, self.num_layers, dropout=0.3, batch_first=True)self.linear = nn.Linear(self.hidden_size, self.output_size)def forward(self, input_seq):batch_size, seq_len = input_seq.shape[0], input_seq.shape[1]h_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size)c_0 = torch.randn(self.num_directions * self.num_layers, self.batch_size, self.hidden_size)output, _ = self.lstm(input_seq, (h_0, c_0))pred = self.linear(output)pred = pred[:, -1, :]return preddef train(Dtr, Val, path):"""训练:param Dtr 训练集:param Val 验证集:param path 模型保持路劲"""input_size = 1hidden_size = 128num_layers = 2output_size = 1epochs = 3model = LSTM(input_size, hidden_size, num_layers, output_size, batch_size=5)loss_function = nn.MSELoss()optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=1e-4)# optimizer = torch.optim.SGD(model.parameters(), lr=0.05, momentum=0.9, weight_decay=1e-4)scheduler = StepLR(optimizer, step_size=30, gamma=0.1)# start trainingfor epoch in tqdm(range(epochs)):train_loss = []for (seq, label) in Dtr:y_pred = model(seq)loss = loss_function(y_pred, label)train_loss.append(loss.item())optimizer.zero_grad()loss.backward()optimizer.step()scheduler.step()# validationmodel.eval()val_loss = []for seq, label in Val:y_pred = model(seq)loss = loss_function(y_pred, label)val_loss.append(loss.item())print('epoch {:03d} train_loss {:.8f} val_loss {:.8f}'.format(epoch, np.mean(train_loss), np.mean(val_loss)))model.train()state = {'models': model.state_dict()}torch.save(state, path)def test(Dte, path, m, n):"""测试:param Dte 测试集:param path 模型:param m 最大值:param n 最小值"""pred = []y = []input_size = 1hidden_size = 128num_layers = 2output_size = 1model = LSTM(input_size, hidden_size, num_layers, output_size, batch_size=5)model.load_state_dict(torch.load(path)['models'])model.eval()for (seq, target) in tqdm(Dte):y.extend(target)with torch.no_grad():y_pred = model(seq)pred.extend(y_pred)y, pred = np.array(y), np.array(pred)y = (m - n) * y + npred = (m - n) * pred + n# 出图x = [i for i in range(len(y))]x_smooth = np.linspace(np.min(x), np.max(x), 1000)y_smooth = make_interp_spline(x, y)(x_smooth)plt.plot(x_smooth, y_smooth, c='green', marker='*', ms=1, alpha=1, label='true')y_smooth = make_interp_spline(x, pred)(x_smooth)plt.plot(x_smooth, y_smooth, c='red', marker='o', ms=1, alpha=1, label='pred')plt.grid(axis='y')plt.legend()plt.show()def test_rolling(Dte, path, m, n):"""滚动测试,预测30条:param Dte 测试集:param path 模型:param m 最大值:param n 最小值"""pred = []y = []input_size = 1hidden_size = 128num_layers = 2output_size = 1model = LSTM(input_size, hidden_size, num_layers, output_size, batch_size=1)model.load_state_dict(torch.load(path)['models'])model.eval()i = 0  # 控制滚动预测的长度,这里计划通过前90分钟内的发生量预测后30分钟内的发生量for (seq, target) in tqdm(Dte):y.extend(target)with torch.no_grad():seq = seq.numpy().tolist()[0]seq.extend(pred)  # 预测值追加到后面seq = seq[-90:]   # 截取后90条数据,滚动预测seq = torch.tensor(seq).resize(1, 90, 1)y_pred = model(seq)pred.extend(y_pred)i = i + 1if i >= 30:  # 控制滚动预测的长度,这里计划通过前90分钟内的发生量预测后30分钟内的发生量breaky, pred = np.array(y), np.array(pred)y = (m - n) * y + npred = (m - n) * pred + n# 出图x = [i for i in range(len(y))]x_smooth = np.linspace(np.min(x), np.max(x), 1000)y_smooth = make_interp_spline(x, y)(x_smooth)plt.plot(x_smooth, y_smooth, c='green', marker='*', ms=1, alpha=1, label='true')y_smooth = make_interp_spline(x, pred)(x_smooth)plt.plot(x_smooth, y_smooth, c='red', marker='o', ms=1, alpha=1, label='pred')plt.grid(axis='y')plt.legend()plt.show()if __name__ == '__main__':Dtr, Val, Dte, m, n = load_data("4.csv")Dtr = process_data(Dtr, 5, False, m, n, 90)Val = process_data(Val, 5, False, m, n, 90)#Dte = process_data(Dte, 5, False, m, n, 90)Dte = process_data(Dte, 1, False, m, n, 90)train(Dtr, Val, "D:\\LIHAOWORK\\model.pth")#test(Dte, "D:\\LIHAOWORK\\model.pth", m, n)test_rolling(Dte, "D:\\LIHAOWORK\\model.pth", m, n)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

A Geolocation Databases Study(2011年)第二部分:Geolocation Services

下载地址:A Geolocation Databases Study | IEEE Journals & Magazine | IEEE Xplore 被引次数:195 Shavitt Y, Zilberman N. A geolocation databases study[J]. IEEE Journal on Selected Areas in Communications, 2011, 29(10): 2044-2056. 2. Geolocation Services…

2024认证杯数学建模C题思路模型代码

目录 2024认证杯数学建模C题思路模型代码:4.11开赛后第一时间更新,获取见文末名片 以下为2023年认证杯C题: 2024年认证杯数学建模C题思路模型代码见此 2024认证杯数学建模C题思路模型代码:4.11开赛后第一时间更新,获…

一文掌握:图片转Base64编码的原理、实践(自定义图片本地缓存等)以及优化事项

图片转Base64是指将一幅图片(如PNG、JPEG、GIF等格式)的二进制数据编码为符合Base64规范的文本字符串的过程。图片Base64编码将图片数据转换为ASCII字符串,便于网络传输和存储。实现步骤包括读取图片文件、转换为字节数组,再通过编…

Windows 安装 A UDP/TCP Assistant 网络调试助手

Windows 安装 A UDP/TCP Assistant 网络调试助手 0. 引言1. 下载地址2. 安装和使用 0. 引言 需要调试一个实时在线聊天程序,安装一个UDP/TCP Assistant 网络调试助手,方便调试。 1. 下载地址 https://github.com/busyluo/NetAssistant/releases 2. 安…

Vue3项目 网易严选_学习笔记

Vue3项目 网易严选_第一天 主要内容 项目搭建vuex基础路由设计首页顶部和底部布局 学习目标 知识点要求项目搭建掌握vuex基础掌握路由设计掌握首页顶部和底部布局掌握 一、项目搭建 1.1 创建项目 vue create vue-wangyi选择vue3.0版本 1.2 目录调整 大致步骤&#xff…

美格智能出席紫光展锐第三届泛金融支付生态论坛,引领智慧金融变革向新

4月16日,以“融智创新,共塑支付产业新生态”为主题的紫光展锐第三届泛金融支付生态论坛在福州举办,来自金融服务机构、分析师机构、终端厂商、模组厂商等行业各领域生态伙伴汇聚一堂,探讨金融支付产业的机遇与挑战。作为紫光展锐重…

个人网站制作 Part 24 添加用户反馈功能[Userback] | Web开发项目添加页面缓存

文章目录 👩‍💻 基础Web开发练手项目系列:个人网站制作🚀 添加用户反馈功能🔨使用反馈工具🔧步骤 1: 选择反馈工具🔧步骤 2: 注册Userback账户🔧步骤 3: 获取反馈按钮代码 使用Vue.…

生成对抗网络GAN的扩展应用理解

注:本文仅个人学习理解,如需详细内容请看原论文! 一、cycleGAN 1.整体架构: 将图片A通过生成器生成图片B,然后通过判别器判别图片B的真假;并且图片B通过另一个生成器生成A‘,让A和A’近似。 2…

Linux 下的文件夹对比工具 vddiff 介绍

大家好,我是孔令飞,字节跳动云原生开发专家、前腾讯云原生技术专家;《企业级Go项目开发实战》作者,云原生实战营 知识星球星主。欢迎关注我的公众号【令飞编程】,干货不错过。 在大家的日常工作中有没有遇到以下场景&a…

初始Next.js

版本: 本系列next.js基于的是目前最新版本的 v14 版本,需要 Node.js 18.17 及以后版本 创建项目: 最快捷的创建 Next.js 项目的方式是使用 create-next-app脚手架,你只需要运行: npx create-next-applatest&&am…

FinalShell 远程连接 Linux(Ubuntu)系统

Linux 系列教程: VMware 安装配置 Ubuntu(最新版、超详细)FinalShell 远程连接 Linux(Ubuntu)系统Ubuntu 系统安装 VS Code 并配置 C 环境 ➡️➡️➡️提出一个问题:为什么使用 FinalShell 连接&#xff0…

Python-VBA函数之旅-filter函数

目录 一、filter函数的常见应用场景: 二、filter函数的使用注意事项: 1、filter函数: 1-1、Python: 1-2、VBA: 2、相关文章: 个人主页:非风V非雨-CSDN博客 一、filter函数的常见应用…

FY-SA-20237·8-ElectricHealing

Translated from the Scientific American, July/August 2023 issue. Electric Healing (电疗) New bandage zaps and medicates chronic wounds 新型创可贴治疗慢性伤口 Paragraph 1 Some wounds won’t heal by themselves. 翻译:一些伤口不会自愈。 解释&…

phpMyadmin 设置显示完整内容

额外选项这里,默认部分内容改成完整内容 方案: 版本>4.5.4.1,修改文件:config.inc.php,添加一行代码: if ( !isset($_REQUEST[pftext])) $_REQUEST[pftext] F;

双向链表详解

目录 带头双向循环链表带头双向循环链表的实现带头双向循环链表的功能实现创造新节点LTNode* CreateLTNode(LTDataType x)代码 初始化链表LTNode*LTInit(LTNode* phead)代码 打印链表void LTPrint(LTNode* phead)代码 链表尾插void LTPushBack(LTNode* phead, LTDataType x)代码…

OpenHarmony 资源调度之内存管理源码分析

作者:张守忠 1 内存管理简介 内存管理部件位于全局资源调度管控子系统中,基于应用的生命周期状态,更新进程回收优先级列表,通过内存回收、查杀等手段管理系统内存,保障内存供给。 1.1 内存管理框架 内存管理部件主要…

韦东山FreeRTOS学习笔记————freertos工程创建

这里写目录标题 一、freertos.c程序结构二、创建任务函数1、动态创建2、静态创建 三、任务调用 一、freertos.c程序结构 1、头文件 2、宏定义、typedef定义… 3、全局变量定义 以下是静态任务的相关变量配置,相当于正点原子例程里的TASK1、TASK2…任务配置 以下…

微信小程序展示倒计时

html <view class"countdown"> <text>倒计时&#xff1a;</text> <text wx:for"{{countdown}}" wx:key"index">{{item}}</text> </view> ts data: {countdown: [], // 存放倒计时数组 targetTime:…

MSSQL 命令行操作说明 sql server 2022 命令行下进行配置管理

说明&#xff1a;本文的内容是因为我在导入Access2019的 *.accdb 格式的数据时&#xff0c;总是出错的背景下&#xff0c;不得已搜索和整理了一下&#xff0c;如何用命令行进行sql server 数据库和用户管理的方法&#xff0c;作为从Access2019 直接导出数据到sql server 数据库…

数据结构(六)----串

目录 1.串的定义 2.串的基本操作 3.串的存储结构 (1)串的定义 •顺序存储 •链式存储 (2)求串长 (3)求子串 (4)比较串的大小 (5)定位操作 4.字符串的模式匹配 (1)朴素模式匹配算法 (2)KMP算法 •求模式串中的next数组&#xff08;重点&#xff09; •练习&#…