生活随笔
收集整理的這篇文章主要介紹了
pytorch搭建LSTM神经网络预测电力负荷
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
import torch
import torch.nn as nn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 由于訓(xùn)練數(shù)據(jù)存在相差較大的,因此使用min/max尺度變換對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行歸一化
# 注意只對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行歸一化,為了防止有些信息從訓(xùn)練數(shù)據(jù)泄露到的測(cè)試數(shù)據(jù)
from sklearn.preprocessing import MinMaxScaler
flight_data = pd.read_csv(r"C:\Users\Administrator\Desktop\填補(bǔ)缺失值.csv")
fig_size = plt.rcParams["figure.figsize"]
fig_size[0] = 15
fig_size[1] = 5
plt.rcParams["figure.figsize"] = fig_size
plt.title('power vs day')
plt.ylabel('power')
plt.xlabel('day')
plt.grid(True)
plt.autoscale(axis='x',tight=True)
plt.plot(flight_data['power'])
plt.show()
#提取數(shù)據(jù)
all_data = flight_data['power'].values.astype(float)
print(all_data)
#將數(shù)據(jù)區(qū)分為訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)
test_data_size = 960
train_data = all_data[:-test_data_size]
test_data = all_data[-test_data_size:]# 由于訓(xùn)練數(shù)據(jù)存在相差較大的,因此使用min/max尺度變換對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行歸一化
# 注意只對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行歸一化,為了防止有些信息從訓(xùn)練數(shù)據(jù)泄露到的測(cè)試數(shù)據(jù)scaler = MinMaxScaler(feature_range=(-1, 1))
train_data_normalized = scaler.fit_transform(train_data.reshape(-1, 1))print(train_data_normalized)# 將數(shù)據(jù)轉(zhuǎn)換為張量
train_data_normalized = torch.FloatTensor(train_data_normalized).view(-1)def create_inout_sequences(input_data, tw):inout_seq = []L = len(input_data)for i in range(L-tw):train_seq = input_data[i:i+tw]train_label = input_data[i+tw:i+tw+1]inout_seq.append((train_seq ,train_label))return inout_seqtrain_window =5
train_inout_seq = create_inout_sequences(train_data_normalized, train_window)#定義LSTM模型
class LSTM(nn.Module):def __init__(self, input_size=1, hidden_size=55, output_size=1):super().__init__()self.hidden_size = hidden_size# 定義lstm 層self.lstm = nn.LSTM(input_size, hidden_size)# 定義線性層,即在LSTM的的輸出后面再加一個(gè)線性層self.linear = nn.Linear(hidden_size, output_size)# input_seq參數(shù)表示輸入sequencedef forward(self, input_seq):# lstm默認(rèn)的輸入X是(sequence_legth,bacth_size,input_size)lstm_out,\self.hidden_cell = self.lstm(input_seq.view(len(input_seq), 1, -1), self.hidden_cell)# lstm_out的默認(rèn)大小是(sequence_legth,bacth_size,hidden_size)# 轉(zhuǎn)化之后lstm_out的大小是(sequence_legth, bacth_size*hidden_size)predictions = self.linear(lstm_out.view(len(input_seq), -1))# 由于bacth_size = 1, 可知predictions 的維度為(sequence_legth, output_size)# [-1] 表示的是取最后一個(gè)時(shí)間步長(zhǎng)對(duì)應(yīng)的輸出return predictions[-1]# 模型實(shí)例化并定義損失函數(shù)和優(yōu)化函數(shù)model = LSTM()loss_function = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
print(model)epochs = 1for i in range(epochs):for seq, labels in train_inout_seq:optimizer.zero_grad()model.hidden_cell = (torch.zeros(1, 1, model.hidden_size),torch.zeros(1, 1, model.hidden_size))y_pred = model(seq)single_loss = loss_function(y_pred, labels)single_loss.backward()optimizer.step()#if i%25 == 1:print(f'epoch: {i:3} loss: {single_loss.item():10.8f}')print(f'epoch: {i:3} loss: {single_loss.item():10.10f}')# 以train data的最后12個(gè)數(shù)據(jù)進(jìn)行預(yù)測(cè)
fut_pred = 960
test_inputs = train_data_normalized[-train_window:].tolist()
print(test_inputs)model.eval()
# 基于最后12個(gè)數(shù)據(jù)來預(yù)測(cè)第133個(gè)數(shù)據(jù),并基于新的預(yù)測(cè)數(shù)據(jù)進(jìn)一步預(yù)測(cè)
# 134-144 的數(shù)據(jù)
for i in range(fut_pred):seq = torch.FloatTensor(test_inputs[-train_window:])# 模型評(píng)價(jià)時(shí)候關(guān)閉梯度下降with torch.no_grad():model.hidden = (torch.zeros(1, 1, model.hidden_size),torch.zeros(1, 1, model.hidden_size))test_inputs.append(model(seq).item())test_inputs[fut_pred:]actual_predictions = scaler.inverse_transform(np.array(test_inputs[train_window:] ).reshape(-1, 1))
print(actual_predictions)
# 繪制圖像查看預(yù)測(cè)的[133-144]的數(shù)據(jù)和實(shí)際的133-144 之間的數(shù)據(jù)差別
x = np.arange(127584,128544, 1)
plt.title('power vs day')
plt.ylabel('power')
plt.grid(True)
plt.autoscale(axis='x', tight=True)
plt.plot(flight_data['power'])
plt.plot(x,actual_predictions)
plt.show()
話不多說,先上代碼,這個(gè)LSTM網(wǎng)絡(luò)是基于之前一個(gè)博主的,然后我再根據(jù)自己的比賽需要改進(jìn)了一部分,這篇文章算是記錄一下自己第一次搭建神經(jīng)網(wǎng)絡(luò)。
1:第一個(gè)就是數(shù)據(jù)的讀取 建議使用pandas來讀取數(shù)據(jù) 值得注意的是路徑名前要有一個(gè)r用于轉(zhuǎn)義,否則系統(tǒng)會(huì)報(bào)錯(cuò),還有EXCEL文件要轉(zhuǎn)化成CSV格式
2:第二個(gè)就是對(duì)于原始數(shù)據(jù)的可視化,python作為解釋性語言相信大家也看的明白那些plt...怎么干嘛
3:因?yàn)閿?shù)據(jù)是一個(gè)時(shí)間序列,所以我們先提取其中的值部分,先忽略時(shí)間部分
4:將數(shù)據(jù)集劃分為訓(xùn)練集和測(cè)試集,比例一般在4:1左右
5:數(shù)據(jù)的歸一化
from sklearn.preprocessing import MinMaxScaler使用庫(kù)函數(shù) 將值變化到-1到1之間 這樣便于在訓(xùn)練的時(shí)候快速收斂 不然計(jì)算時(shí)間會(huì)比較久
還有就是一些參數(shù)的設(shè)定 比如train_window hidden_size epoch fut_pred等等參數(shù)的設(shè)置 里面還有一些LSTM的細(xì)節(jié) 感興趣的可以多了解一下他的原理
最后就是自己改預(yù)測(cè)范圍 看你想要的預(yù)測(cè)是多
少? 當(dāng)然原來的博主里面沒有反歸一化? 我們要記得反歸一化 不然預(yù)測(cè)的數(shù)據(jù)還是-1到1
actual_predictions = scaler.inverse_transform(np.array(test_inputs[train_window:] ).reshape(-1, 1))
第一次寫 大概就是記錄一下這些時(shí)間為數(shù)模而準(zhǔn)備的一些東西 還有很多不足 希望大家一起進(jìn)步
總結(jié)
以上是生活随笔為你收集整理的pytorch搭建LSTM神经网络预测电力负荷的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。