MNIST手写数字识别:卷积神经网络
代码
import torch
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim
from torchvision import transforms #从torchvision中引入图像转换
#采用随机批量梯度下降,batch_size设为64
batch_size = 64
#用Compose串联多个“图片变换操作”(此处将ToTensor和Normalize组合)
transform = transforms.Compose([
#ToTensor()将shape为(H, W, C)de numpy.darray或者img转为shape为(C, H, W)的tensor,其将每一个数值归一化到(0,1)
transforms.ToTensor(),
#标准化:使用公式" (x - mean) / std ",将每一个元素分布到(-1, 1)
transforms.Normalize(mean = (0.1307,), std = (0.3081,)) #由于mnist数据集的图片均为灰度图片(单通道),所以mean和std各自值输入了一个值
])
# 获取训练集
train_dataset = datasets.MNIST(
#指定保存路径
root = "./mnist",
#获取的是训练集
train = True,
#若在指定路径下找不到目标文件则会自动下载
download = True,
#对所获取的数据集执行上述的transform处理
transform = transform
)
# 获取测试集
test_dataset = datasets.MNIST(
root = "./mnist",
train = False,
download = True,
transform = transform
)
# 定义数据加载器
train_loader = DataLoader(train_dataset, shuffle = True, batch_size = batch_size)
test_loader = DataLoader(test_dataset, shuffle = False, batch_size = batch_size)
# 定义网络模型
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
# 第一层卷积层采用Conv2d模块:输入1维,输出10维,卷积核尺寸5x5(此处输入输出的维度表示的是通道数),不扩充(padding),不设偏置
self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5, padding=0, bias=False)
self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)
# 池化层采用MaxPool2d模块:kernel_size=2表示池化窗口大小为2x2
self.pooling = torch.nn.MaxPool2d(kernel_size=2)
self.fc = torch.nn.Linear(320, 10)
def forward(self, x):
#定义batch的大小是数据张量的第0个维度的数据,也就是每次传入的批量大小
batch_size = x.size(0)
#先做卷积再做池化,然后激活
x = F.relu(self.pooling(self.conv1(x)))
x = F.relu(self.pooling(self.conv2(x)))
# 改变x的形状,为了匹配FC层的输入(传入fc层的需为二维矩阵)
x = x.view(batch_size, -1)
#送入全连接层
x = self.fc(x)
return x
# 实例化模型
model = Model()
# 构造多分类交叉熵损失函数
criterion = torch.nn.CrossEntropyLoss()
# 构造优化器:优化模型中的所有参数,学习率=0.01, 加入一个冲量0.5
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01, momentum=0.5)
# 定义训练过程
def train(epoch):
running_loss = 0
for batch_idx, data in enumerate(train_loader, 0):
inputs, labels = data
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if(batch_idx+1) % 300 ==0:
print(f' [Epoch:{epoch+1},Btach_idx:{batch_idx+1}],loss:{running_loss / 300:.3f} ')
running_loss = 0
# 定义测试过程
def test():
# 已经预测结束且预测正确的样本数(初始化为0 )
correct = 0
# 已经预测结束的样本数(初始化为0)
total = 0
with torch.no_grad(): #测试过程不需要梯度优化
for data in test_loader:
images, labels = data
outputs = model(images)
# model最后输出的是一个10维的矩阵(1行10列),返回‘预测最大值predicted’和‘预测最大值下标’_
_, predicted = torch.max(outputs.data, dim = 1)
#更新已预测结束的样本数
total += labels.size(0)
# 更新已预测结束且预测正确的样本数
correct += (predicted == labels).sum().item()
print(f' Accuracy on testdatset:{100 * (correct/total):.2f}% ') #输出准确率
# 开始运行
if __name__ == '__main__':
for epoch in range(10):
train(epoch)
test()
运行效果
[Epoch:1,Btach_idx:300],loss:0.627
[Epoch:1,Btach_idx:600],loss:0.190
[Epoch:1,Btach_idx:900],loss:0.143
Accuracy on testdataset:96.71%
[Epoch:2,Btach_idx:300],loss:0.115
[Epoch:2,Btach_idx:600],loss:0.097
[Epoch:2,Btach_idx:900],loss:0.086
Accuracy on testdataset:97.69%
[Epoch:3,Btach_idx:300],loss:0.080
[Epoch:3,Btach_idx:600],loss:0.073
[Epoch:3,Btach_idx:900],loss:0.069
Accuracy on testdataset:97.86%
[Epoch:4,Btach_idx:300],loss:0.062
[Epoch:4,Btach_idx:600],loss:0.064
[Epoch:4,Btach_idx:900],loss:0.061
Accuracy on testdataset:98.44%
[Epoch:5,Btach_idx:300],loss:0.052
[Epoch:5,Btach_idx:600],loss:0.051
[Epoch:5,Btach_idx:900],loss:0.059
Accuracy on testdataset:98.50%
[Epoch:6,Btach_idx:300],loss:0.049
[Epoch:6,Btach_idx:600],loss:0.048
[Epoch:6,Btach_idx:900],loss:0.050
Accuracy on testdataset:98.45%
[Epoch:7,Btach_idx:300],loss:0.047
[Epoch:7,Btach_idx:600],loss:0.041
[Epoch:7,Btach_idx:900],loss:0.045
Accuracy on testdataset:98.36%
[Epoch:8,Btach_idx:300],loss:0.040
[Epoch:8,Btach_idx:600],loss:0.042
[Epoch:8,Btach_idx:900],loss:0.041
Accuracy on testdataset:98.73%
[Epoch:9,Btach_idx:300],loss:0.032
[Epoch:9,Btach_idx:600],loss:0.041
[Epoch:9,Btach_idx:900],loss:0.038
Accuracy on testdataset:98.57%
[Epoch:10,Btach_idx:300],loss:0.033
[Epoch:10,Btach_idx:600],loss:0.035
[Epoch:10,Btach_idx:900],loss:0.036
Accuracy on testdataset:98.59%
补充
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
# 第一层卷积层采用Conv2d模块:输入1维,输出10维,卷积核尺寸5x5(此处输入输出的维度表示的是通道数),不扩充(padding),不设偏置
self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5, padding=0, bias=False)
self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)
# 池化层采用MaxPool2d模块:kernel_size=2表示池化窗口大小为2x2
self.pooling = torch.nn.MaxPool2d(kernel_size=2)
self.fc = torch.nn.Linear(320, 10)
def forward(self, x):
#定义batch的大小是数据张量的第0个维度的数据,也就是每次传入的批量大小
batch_size = x.size(0)
#先做卷积再做池化,然后激活
x = F.relu(self.pooling(self.conv1(x)))
x = F.relu(self.pooling(self.conv2(x)))
# 改变x的形状,为了匹配FC层的输入(传入fc层的需为二维矩阵)
x = x.view(batch_size, -1)
#送入全连接层
x = self.fc(x)
return x
Q:self.fc = torch.nn.Linear(320, 10)中的320在不通过手算推理的前提下如何得知?
A:随便填一个数字,运行代码,通过查看报错信息获取FC层的真实输入维数


MNIST手写数字识别:卷积神经网络的更多相关文章
- 手写数字识别 卷积神经网络 Pytorch框架实现
MNIST 手写数字识别 卷积神经网络 Pytorch框架 谨此纪念刚入门的我在卷积神经网络上面的摸爬滚打 说明 下面代码是使用pytorch来实现的LeNet,可以正常运行测试,自己添加了一些注释, ...
- Android+TensorFlow+CNN+MNIST 手写数字识别实现
Android+TensorFlow+CNN+MNIST 手写数字识别实现 SkySeraph 2018 Email:skyseraph00#163.com 更多精彩请直接访问SkySeraph个人站 ...
- 基于tensorflow的MNIST手写数字识别(二)--入门篇
http://www.jianshu.com/p/4195577585e6 基于tensorflow的MNIST手写字识别(一)--白话卷积神经网络模型 基于tensorflow的MNIST手写数字识 ...
- 第三节,CNN案例-mnist手写数字识别
卷积:神经网络不再是对每个像素做处理,而是对一小块区域的处理,这种做法加强了图像信息的连续性,使得神经网络看到的是一个图像,而非一个点,同时也加深了神经网络对图像的理解,卷积神经网络有一个批量过滤器, ...
- 基于TensorFlow的MNIST手写数字识别-初级
一:MNIST数据集 下载地址 MNIST是一个包含很多手写数字图片的数据集,一共4个二进制压缩文件 分别是test set images,test set labels,training se ...
- Tensorflow实现MNIST手写数字识别
之前我们讲了神经网络的起源.单层神经网络.多层神经网络的搭建过程.搭建时要注意到的具体问题.以及解决这些问题的具体方法.本文将通过一个经典的案例:MNIST手写数字识别,以代码的形式来为大家梳理一遍神 ...
- mnist手写数字识别——深度学习入门项目(tensorflow+keras+Sequential模型)
前言 今天记录一下深度学习的另外一个入门项目——<mnist数据集手写数字识别>,这是一个入门必备的学习案例,主要使用了tensorflow下的keras网络结构的Sequential模型 ...
- Pytorch入门——手把手教你MNIST手写数字识别
MNIST手写数字识别教程 要开始带组内的小朋友了,特意出一个Pytorch教程来指导一下 [!] 这里是实战教程,默认读者已经学会了部分深度学习原理,若有不懂的地方可以先停下来查查资料 目录 MNI ...
- 手写数字识别 ----卷积神经网络模型官方案例注释(基于Tensorflow,Python)
# 手写数字识别 ----卷积神经网络模型 import os import tensorflow as tf #部分注释来源于 # http://www.cnblogs.com/rgvb178/p/ ...
- 持久化的基于L2正则化和平均滑动模型的MNIST手写数字识别模型
持久化的基于L2正则化和平均滑动模型的MNIST手写数字识别模型 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献Tensorflow实战Google深度学习框架 实验平台: Tens ...
随机推荐
- 005 媒体访问控制(MAC,Media Access Control)
一,MAC MAC是媒体访问控制器.以太网MAC由IEEE-802.3以太网标准定义.它实现了数据链路层.最新的MAC同时支持10/100/1000Mbps速率.通常情况下,它实现MII/GMII/R ...
- MySQL自定义函数与存储过程的创建、使用、删除
前言 日常开发中,可能会用到数据库的自定义函数/存储过程,本文记录MySQL对自定义函数与存储过程的创建.使用.删除的使用 通用语法 事实上,可以认为存储过程就是没有返回值的函数,创建/使用/删除都非 ...
- css内容渐入效果实现
.fade-in-section { opacity: 0; transform: translateY(20vh); visibility: hidden; transition: opacity ...
- [转]C# 互操作性入门系列(二):使用平台调用调用Win32 函数
传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...
- 动态规划_C#
参考网址:https://blog.csdn.net/lvcoc/article/details/104167648 先不管动态规划,先看斐波那契数列 斐波那契数列:F1=Fn-1+Fn-2 分别用递 ...
- Js/jquery常用
id属性不能有空格 1. js判断checkebox是否被选中 var ischecked = document.getElementById("xxx").checked // ...
- 【转】时冲的CSDN:Linux系统各个目录的作用
请各位移步原文链接:时冲的CSDN 以下仅用于个人梳理,排版方便阅读记忆(原文更优): from my typora: 文章目录 Linux文件系统 LINUX有四种基本文件系统类型: 1.普通文件: ...
- ABC类IP地址
A类IP地址一个A类IP地址由1字节的网络地址和3字节主机地址组成,网络地址的最高位 必须是"0", 地址范围从1.0.0.0 到126.0.0.0.可用的A类网络有126个,每个 ...
- Go版本管理--go.sum
目录 1. 简介 2. go.sum文件记录 3. 生成 4.校验 5.校验和数据库 1. 简介 为了确保一致性构建,Go引入了go.mod文件来标记每个依赖包的版本,在构建过程中go命令会下载go. ...
- MySQL-表迁移工具的选型-xtrabackup的使用
1.1. 场景 有的时候test人员可能需要在测试库上比较新的数据,这时候只能是从生产库上面去那了.如果是小表还好实用mysqldump/mysqlpump就可以轻松的解决.但是,如果遇到了大表这将是 ...