0
点赞
收藏
分享

微信扫一扫

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(), # 将载入进来的数据变成Tensor
download = True) # 是否下载数据
test_dataset = datasets.MNIST(root = './data/', # 载入的数据存放的位置
train = False, # 载入测试集数据
transform = transforms.ToTensor(), # 将载入进来的数据变成Tensor
download = 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)
# softmax
self.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)
# 梯度清0
optimizer.zero_grad()
# 计算梯度
loss.backward()
# 修改权值
optimizer.step()

def test():
model.eval()

# 计算训练集准确率
correct = 0
for 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 = 0
for 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

举报

相关推荐

0 条评论