💖作者简介:大家好,我是车神哥,府学路18号的车神🥇
⚡About—>车神:从寝室到实验室最快3分钟,最慢3分半(那半分钟其实是等红绿灯)
📝个人主页:车手只需要车和手,压力来自论文_府学路18号车神_CSDN博客
🥇 官方认证:人工智能领域优质创作者
🎉点赞➕评论➕收藏 == 养成习惯(一键三连)😋⚡希望大家多多支持🤗~一起加油 😁
专栏
从深度学习的简单任务开始,我们将从不同的深度学习框架来实现一个手写体识别任务,这个任务在深度学习领域可以说是和学习编程语言的第一步“Hello World”差不多。
主要的目的是为了可以直观的对比出不同深度学习框架下实现代码的差异性。我们均通过构建一个多层感知机模型来完成这个任务。
手写体识别任务
🎉PyTorch
老规矩,关于Pytorch之前也讲过了。
它是一个基于Python的科学计算包,好处也很多,如速度快,方便灵活~
⚡PyTorch安装
简单粗暴版
用conda创建环境来安装不同版本的pytorch
conda create -n pytorch python=3.6.0
注意后面可以选择不同的版本哦~
进入环境
-
activate base
-
activate pytorch
🎉手写体识别任务
这里我们用到的一个开放的手写体识别数据集:MNIST数据集。
目前应用相当的广泛,在许多论文和基础教程中都应用到了。
MNIST数据集来自美国国家标准与技术研究所。
数据集由250个不同的人手写的数字构成,其中50%来自高中生,50%来自人口普查局的工作人员。具体由如下4个部分组成:
- 训练图片集(training set images):train-images-idx3-ubyte.gz (包含60,000个样本)
- 训练图片标签(training set labels):train-labels-idxl-ubyte.gz (包含60,000个标签)
- 测试图片集(test set images):t10k-images-idx3-ubyte.gz (包含10,000 个样本)
- 测试图片标签(test set labels):t10k-labels-idxl-ubyte.gz (包含10,000个标签)
样例如下图所示:
🎉多层感知机
对于上面这样的数据集,我们构建一个三层神经网络模型,分别为输入层
、隐含层
、输出层
。这是一个非常普通简单的神经网络模型,俗称为多层感知机(Mult-Layer Perceptron, MLP)
。
整个模型如下图所示:
该神经网络包含三层,第一层(输入层)有784个神经元(每张手写体识别图像素均为28像素*28像素的图像),第二层(隐藏层)有200个神经元,最终层(输出层)有10个神经元(有数字0~9共有10个类别)。我们使用Sigmoid函数作为激活函数,将均方误差作为损失函数,使用Adam优化器,Learning Rate=0.01.
🎉PyTorch代码
所有框架下的步骤均一致:
- 设置参数并加载数据集(大多数框架都有架子标准数据集的方法,如MNIST)
- 创建多层感知机(MLP)神经网络
- 定义训练函数,包括模型训练和模型存储
- 定义预测函数,包括模型导入和测试数据预测
- 创建main函数,让用户使用训练数据集进行训练,然后使用测试数据集进行测试
在下列代码中,将其整理为相同的格式以便比较,每份代码包含五部分:
- 设置参数并加载数据集
- 定义神经网络
- 定义训练函数
- 定义预测函数
main
函数
⚡*main函数
其中的main
函数不变:
import argparse
if __name__=="__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--action", type=str, default="predict")
FLAGS, unparsed = parser.parse_known_args()
if FLAGS.action == "train":
train()
if FLAGS.action == "predict":
predict()
运行代码的方法:
1. 训练:python MNIST.py --action train
2. 预测:python MNIST.py -- action predict
1. ⚡设置参数并加载数据集
import torch
import argparse
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.autograd import Variable
from torch.utils.data import DataLoader
# 定义参数
inputs, hiddens, outputs = 784, 200, 10
learning_rate = 0.01
epochs = 50
batch_size = 64
trainsformation = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
train_set = datasets.MNIST('mnist/', train=True, transform=trainsformation, download=True)
train_loader = DataLoader(dataset=train_set, batch_size=batch_size, shuffle=True)
test_set = datasets.MNIST('mnist/', train=False, transform=trainsformation, download=True)
test_loader = DataLoader(dataset=test_set, batch_size=batch_size, shuffle=False)
2. ⚡定义神经网络
# 定义神经网络
class mlp(nn.Module):
def __init__(self):
super(mlp, self).__init__()
self.sigmoid = nn.Sigmoid()
self.hidden_layer = nn.Linear(inputs, hiddens)
self.output_layer = nn.Linear(hiddens, outputs)
def forward(self, x):
out = self.sigmoid(self.hidden_layer(x))
out = self.sigmoid(self.output_layer(out))
return out
def name(self):
return "mlp"
3. ⚡定义训练函数
# 定义训练函数
def train():
model = mlp()
loss = nn.MSELoss(reduction='sum')
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
for epoch in range(epochs):
avg_error = 0
for i, (images, labels) in enumerate(train_loader):
images = Variable(images.view(-1, inputs))
# 将类别标签转换成One-hot编码
one_hot = torch.FloatTensor(labels.size(0), 10).zero_()
target = one_hot.scatter_(1, labels.view((labels.size(0), 1)), 1)
target = Variable(target)
# 计算损失函数和梯度
optimizer.zero_grad()
out = model(images)
error = loss(out, target)
error.backward()
optimizer.step()
avg_error += error.item()
avg_error /= train_loader.dataset.train_data.shape[0]
print('Epoch [%d/%d], error:%.4f' % (epoch+1, epochs, avg_error))
torch.save(model.state_dict(), "model.pkl")
4. ⚡定义预测函数
# 定义预测函数
def predict():
model = mlp()
model.load_state_dict(torch.load("model.pkl"))
correct, total = 0, 0
for images, labels in test_loader:
images = Variable(images.view(-1, inputs))
out = model(images)
_, predicted = torch.max(out.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum()
print("accuracy: %0.2f %%" % (100.0 * correct / total))
🤗代码汇总
到此我们已经构建完了所有的模型结构,让我们运行起来~
训练开始(在Terminal
输入):
python MNIST.py --action train
预测开始:
python MNIST.py -action predict
# -- coding: utf-8 --
# @Time : 2022/5/26 19:07
# @Author : 府学路18号车神
# @File : PyTorch.py
# @Software: PyCharm
import torch
import argparse
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.autograd import Variable
from torch.utils.data import DataLoader
# 定义参数
inputs, hiddens, outputs = 784, 200, 10
learning_rate = 0.01
epochs = 50
batch_size = 64
trainsformation = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
train_set = datasets.MNIST('mnist/', train=True, transform=trainsformation, download=True)
train_loader = DataLoader(dataset=train_set, batch_size=batch_size, shuffle=True)
test_set = datasets.MNIST('mnist/', train=False, transform=trainsformation, download=True)
test_loader = DataLoader(dataset=test_set, batch_size=batch_size, shuffle=False)
# 定义神经网络
class mlp(nn.Module):
def __init__(self):
super(mlp, self).__init__()
self.sigmoid = nn.Sigmoid()
self.hidden_layer = nn.Linear(inputs, hiddens)
self.output_layer = nn.Linear(hiddens, outputs)
def forward(self, x):
out = self.sigmoid(self.hidden_layer(x))
out = self.sigmoid(self.output_layer(out))
return out
def name(self):
return "mlp"
# 定义训练函数
def train():
model = mlp()
loss = nn.MSELoss(reduction='sum')
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
for epoch in range(epochs):
avg_error = 0
for i, (images, labels) in enumerate(train_loader):
images = Variable(images.view(-1, inputs))
# 将类别标签转换成One-hot编码
one_hot = torch.FloatTensor(labels.size(0), 10).zero_()
target = one_hot.scatter_(1, labels.view((labels.size(0), 1)), 1)
target = Variable(target)
# 计算损失函数和梯度
optimizer.zero_grad()
out = model(images)
error = loss(out, target)
error.backward()
optimizer.step()
avg_error += error.item()
avg_error /= train_loader.dataset.train_data.shape[0]
print('Epoch [%d/%d], error:%.4f' % (epoch+1, epochs, avg_error))
torch.save(model.state_dict(), "model.pkl")
# 定义预测函数
def predict():
model = mlp()
model.load_state_dict(torch.load("model.pkl"))
correct, total = 0, 0
for images, labels in test_loader:
images = Variable(images.view(-1, inputs))
out = model(images)
_, predicted = torch.max(out.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum()
print("accuracy: %0.2f %%" % (100.0 * correct / total))
# main
if __name__=="__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--action", type=str, default="predict")
FLAGS, unparsed = parser.parse_known_args()
if FLAGS.action == "train":
train()
if FLAGS.action == "predict":
predict()
📝总结
PyTorch的关键特性是命令式编程,所见即所得,输入什么执行什么。完全契合Python的语法风格,和之前的Tensorflow与Keras的符号式编程大不相同。
很大一个好处就是,我们面对不同的API时,如果遇到不懂的,可以直接运行查看结果是否满足要求~
🥇 往期框架
框架 | Blog |
---|---|
TensorFlow | 【深度学习框架】|TensorFlow|完成一个手写体识别任务 |
Keras | 【深度学习框架】|Keras|完成一个手写体识别任务 |
好了,第三个框架下实现手写体识别的任务就到这了,下次在换Pytorch框架来实现一下,下期再见哦~
❤坚持读Paper,坚持做笔记,坚持学习,坚持刷力扣LeetCode❤!!!
坚持刷题!!!
⚡To Be No.1⚡⚡哈哈哈哈
⚡创作不易⚡,过路能❤关注、收藏、点个赞❤三连就最好不过了
ღ( ´・ᴗ・` )
❤