利用LSTM时序神经网络对主蒸汽流量的预测

利用LSTM时序神经网络对主蒸汽流量的预测

1.数据集介绍

训练数据是一个9列(含有9个特征量),包括炉膛温度,炉膛压力等数据,label数据是主蒸汽流量,其中9个特征量进行了归一化处理,使用的是sklearn里的 StandardScaler。导入的库和包,如下所示:

import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
import numpy as np
import torch
from torch import nn
import pandas as pd
from tqdm import tqdm
from tqdm.std import trange
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import QuantileTransformer
import seaborn as sns
from sklearn.metrics import r2_score
 
DAYS_FOR_TRAIN = 5
EPOCHS = 200
#调参日记
#(1200 trainloss=0.054  
#(2400 不加学习率降低 效果可以   R20.76
#(3400不加学习率降低多加入线性层 R20.66 #加激活函数
#(4400 不加学习率降低多加入线性层  不加激活函数 层数 64  R2-800?
#(5400 加入学习率降低  加入多层学习率下降效果不好
#(6400 加入梯级学习率 R2 0.7656 
#(7100 加入梯级学习率 0.78 将hidden_size = 10变为
#(8300  用Quantile归一化 0.84  400 0.79 300步效果好
#(9100  LR=0.05  Quantile  MinMaxscaler  0.86
#(10)测试8502s模型

2.数据训练

class LSTM_Regression(nn.Module):
    def __init__(self, input_size, hidden_size, output_size=1, num_layers=2):
        super().__init__()
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers)       
        self.fc = nn.Linear(hidden_size, output_size)
    def forward(self, _x, h_state,c_state):
        x, (h_state,c_state) = self.lstm(_x , (h_state,c_state))  # _x is input, size (seq_len, batch, input_size)
        s, b, h = x.shape  # x is output, size (seq_len, batch, hidden_size)
        x = x.view(s * b, h)
        x = self.fc(x)
        x = x.view(s, b, -1)  # 把形状改回来
        return x,h_state
    def InitHidden(self):
        h_state=torch.zeros(2, 1, 10)
        c_state=torch.zeros(2, 1, 10)# hidden_size =16
#       h_state = torch.randn(2, 2, 8)#初始化 hidden_size=8
        return h_state,c_state
def create_dataset(dataX,dataY, days_for_train=5) -> (np.array, np.array):
    dataset_x, dataset_y = [], []
    for i in range(len(dataX) - days_for_train):
        _x = dataX[i:(i + days_for_train)]
        dataset_x.append(_x)
        dataset_y.append(dataY[i + days_for_train])
    return (np.array(dataset_x), np.array(dataset_y))

随后开始训练:

if __name__ == '__main__':
    train = pd.read_csv('./loader_data2.csv')
    train_data = np.array(train.loc[:, 'sep_rst':'sep_sobelsum'], dtype=np.float32) # 转化为numpy数据
    label_train_data = np.array(train.sep_sobelart, dtype=np.float32)
    scaler = QuantileTransformer() #新的归一化方法
    #scaler = StandardScaler()   #Standardscaler的归一化方法
    train_data = scaler.fit_transform(train_data)
#   label_train_data = scaler.fit_transform(label_train_data)
    scaler_label = StandardScaler()  #Standardscaler的归一化方法
#   scaler_label = MinMaxScaler(feature_range=(0, 1))  # minmax归一化
    label_train_data = scaler_label.fit_transform(label_train_data.reshape(-1,1))
    #train_data = scaler.fit_transform(train_data)
    # 数据集序列化,进行标签分离
    dataset_x, dataset_y = create_dataset(train_data,label_train_data,DAYS_FOR_TRAIN)
    # 划分训练集和测试集,80%作为训练集,20%作为测试集
    train_size = int(len(dataset_x) * 0.8)
    train_x = dataset_x[:train_size]
    train_y = dataset_y[:train_size]
    test_x = dataset_x[train_size:]
    test_y = dataset_y[train_size:]
    # 改变数据集形状,RNN 读入的数据维度是 (seq_size, batch_size, feature_size)
    train_x = train_x.reshape(-1, 1, train_x.shape[2]*train_x.shape[1])
    train_y = train_y.reshape(-1, 1, 1)
    # 数据集转为pytorch的tensor对象
    train_x = torch.from_numpy(train_x)
    train_y = torch.from_numpy(train_y)
    # train model
    netdim = train_x.shape[2]*train_x.shape[1]
    model = LSTM_Regression(netdim,hidden_size=10,output_size=1, num_layers=2)  # 网络初始化
    h_state,c_state = model.InitHidden()
    loss_function = nn.MSELoss()  # 损失函数
    optimizer = torch.optim.Adam(model.parameters(), lr=0.01)  # 优化器 Adam 0.05加学习率降低
    #scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.9)  #log学习率下降
    #scheduler= torch.optim.lr_scheduler.StepLR(optimizer, step_size=200, gamma=0.3) #有序学习率下降
    #scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer,milestones=[200,250], gamma=0.1)  #多步学习率下降
    for step in trange(EPOCHS):
        out,h_state = model(train_x,h_state,c_state)
        loss = loss_function(out, train_y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        h_state = h_state.detach()
        #scheduler.step()
        if step % 10 == 0:
            print('Epoch: {}, Loss:{:.5f}'.format(step, loss.item()))
    #torch.save(model.state_dict(), 'model_twosecond_test.pkl')  # 用以保存2s的模型
    # predict
    model = model.eval()  # 转换成测试模式
    # model.load_state_dict(torch.load('model_params.pkl'))  # 读取参数
    # 使用全部数据集dataset_x,模型的输出长度会比dataset_x少 DAYS_FOR_TRAIN
    dataset_x = dataset_x.reshape(-1, 1, train_x.shape[2]*train_x.shape[1])  # (seq_size, batch_size, feature_size)
    dataset_x = torch.from_numpy(dataset_x)  # 转为pytorch的tensor对象
    pred_y,_ = model(dataset_x,h_state,c_state)  # 全量数据集的模型输出 (seq_size, batch_size, output_size)
    pred_y = pred_y.view(-1).data.numpy()

3.模型预测

 # 对标准化数据进行还原
actual_pred_y = scaler_label.inverse_transform(pred_y.reshape(-1,1))
actual_pred_y = actual_pred_y.reshape(-1, 1).flatten()
test_y = scaler_label.inverse_transform(test_y.reshape(-1, 1))
test_y = test_y.reshape(-1, 1).flatten()
actual_pred_y = actual_pred_y[-len(test_y):]
test_y = test_y.reshape(-1, 1)
assert len(actual_pred_y) == len(test_y)
#(1)学习率 0.01可以预测趋势  0.9/0.1 测试集分割
#(2)学习率
import matplotlib.pyplot as plt
# 初始结果 - 预测结果
plt.plot(test_y, 'b', label='real')
plt.plot(actual_pred_y, 'r', label='prediction')
plt.legend(loc='best')
plt.savefig('result.png', format='png', dpi=200)
plt.show()

训练效果还不错,如下图所示!
利用LSTM时序神经网络对主蒸汽流量的预测_第1张图片
评估指标1——散点图:

import seaborn as sns
sns.scatterplot(df["jy"], df["jy_"])
#plt.plot(x,df["jy_"])
#plt.plot(x,df["jy"])
sns.lineplot(np.linspace(50,80, 100),np.linspace(50,80, 100))

评估指标2:——R2决定系数:

from sklearn.metrics import r2_score
loss_sss=r2_score(test_y,actual_pred_y)
print(loss_sss)        #R2决定系数

你可能感兴趣的:(机器学习,深度学习)