基于pytorch实现RNN和LSTM对手写数字集分类的完整实例
Posted Icy Hunter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于pytorch实现RNN和LSTM对手写数字集分类的完整实例相关的知识,希望对你有一定的参考价值。
RNN
# coding: utf-8
import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torchvision
import numpy as np
import matplotlib.pyplot as plt
trainsets = datasets.MNIST(root="./data", train=True, download=True, transform=transforms.ToTensor())
testsets = datasets.MNIST(root="./data", train=False, transform=transforms.ToTensor())
class_names = trainsets.classes
BATCH_SIZE = 32 # 每批读取的数据大小
EPOCHS = 10 # 训练10轮
train_loader = torch.utils.data.DataLoader(dataset=trainsets, batch_size=BATCH_SIZE, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=testsets, batch_size=BATCH_SIZE, shuffle=True)
# 查看一批batch的数据
images, labels = next(iter(test_loader))
print(images.shape)
print(labels.shape)
def imshow(inp, title=None):
inp = inp.numpy().transpose((1, 2, 0))
mean = np.array([0.485, 0.456, 0.406])
std = np.array([0.229, 0.224, 0.225])
inp = std * inp + mean
inp = np.clip(inp, 0, 1)
plt.imshow(inp)
if title is not None:
plt.title(title)
plt.pause(0.001)
plt.show()
# 网格显示
out = torchvision.utils.make_grid(images)
imshow(out)
class RNN_Model(nn.Module):
def __init__(self, input_dim, hidden_dim, layer_dim, output_dim):
super(RNN_Model, self).__init__()
self.hidden_dim = hidden_dim
self.layer_dim = layer_dim
self.rnn = nn.RNN(input_dim, hidden_dim, layer_dim, batch_first=True, nonlinearity='relu')
# 全连接层
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
# layer_dim, batch_size, hidden_dim
h0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_().to(device)
# 分离隐藏状态,避免梯度爆炸
out, hn = self.rnn(x, h0.detach())
out = self.fc(out[:, -1, ])
return out
input_dim = 28 # 输入维度
hidden_dim = 100 # 隐层的维度
layer_dim = 2 # 2层RNN
output_dim = 10 # 输出维度
model = RNN_Model(input_dim, hidden_dim, layer_dim, output_dim)
device = torch.device("cuda:0" if torch.cuda.is_available() else 'cpu')
# 损失函数
criterion = nn.CrossEntropyLoss()
# 优化器
learning_rate = 0.01
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
# 模型参数
l = len(list(model.parameters()))
for i in range(l):
print("参数:%d" % (i + 1))
print(list((model.parameters()))[i].size())
# 模型训练
sequence_dim = 28 # 序列长度
loss_list = []
accuracy_list = []
iteration_list = [] # 迭代次数
iter = 0
for epoch in range(EPOCHS):
for i, (images, labels) in enumerate(train_loader):
model.train()
# 一个batch的数据转换为RNN的输入维度
images = images.view(-1, sequence_dim, input_dim).requires_grad_().to(device)
labels = labels.to(device)
optimizer.zero_grad()
# 前向传播
outputs = model(images)
# 计算损失
loss = criterion(outputs, labels)
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
# 计数器加1
iter += 1
# 模型验证
if iter % 500 == 0:
model.eval() # 声明
# 计算验证的accuracy
correct = 0.0
total = 0.0
# 迭代测试集,获取数据、预测
for images, labels in test_loader:
images = images.view(-1, sequence_dim, input_dim).to(device)
# 模型预测
outputs = model(images)
# 获取预测概率最大值的下标
predict = torch.max(outputs.data, 1)[1]
# 统计测试集的大小
total += labels.size(0)
# 统计判断预测正确的数量
if torch.cuda.is_available():
correct += (predict.gpu() == labels.gpu()).sum()
else:
correct += (predict == labels).sum()
# 计算accuracy
accuracy = correct / total * 100
loss_list.append(loss.data)
accuracy_list.append(accuracy)
iteration_list.append(iter)
# 打印信息
print("loos:, Loss:, Accuracy:".format(iter, loss.item(), accuracy))
plt.plot(iteration_list, loss_list)
plt.xlabel("Number of Iteration")
plt.ylabel("Loss")
plt.title("RNN")
plt.show()
plt.plot(iteration_list, accuracy_list, color='r')
plt.xlabel("Number of iteration")
plt.ylabel("Accuracy")
plt.title("RNN")
plt.show()
LSTM
# coding: utf-8
import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import matplotlib.pyplot as plt
input_dim = 28 # 输入维度
hidden_dim = 100 # 隐层的维度
layer_dim = 1 # 1层LSTM
output_dim = 10 # 输出维度
BATCH_SIZE = 32 # 每批读取的
EPOCHS = 10 # 训练10轮
trainsets = datasets.MNIST(root="./data", train=True, download=True, transform=transforms.ToTensor())
testsets = datasets.MNIST(root="./data", train=False, transform=transforms.ToTensor())
train_loader = torch.utils.data.DataLoader(dataset=trainsets, batch_size=BATCH_SIZE, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=testsets, batch_size=BATCH_SIZE, shuffle=True)
class LSTM_Model(nn.Module):
def __init__(self, input_dim, hidden_dim, layer_dim, output_dim):
super(LSTM_Model, self).__init__()
self.hidden_dim = hidden_dim
self.layer_dim = layer_dim
self.lstm = nn.LSTM(input_dim, hidden_dim, layer_dim, batch_first=True)
# 全连接层
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
# layer_dim, batch_size, hidden_dim
print("x", x.shape)
print(x.size(0))
h0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_().to(device)
# 初始化cell, state
c0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_().to(device)
# 分离隐藏状态,避免梯度爆炸
out, (hn, cn) = self.lstm(x, (h0.detach(), c0.detach()))
print(out.shape)
print(out[:, -1].shape)
out = self.fc(out[:, -1])
print("out-----", out.shape)
return out
model = LSTM_Model(input_dim, hidden_dim, layer_dim, output_dim)
device = torch.device("cuda:0" if torch.cuda.is_available() else 'cpu')
# 损失函数
criterion = nn.CrossEntropyLoss()
# 优化器
learning_rate = 0.01
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
# 模型训练
sequence_dim = 28 # 序列长度
loss_list = []
accuracy_list = []
iteration_list = [] # 迭代次数
iter = 0
for epoch in range(EPOCHS):
for i, (images, labels) in enumerate(train_loader):
model.train()
# 一个batch的数据转换为RNN的输入维度
images = images.view(-1, sequence_dim, input_dim).requires_grad_().to(device)
labels = labels.to(device)
optimizer.zero_grad()
# 前向传播
print(images.shape)
print(labels.shape)
outputs = model(images)
# 计算损失
loss = criterion(outputs, labels)
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
# 计数器加1
iter += 1
# 模型验证
if iter % 500 == 0:
model.eval() # 声明
# 计算验证的accuracy
correct = 0.0
total = 0.0
# 迭代测试集,获取数据、预测
for images, labels in test_loader:
images = images.view(-1, sequence_dim, input_dim).to(device)
# 模型预测
outputs = model(images)
# 获取预测概率最大值的下标
predict = torch.max(outputs.data, 1)[1]
# 统计测试集的大小
total += labels.size(0)
# 统计判断预测正确的数量
if torch.cuda.is_available():
correct += (predict.gpu() == labels.gpu()).sum()
else:
correct += (predict == labels).sum()
# 计算accuracy
accuracy = correct / total * 100
loss_list.append(loss.data)
accuracy_list.append(accuracy)
iteration_list.append(iter)
# 打印信息
print("loos:, Loss:, Accuracy:".format(iter, loss.item(), accuracy))
plt.plot(iteration_list, loss_list)
plt.xlabel("Number of Iteration")
plt.ylabel("Loss")
plt.title("LSTM")
plt.show()
plt.plot(iteration_list, accuracy_list, color='r')
plt.xlabel("Number of iteration")
plt.ylabel("Accuracy")
plt.title("LSTM")
plt.show()
本文参考https://www.bilibili.com/video/BV1n54y117KK/?spm_id_from=333.788
讲的还不错吧,可以听一听
以上是关于基于pytorch实现RNN和LSTM对手写数字集分类的完整实例的主要内容,如果未能解决你的问题,请参考以下文章
图像分类基于PyTorch搭建LSTM实现MNIST手写数字体识别(单向LSTM,附完整代码和数据集)
小白学习PyTorch教程十基于大型电影评论数据集训练第一个LSTM模型
通过PyTorch构建的LeNet-5网络对手写数字进行训练和识别