<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
關鍵步驟主要分為資料準備和模型構建兩大部分,其中,
資料準備主要工作:
class LSTM(nn.Module):#注意Module首字母需要大寫 def __init__(self, input_size=1, hidden_layer_size=100, output_size=1): super().__init__() self.hidden_layer_size = hidden_layer_size # 建立LSTM層和linear層,LSTM層提取特徵,linear層用作最後的預測 # LSTM演演算法接受三個輸入:先前的隱藏狀態,先前的單元狀態和當前輸入。 self.lstm = nn.LSTM(input_size, hidden_layer_size) self.linear = nn.Linear(hidden_layer_size, output_size) #初始化隱含狀態及細胞狀態C,hidden_cell變數包含先前的隱藏狀態和單元狀態 self.hidden_cell = (torch.zeros(1, 1, self.hidden_layer_size), torch.zeros(1, 1, self.hidden_layer_size)) # 為什麼的第二個引數也是1 # 第二個引數代表的應該是batch_size吧 # 是因為之前對資料已經進行過切分了嗎????? def forward(self, input_seq): #lstm的輸出是當前時間步的隱藏狀態ht和單元狀態ct以及輸出lstm_out lstm_out, self.hidden_cell = self.lstm(input_seq.view(len(input_seq), 1, -1), self.hidden_cell) #按照lstm的格式修改input_seq的形狀,作為linear層的輸入 predictions = self.linear(lstm_out.view(len(input_seq), -1)) #返回predictions的最後一個元素 return predictions[-1]
定義好每層之後,最後還需要通過前向傳播的方式把這些串起來,這就涉及如何定義forward函數。
forward函數的任務需要把輸入層、網路層、輸出層連結起來,實現資訊的前向傳導。
forward該函數的引數一般為輸入資料,返回值是輸出資料。
#建立LSTM()類的物件,定義損失函數和優化器 model = LSTM() loss_function = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001)#建立優化器範例 print(model)
epochs = 150 for i in range(epochs): for seq, labels in train_inout_seq: #清除網路先前的梯度值 optimizer.zero_grad() #初始化隱藏層資料 model.hidden_cell = (torch.zeros(1, 1, model.hidden_layer_size), torch.zeros(1, 1, model.hidden_layer_size)) #範例化模型 y_pred = model(seq) #計算損失,反向傳播梯度以及更新模型引數 #訓練過程中,正向傳播生成網路的輸出,計算輸出和實際值之間的損失值 single_loss = loss_function(y_pred, labels) single_loss.backward()#呼叫backward()自動生成梯度 optimizer.step()#使用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}')
訓練模型時需要使模型處於訓練模式,即呼叫model.train()。
預設情況下梯度是累加的,需要手工把梯度初始化或者清零,呼叫optimizer.zero_grad()。
在訓練過程中正向傳播生成網路的輸出,計算輸出與實際值之間的損失值。呼叫loss.backward()自動生成反向傳播梯度,然後使用optimizer.step()執行優化器,把梯度傳播回每個網路。
實現梯度反向傳播的方法主要是複合函數的鏈式法則。Pytorch提供了自動反向傳播的功能,使用nn工具箱,無需自己編寫反向傳播,直接讓損失函數呼叫backward()即可。
反向傳播中,優化器十分重要,這類優化演演算法通過使用引數的梯度值更新引數。
fut_pred = 12 test_inputs = train_data_normalized[-train_window:].tolist()#首先列印出資料列表的最後12個值 print(test_inputs) #更改模型為測試或者驗證模式 model.eval()#把training屬性設定為false,使模型處於測試或驗證狀態 for i in range(fut_pred): seq = torch.FloatTensor(test_inputs[-train_window:]) with torch.no_grad(): model.hidden = (torch.zeros(1, 1, model.hidden_layer_size), torch.zeros(1, 1, model.hidden_layer_size)) test_inputs.append(model(seq).item()) #列印最後的12個預測值 print(test_inputs[fut_pred:]) #由於對訓練集資料進行了標準化,因此預測資料也是標準化了的 #需要將歸一化的預測值轉換為實際的預測值。通過inverse_transform實現 actual_predictions = scaler.inverse_transform(np.array(test_inputs[train_window:]).reshape(-1, 1)) print(actual_predictions)
全部程式碼如下:
import torch import torch.nn as nn import torch.nn.functional import seaborn as sns import numpy as np import pandas as pd import matplotlib.pyplot as plt """ 匯入資料 """ flight_data = sns.load_dataset("flights") print(flight_data.head()) print(flight_data.shape) #繪製每月乘客的出行頻率 fig_size = plt.rcParams['figure.figsize'] fig_size[0] = 15 fig_size[1] = 5 plt.rcParams['figure.figsize'] = fig_size plt.title('Month vs Passenger') plt.ylabel('Total Passengers') plt.xlabel('Months') plt.grid(True) plt.autoscale(axis='x',tight=True) plt.plot(flight_data['passengers']) plt.show() """ 資料預處理 """ flight_data.columns#顯示資料集中 列的資料型別 all_data = flight_data['passengers'].values.astype(float)#將passengers列的資料型別改為float #劃分測試集和訓練集 test_data_size = 12 train_data = all_data[:-test_data_size]#除了最後12個資料,其他全取 test_data = all_data[-test_data_size:]#取最後12個資料 print(len(train_data)) print(len(test_data)) #最大最小縮放器進行歸一化,減小誤差,注意,資料標準化只應用於訓練資料而不應用於測試資料 from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler(feature_range=(-1, 1)) train_data_normalized = scaler.fit_transform(train_data.reshape(-1, 1)) #檢視歸一化之後的前5條資料和後5條資料 print(train_data_normalized[:5]) print(train_data_normalized[-5:]) #將資料集轉換為tensor,因為PyTorch模型是使用tensor進行訓練的,並將訓練資料轉換為輸入序列和相應的標籤 train_data_normalized = torch.FloatTensor(train_data_normalized).view(-1) #view相當於numpy中的resize,引數代表陣列不同維的維度; #引數為-1表示,這個維的維度由機器自行推斷,如果沒有-1,那麼view中的所有引數就要和tensor中的元素總個數一致 #定義create_inout_sequences函數,接收原始輸入資料,並返回一個元組列表。 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]#預測time_step之後的第一個數值 inout_seq.append((train_seq, train_label))#inout_seq內的資料不斷更新,但是總量只有tw+1個 return inout_seq train_window = 12#設定訓練輸入的序列長度為12,類似於time_step = 12 train_inout_seq = create_inout_sequences(train_data_normalized, train_window) print(train_inout_seq[:5])#產看資料集改造結果 """ 注意: create_inout_sequences返回的元組列表由一個個序列組成, 每一個序列有13個資料,分別是設定的12個資料(train_window)+ 第13個資料(label) 第一個序列由前12個資料組成,第13個資料是第一個序列的標籤。 同樣,第二個序列從第二個資料開始,到第13個資料結束,而第14個資料是第二個序列的標籤,依此類推。 """ """ 建立LSTM模型 引數說明: 1、input_size:對應的及特徵數量,此案例中為1,即passengers 2、output_size:預測變數的個數,及資料標籤的個數 2、hidden_layer_size:隱藏層的特徵數,也就是隱藏層的神經元個數 """ class LSTM(nn.Module):#注意Module首字母需要大寫 def __init__(self, input_size=1, hidden_layer_size=100, output_size=1): super().__init__() self.hidden_layer_size = hidden_layer_size # 建立LSTM層和linear層,LSTM層提取特徵,linear層用作最後的預測 ##LSTM演演算法接受三個輸入:先前的隱藏狀態,先前的單元狀態和當前輸入。 self.lstm = nn.LSTM(input_size, hidden_layer_size) self.linear = nn.Linear(hidden_layer_size, output_size) #初始化隱含狀態及細胞狀態C,hidden_cell變數包含先前的隱藏狀態和單元狀態 self.hidden_cell = (torch.zeros(1, 1, self.hidden_layer_size), torch.zeros(1, 1, self.hidden_layer_size)) # 為什麼的第二個引數也是1 # 第二個引數代表的應該是batch_size吧 # 是因為之前對資料已經進行過切分了嗎????? def forward(self, input_seq): lstm_out, self.hidden_cell = self.lstm(input_seq.view(len(input_seq), 1, -1), self.hidden_cell) #lstm的輸出是當前時間步的隱藏狀態ht和單元狀態ct以及輸出lstm_out #按照lstm的格式修改input_seq的形狀,作為linear層的輸入 predictions = self.linear(lstm_out.view(len(input_seq), -1)) return predictions[-1]#返回predictions的最後一個元素 """ forward方法:LSTM層的輸入與輸出:out, (ht,Ct)=lstm(input,(h0,C0)),其中 一、輸入格式:lstm(input,(h0, C0)) 1、input為(seq_len,batch,input_size)格式的tensor,seq_len即為time_step 2、h0為(num_layers * num_directions, batch, hidden_size)格式的tensor,隱藏狀態的初始狀態 3、C0為(seq_len, batch, input_size)格式的tensor,細胞初始狀態 二、輸出格式:output,(ht,Ct) 1、output為(seq_len, batch, num_directions*hidden_size)格式的tensor,包含輸出特徵h_t(源於LSTM每個t的最後一層) 2、ht為(num_layers * num_directions, batch, hidden_size)格式的tensor, 3、Ct為(num_layers * num_directions, batch, hidden_size)格式的tensor, """ #建立LSTM()類的物件,定義損失函數和優化器 model = LSTM() loss_function = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001)#建立優化器範例 print(model) """ 模型訓練 batch-size是指1次迭代所使用的樣本量; epoch是指把所有訓練資料完整的過一遍; 由於預設情況下權重是在PyTorch神經網路中隨機初始化的,因此可能會獲得不同的值。 """ epochs = 150 for i in range(epochs): for seq, labels in train_inout_seq: #清除網路先前的梯度值 optimizer.zero_grad()#訓練模型時需要使模型處於訓練模式,即呼叫model.train()。預設情況下梯度是累加的,需要手工把梯度初始化或者清零,呼叫optimizer.zero_grad() #初始化隱藏層資料 model.hidden_cell = (torch.zeros(1, 1, model.hidden_layer_size), torch.zeros(1, 1, model.hidden_layer_size)) #範例化模型 y_pred = model(seq) #計算損失,反向傳播梯度以及更新模型引數 single_loss = loss_function(y_pred, labels)#訓練過程中,正向傳播生成網路的輸出,計算輸出和實際值之間的損失值 single_loss.backward()#呼叫loss.backward()自動生成梯度, optimizer.step()#使用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}') """ 預測 注意,test_input中包含12個資料, 在for迴圈中,12個資料將用於對測試集的第一個資料進行預測,然後將預測值附加到test_inputs列表中。 在第二次迭代中,最後12個資料將再次用作輸入,並進行新的預測,然後 將第二次預測的新值再次新增到列表中。 由於測試集中有12個元素,因此該回圈將執行12次。 迴圈結束後,test_inputs列表將包含24個資料,其中,最後12個資料將是測試集的預測值。 """ fut_pred = 12 test_inputs = train_data_normalized[-train_window:].tolist()#首先列印出資料列表的最後12個值 print(test_inputs) #更改模型為測試或者驗證模式 model.eval()#把training屬性設定為false,使模型處於測試或驗證狀態 for i in range(fut_pred): seq = torch.FloatTensor(test_inputs[-train_window:]) with torch.no_grad(): model.hidden = (torch.zeros(1, 1, model.hidden_layer_size), torch.zeros(1, 1, model.hidden_layer_size)) test_inputs.append(model(seq).item()) #列印最後的12個預測值 print(test_inputs[fut_pred:]) #由於對訓練集資料進行了標準化,因此預測資料也是標準化了的 #需要將歸一化的預測值轉換為實際的預測值。通過inverse_transform實現 actual_predictions = scaler.inverse_transform(np.array(test_inputs[train_window:]).reshape(-1, 1)) print(actual_predictions) """ 根據實際值,繪製預測值 """ x = np.arange(132, 132+fut_pred, 1) plt.title('Month vs Passenger') plt.ylabel('Total Passengers') plt.xlabel('Months') plt.grid(True) plt.autoscale(axis='x', tight=True) plt.plot(flight_data['passengers']) plt.plot(x, actual_predictions) plt.show() #繪製最近12個月的實際和預測乘客數量,以更大的尺度觀測資料 plt.title('Month vs Passenger') plt.ylabel('Total Passengers') plt.xlabel('Months') plt.grid(True) plt.autoscale(axis='x', tight=True) plt.plot(flight_data['passengers'][-train_window:]) plt.plot(x, actual_predictions) plt.show()
到此這篇關於Pytorch實現LSTM案例總結學習的文章就介紹到這了,更多相關Pytorch實現LSTM內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45