用pytorch实现简易RNN
生活随笔
收集整理的這篇文章主要介紹了
用pytorch实现简易RNN
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1 導入庫函數
import torch import numpy as np import matplotlib.pyplot as plt2 設置超參數
TIME_STEP=10 INPUT_SIZE=1 HIDDEN_SIZE=32 LR=0.023? 定義RNN?
class RNN(torch.nn.Module):def __init__(self):super(RNN,self).__init__()self.rnn=torch.nn.RNN(input_size=INPUT_SIZE,hidden_size=HIDDEN_SIZE,num_layers=1,batch_first=True) #設置batch_first為True,那么輸入數據的維度為(batch_size,time_step,input_size) #如果不設置這個值,或者設置為False,那么輸入數據的維度為(time_step,batch_size,input_size)self.out=torch.nn.Linear(HIDDEN_SIZE,1)#將隱藏層輸出轉化為需要的輸出def forward(self,x,h_state):#因為在RNN中,下一個時間片隱藏層狀態的計算需要上一個時間片的隱藏層狀態,所以我們要一直傳遞這個h_state#x (batch_size,time_step,INPUT_SIZE)r_out,h_state=self.rnn(x,h_state)#h_state也要作為RNN的一個輸入和一個輸出#r_out:(batch_size,time_step,HIDDEN_SIZE)#h_state:(batch_size,time_step,HIDDEN_SIZE)outs=[]for time_step in range(r_out.size()[1]):outs.append(self.out(r_out[:,time_step,:]))#每一個要被self.out運算的元素[batch_size,1,HIDDEN_SIZE]#每個計算完,被append到outs的元素[batch_size,1,1]return torch.stack(outs,dim=1),h_state#返回的第一個元素[batch_size,time_step,1]#torch.stack函數的維度和axis不一樣,dim=1的意思是在第一個維度處疊加rnn=RNN() print(rnn) ''' RNN((rnn): RNN(1, 32, batch_first=True)(out): Linear(in_features=32, out_features=1, bias=True) ) '''或者foward函數也可以這么寫:
class RNN(torch.nn.Module):def __init__(self):super(RNN,self).__init__()self.rnn=torch.nn.RNN(input_size=INPUT_SIZE,hidden_size=HIDDEN_SIZE,num_layers=1,batch_first=True) #設置batch_first為True,那么輸入數據的維度為(batch,time_step,input_size) #如果不設置這個值,或者設置為False,那么輸入數據的維度為(time_step,batch,input_size)self.out=torch.nn.Linear(HIDDEN_SIZE,1)def forward(self,x,h_state):r_out,h_state=self.rnn(x,h_state)#在此之前的部分不動r_out=r_out.view(-1,HIDDEN_SIZE)out=self.out(r_out)out=out.view(-1,TIME_STEP,1)return(out,h_state)rnn=RNN() print(rnn)4 設置優化器和損失函數
optimizer=torch.optim.Adam(rnn.parameters(),lr=LR) loss_func=torch.nn.MSELoss()5 訓練RNN
我們這里希望用sin函數預測cos函數
h_state=Nonefor step in range(100):start=step*np.piend=(step+1)*np.pisteps=np.linspace(start,end,TIME_STEP,dtype=np.float32)#這里dtype這一部分一定要加,不然的話會報錯,RuntimeError: expected scalar type Double but found Floatx_np=np.sin(steps).reshape(1,TIME_STEP,INPUT_SIZE)y_np=np.cos(steps).reshape(1,TIME_STEP,1)#目標:用sin預測cosx=torch.from_numpy(x_np)y=torch.from_numpy(y_np)prediction,h_state=rnn(x,h_state)#每一組input,都對應了一個h_state和一個predictionh_state=h_state.data#將對應的h_state向后傳loss=loss_func(prediction,y)optimizer.zero_grad()#清空上一步的參與更新參數值loss.backward()#誤差反向傳播,計算參數更新值optimizer.step()#將參數更新值施加到rnn的parameters上if(step % 10==0):plt.plot(steps,prediction.data.numpy().flatten(),'g*')plt.plot(steps,y_np.flatten(),'r-')plt.show()6 實驗結果
一開始
最終
7 整體函數
import torch import numpy as np import matplotlib.pyplot as pltTIME_STEP=10 INPUT_SIZE=1 HIDDEN_SIZE=32 LR=0.02class RNN(torch.nn.Module):def __init__(self):super(RNN,self).__init__()self.rnn=torch.nn.RNN(input_size=INPUT_SIZE,hidden_size=HIDDEN_SIZE,num_layers=1,batch_first=True) #設置batch_first為True,那么輸入數據的維度為(batch_size,time_step,input_size) #如果不設置這個值,或者設置為False,那么輸入數據的維度為(time_step,batch_size,input_size)self.out=torch.nn.Linear(HIDDEN_SIZE,1)#將隱藏層輸出轉化為需要的輸出def forward(self,x,h_state):#因為在RNN中,下一個時間片隱藏層狀態的計算需要上一個時間片的隱藏層狀態,所以我們要一直傳遞這個h_state#x (batch_size,time_step,INPUT_SIZE)r_out,h_state=self.rnn(x,h_state)#h_state也要作為RNN的一個輸入和一個輸出#r_out:(batch_size,time_step,HIDDEN_SIZE)#h_state:(batch_size,time_step,HIDDEN_SIZE)outs=[]for time_step in range(r_out.size()[1]):outs.append(self.out(r_out[:,time_step,:]))#每一個要被self.out運算的元素[batch_size,1,HIDDEN_SIZE]#每個計算完,被append到outs的元素[batch_size,1,1]return torch.stack(outs,dim=1),h_state#返回的第一個元素[batch_size,time_step,1]#torch.stack函數的維度和axis不一樣,dim=1的意思是在第一個維度處疊加rnn=RNN() print(rnn) ''' RNN((rnn): RNN(1, 32, batch_first=True)(out): Linear(in_features=32, out_features=1, bias=True) ) '''optimizer=torch.optim.Adam(rnn.parameters(),lr=LR) loss_func=torch.nn.MSELoss()h_state=Nonefor step in range(100):start=step*np.piend=(step+1)*np.pisteps=np.linspace(start,end,TIME_STEP,dtype=np.float32)#這里dtype這一部分一定要加,不然的話會報錯,RuntimeError: expected scalar type Double but found Floatx_np=np.sin(steps).reshape(1,TIME_STEP,INPUT_SIZE)y_np=np.cos(steps).reshape(1,TIME_STEP,1)#目標:用sin預測cosx=torch.from_numpy(x_np)y=torch.from_numpy(y_np)prediction,h_state=rnn(x,h_state)#每一組input,都對應了一個h_state和一個predictionh_state=h_state.data#將對應的h_state向后傳loss=loss_func(prediction,y)optimizer.zero_grad()#清空上一步的參與更新參數值loss.backward()#誤差反向傳播,計算參數更新值optimizer.step()#將參數更新值施加到rnn的parameters上if(step % 10==0):plt.plot(steps,prediction.data.numpy().flatten(),'g*')plt.plot(steps,y_np.flatten(),'r-')plt.show()?
總結
以上是生活随笔為你收集整理的用pytorch实现简易RNN的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库笔记——数据模型
- 下一篇: 机器学习笔记 RNN初探 LSTM