PyTorch基础(part8)--LSTM
生活随笔
收集整理的這篇文章主要介紹了
PyTorch基础(part8)--LSTM
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
學習筆記,僅供參考,有錯必糾
文章目錄
- 代碼
- 問題分析
- 初始設置
- 導包
- 載入數據
- 模型
- 模型持久化
- 模型的保存
- 模型的載入
代碼
問題分析
我們將圖片看成是一種序列問題,比如將28*28的圖像中的每行看成一維度為28的一條數據,那么28行則可以看成按照時間順序排列的28條數據.
初始設置
# 支持多行輸出 from IPython.core.interactiveshell import InteractiveShell InteractiveShell.ast_node_interactivity = 'all' #默認為'last'導包
# 導入常用的包 import numpy as np from torch import nn,optim from torch.autograd import Variable from torchvision import datasets, transforms from torch.utils.data import DataLoader import torch載入數據
# 載入數據 train_dataset = datasets.MNIST(root = './data/', # 載入的數據存放的位置train = True, # 載入訓練集數據transform = transforms.ToTensor(), # 將載入進來的數據變成Tensordownload = True) # 是否下載數據 test_dataset = datasets.MNIST(root = './data/', # 載入的數據存放的位置train = False, # 載入測試集數據transform = transforms.ToTensor(), # 將載入進來的數據變成Tensordownload = True) # 是否下載數據 # 批次大小 batch_size = 64# 裝載訓練集 train_loader = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)# 裝載訓練集 test_loader = DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=True)模型
這里我們使用具有多層網絡結構的模型,并加入Dropout操作.
# 定義網絡結構 class LSTM(nn.Module):def __init__(self):super(LSTM, self).__init__()# 定義LSTM層(相當于隱藏層)# input_size 表示數據輸入特征的大小# hidden_size 表示LSTM模塊的數量# num_layers 表示隱藏層的層數, 一般設置1-3層就可以了# batch_first 用于設置數據格式,默認:input(seq_len, batch, feature)# 當batch_first = True,則input和output數據的格式變為:(batch, seq_len, feature)self.lstm = torch.nn.LSTM(input_size = 28,hidden_size = 64,num_layers = 1,batch_first = True)# 定義全連接層# 這里的in_features=64,是因為LSTM層中hidden_size = 64,每一個LSTM塊都會輸出一個值.self.out = torch.nn.Linear(in_features=64, out_features=10)# softmaxself.softmax = torch.nn.Softmax(dim = 1)def forward(self, x):# 我們要將數據reshape成3維數據(batch, seq_len, feature)# seq_len表示序列長度# feature:表示每次傳入數據的個數x = x.view(-1, 28, 28)# output: 包含每個批次的每個序列的每個LSTM單元的輸出結果,是3維[batch, seq_len, hidden_size]# 雖然LSTM的batch_first = True,但是h_n和c_n的第一個維度還是seq_len# h_n: [num_layers, batch, hidden_size] 只包含最后一個序列的輸出結果# c_n: [num_layers, batch, hidden_size] 只包含最后一個序列的輸出結果output, (h_n, c_n) = self.lstm(x)# 如果這里有很多隱藏層,那么我們只需要最后一層的輸出結果output_in_last_timestep = h_n[-1, :, :]x = self.out(output_in_last_timestep)x = self.softmax(x)return x LR = 0.0003 # 定義模型 model = LSTM() # 定義代價函數為交叉熵代價函數 mse_loss = nn.CrossEntropyLoss() # 定義優化器Adam optimizer = optim.Adam(model.parameters(), LR)在自定義訓練和測試函數中,我們分別增加兩個方法,model.train()和model.eval() ,這model.train()方法可以使訓練集中的Dropout在訓練模型時發揮作用,而model.eval()則可以使模型在測試過程中不工作.
def train():model.train()for i,data in enumerate(train_loader):# 獲得一個批次的數據和標簽inputs, labels = data# 獲得模型預測結果(64,10)out = model(inputs)# 計算loss,交叉熵代價函數out(batch,C), labels(batch)loss = mse_loss(out, labels)# 梯度清0optimizer.zero_grad()# 計算梯度loss.backward()# 修改權值optimizer.step()def test():model.eval()# 計算訓練集準確率correct = 0for i,data in enumerate(train_loader):# 獲得一個批次的數據和標簽inputs, labels = data# 獲得模型預測結果(64,10)out = model(inputs)# 獲得最大值,以及最大值所在的位置_, predicted = torch.max(out, 1)# 預測正確的數量correct += (predicted == labels).sum()print("Train acc:{0}".format(correct.item()/len(train_dataset)))# 計算測試集準確率correct = 0for i,data in enumerate(test_loader):# 獲得一個批次的數據和標簽inputs, labels = data# 獲得模型預測結果(64,10)out = model(inputs)# 獲得最大值,以及最大值所在的位置_, predicted = torch.max(out, 1)# 預測正確的數量correct += (predicted == labels).sum()print("Test acc:{0}".format(correct.item()/len(test_dataset))) for epoch in range(5):print('epoch:',epoch)train()test() epoch: 0 Train acc:0.8103333333333333 Test acc:0.8137 epoch: 1 Train acc:0.8489666666666666 Test acc:0.8494 epoch: 2 Train acc:0.8629166666666667 Test acc:0.8616 epoch: 3 Train acc:0.935 Test acc:0.9318 epoch: 4 Train acc:0.94415 Test acc:0.9433模型持久化
模型的保存
torch.save(model.state_dict(), "output/my_model.pth")模型的載入
需要注意的是,模型載入的是對應算法已經訓練好的參數.
model_new = LSTM() # 載入模型 model_new.load_state_dict(torch.load("output/my_model.pth")) <All keys matched successfully> # 載入模型后就可以直接測試了 test() Train acc:0.94415 Test acc:0.9433總結
以上是生活随笔為你收集整理的PyTorch基础(part8)--LSTM的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PyTorch基础(part7)--CN
- 下一篇: [css]画圆形标签