PyTorch基础与简单应用:构建卷积神经网络实现MNIST手写数字分类
文章目录
- (一) 问题描述
- (二) 设计简要描述
- (三) 程序清单
- (四) 结果分析
- (五) 调试报告
- (六) 实验小结
- (七) 参考资料
(一) 问题描述
构建卷积神经网络实现MNIST手写数字分类。
(二) 设计简要描述
机器学习的三个基本步骤——
程序设计思路——(此图放大可看清)
(三) 程序清单
import torch
import torchvision
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optimn_epochs = 3 # 定义了学习算法在整个训练数据集中的工作次数
batch_size_train = 64 # 1 <批量大小<训练集的大小 严格来说这个算小批量梯度下降,而不是SGD
batch_size_test = 1000
learning_rate = 0.01
momentum = 0.5 # Momentum可以加速 SGD, 并且抑制震荡
'''可以使得梯度方向不变的维度上速度变快,梯度方向有所改变的维度上的更新速度变慢'''
log_interval = 10
random_seed = 1
torch.manual_seed(random_seed)train_loader = torch.utils.data.DataLoader(torchvision.datasets.MNIST('./data/', train=True, download=True,transform=torchvision.transforms.Compose([torchvision.transforms.ToTensor(), # 用于将图片转换成Tensor格式的数据,并且进行了标准化处理torchvision.transforms.Normalize( # Normalize()用均值和标准偏差对张量图像进行归一化(0.1307,), (0.3081,)) # Normalize()转换使用的值0.1307和0.3081是MNIST数据集的全局平均值和标准偏差])),batch_size=batch_size_train, shuffle=True)
test_loader = torch.utils.data.DataLoader(torchvision.datasets.MNIST('./data/', train=False, download=True,transform=torchvision.transforms.Compose([torchvision.transforms.ToTensor(),torchvision.transforms.Normalize((0.1307,), (0.3081,))])),batch_size=batch_size_test, shuffle=True)# 看看一批数据的形状
'''examples = enumerate(test_loader)
batch_idx, (example_data, example_targets) = next(examples)
print(example_targets)
print(example_data.shape)'''# 查看MNIST数据集中的图片
'''fig = plt.figure()
for i in range(6):plt.subplot(2, 3, i + 1)plt.tight_layout()plt.imshow(example_data[i][0], cmap='gray', interpolation='none')plt.title("Ground Truth: {}".format(example_targets[i]))plt.xticks([])plt.yticks([])
plt.show()'''class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(1, 10, kernel_size=5) # 三个参数的意思分别是:输入信号的通道,卷积产生的通道,卷积核的尺寸self.conv2 = nn.Conv2d(10, 20, kernel_size=5)self.conv2_drop = nn.Dropout2d() # 随机将输入张量中整个通道设置为0self.fc1 = nn.Linear(320, 50) # 全连接层采用线性函数self.fc2 = nn.Linear(50, 10) # 第一个参数是输入样本的大小,第二个是输出def forward(self, x): # forward()传递定义了使用给定的层和函数计算输出的方式x = F.relu(F.max_pool2d(self.conv1(x), 2)) # relu:Rectified Linear Unit,修正线性单元,是一种非线性激活函数x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))x = x.view(-1, 320)x = F.relu(self.fc1(x))x = F.dropout(x, training=self.training)x = self.fc2(x)return F.log_softmax(x) # softmax:输出是每个分类被取到的概率# 初始化网络和优化器
network = Net()
optimizer = optim.SGD(network.parameters(), lr=learning_rate, # SGD:Stochastic Gradient Descentmomentum=momentum)train_losses = []
train_counter = []
test_losses = []
test_counter = [i * len(train_loader.dataset) for i in range(n_epochs + 1)]
del test_counter[0]def train(epoch):network.train()for batch_idx, (data, target) in enumerate(train_loader):optimizer.zero_grad()output = network(data)loss = F.nll_loss(output, target)loss.backward()optimizer.step()if batch_idx % log_interval == 0:print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset),100. * batch_idx / len(train_loader), loss.item()))train_losses.append(loss.item())train_counter.append((batch_idx * 64) + ((epoch - 1) * len(train_loader.dataset)))torch.save(network.state_dict(), './model.pth')torch.save(optimizer.state_dict(), './optimizer.pth')def test():network.eval()test_loss = 0correct = 0with torch.no_grad():for data, target in test_loader:output = network(data)test_loss += F.nll_loss(output, target, size_average=False).item()pred = output.data.max(1, keepdim=True)[1]correct += pred.eq(target.data.view_as(pred)).sum()test_loss /= len(test_loader.dataset)test_losses.append(test_loss)print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset),100. * correct / len(test_loader.dataset)))for epoch in range(1, n_epochs + 1):train(epoch)test()fig = plt.figure()
plt.plot(train_counter, train_losses, color='blue')
plt.scatter(test_counter, test_losses, color='red')
plt.legend(['Train Loss', 'Test Loss'], loc='upper right')
plt.xlabel('number of training examples seen')
plt.ylabel('negative log likelihood loss')
plt.show()
(四) 结果分析
一批训练数据是一个形状张量
意味着有1000个例子的28x28像素的灰度(即没有rgb通道)训练结果与测试结果
蓝色为训练集上损失值
红色为一轮训练后测试集上的损失值
一共训练了三轮
模型精度
第一轮训练后测试集上的精度
第二轮训练后测试集上的精度
第三轮训练后测试集上的精度
(五) 调试报告
- 在PyTorch中,构建网络的一个好方法是为我们希望构建的网络创建一个新类,再在类中导入一些子模块,以获得更具可读性的代码。
- 报错:ValueError: x and y must be the same size
定位:plt.scatter(test_counter, test_losses, color=‘red’)
分析:打印出test_counter和test_losses,发现test_counter多一个元素0
解决:在test_counter = [i * len(train_loader.dataset) for i in range(n_epochs + 1)]下面加一行
del test_counter[0] - 增加Dropout layers
其作用是随机将输入张量中部分元素设置为0。对于每次前向调用,被置0的元素都是随机的。
作用是可以提高特征图之间的独立程度,防止过拟合。
(六) 实验小结
- 本次实验使用了PyTorch框架,在实验指导书和官方文档的帮助下训练了一个精度还算不错的卷积神经网络模型,由两个卷积层一个dropout层两个池化层两个全连接层构成。
- 弄清了epoch和batch的区别,epoch是对于整个训练集而言要训练多少次,取值范围是1到正无穷,batch是训练的最小单元,假设总样本量为total,batch_size的取值在1~total之间,一个epoch会进行total/batch_size回训练。
(七) 参考资料
CSDN博客:https://blog.csdn.net/sxf1061700625/article/details/105870851
PyTorch官方文档:https://pytorch-cn.readthedocs.io/zh/latest/
PyTorch基础与简单应用:构建卷积神经网络实现MNIST手写数字分类相关推荐
- 基于PyTorch框架的多层全连接神经网络实现MNIST手写数字分类
多层全连接神经网络实现MNIST手写数字分类 1 简单的三层全连接神经网络 2 添加激活函数 3 添加批标准化 4 训练网络 5 结论 参考资料 先用PyTorch实现最简单的三层全连接神经网络,然后 ...
- PyTorch入门一:卷积神经网络实现MNIST手写数字识别
先给出几个入门PyTorch的好的资料: PyTorch官方教程(中文版):http://pytorch123.com <动手学深度学习>PyTorch版:https://github.c ...
- 卷积神经网络mnist手写数字识别代码_搭建经典LeNet5 CNN卷积神经网络对Mnist手写数字数据识别实例与注释讲解,准确率达到97%...
LeNet-5卷积神经网络是最经典的卷积网络之一,这篇文章就在LeNet-5的基础上加入了一些tensorflow的有趣函数,对LeNet-5做了改动,也是对一些tf函数的实例化笔记吧. 环境 Pyc ...
- Tensorflow之 CNN卷积神经网络的MNIST手写数字识别
点击"阅读原文"直接打开[北京站 | GPU CUDA 进阶课程]报名链接 作者,周乘,华中科技大学电子与信息工程系在读. 前言 tensorflow中文社区对官方文档进行了完整翻 ...
- PyTorch之实现LeNet-5卷积神经网络对mnist手写数字图片进行分类
论文:Gradient-based learning applied to document recognition 简单介绍 意义: 对手写数据集进行识别,对后续卷积网络的发展起到了奠基作用 特点: ...
- 用Python搭建2层神经网络实现mnist手写数字分类
这是一个用python搭建2层NN(一个隐藏层)识别mnist手写数据集的示例 mnist.py文件提供了mnist数据集(6万张训练图,1万张测试图)的在线下载,每张图片是 28 ∗ 28 28*2 ...
- PyTorch基础入门五:PyTorch搭建多层全连接神经网络实现MNIST手写数字识别分类
)全连接神经网络(FC) 全连接神经网络是一种最基本的神经网络结构,英文为Full Connection,所以一般简称FC. FC的准则很简单:神经网络中除输入层之外的每个节点都和上一层的所有节点有连 ...
- 独家 | 如何从头开始为MNIST手写数字分类建立卷积神经网络(附代码)
翻译:张睿毅 校对:吴金笛 本文约9300字,建议阅读20分钟. 本文章逐步介绍了卷积神经网络的建模过程,最终实现了MNIST手写数字分类. MNIST手写数字分类问题是计算机视觉和深度学习中使用的标 ...
- 基于TensorFlow深度学习框架,运用python搭建LeNet-5卷积神经网络模型和mnist手写数字识别数据集,设计一个手写数字识别软件。
本软件是基于TensorFlow深度学习框架,运用LeNet-5卷积神经网络模型和mnist手写数字识别数据集所设计的手写数字识别软件. 具体实现如下: 1.读入数据:运用TensorFlow深度学习 ...
最新文章
- crontab安装_django-crontab实现服务端的定时计划任务
- initramfs下启动linux_和菜鸟一起学linux之initramfs方式启动
- 为什么onenote一直在加载_OneNote:科研笔记独一无二的无敌利器
- java开发工具软件排行榜
- Caffe源码解析2:SycedMem
- 页面缓存,数据源缓存
- hibernate.Session简介
- 上班摸鱼打卡模拟器微信小程序源码
- java程序设计实用教程 实验6答案_java程序设计实用教程习题解答与实验指导.doc...
- 实践致知第6享:QQ截图的文字识别功能
- 解决0xc00d5212
- eclipse 装阿里规范模板
- 靠微信小程序两周获客20万,同城小程序开始爆发
- php实现文件下载的几种方式
- 什么是Product Lead Growth( PLG)
- notepad拼心形_用shell脚本写个心形动画表格
- 使用ActiveX实现的Web自定义查询-万能查询
- 应用软件安全编程资源使用安全
- 新编程语言——微软的“M”语言
- FIFO原理及其应用