首页 > 分享 > pytorch实现简单卷积神经网络(CNN)网络完成手写数字识别

pytorch实现简单卷积神经网络(CNN)网络完成手写数字识别

首先你需要安装torch,torchvision,然后使用torchvision来下载mnist数据集,如果下载数据集有什么问题,请查看PyTorch用最简单的多层感知机(深度神经网络)实现手写数字识别   和   使用torchvision下载外网数据集mnist没有进度的解决方案

本文假设你对CNN基本原理有一定的了解。

我首先建立了一个tools工具类,这样主模块的代码可以少一些了。我把它命名成tools.py:

import torch

import torchvision

from torch.utils.data import DataLoader

def get_trans():

trans = torchvision.transforms.Compose(

[

torchvision.transforms.ToTensor(),

torchvision.transforms.Normalize( [0.5], [0.5] )

]

)

return trans

DOWNLOAD_MNIST=False

train_data = torchvision.datasets.MNIST( root="./mnist",

train=True,

transform=get_trans(),

download=DOWNLOAD_MNIST

)

test_data = torchvision.datasets.MNIST( root="./mnist", train=False,

transform=get_trans(), download=DOWNLOAD_MNIST

)

def get_trainLoader(BATCH_SIZE):

train_loader = DataLoader(train_data, batch_size=BATCH_SIZE, shuffle=True)

return train_loader

def get_testLoader(BATCH_SIZE):

test_loader = DataLoader(test_data, batch_size=BATCH_SIZE, shuffle=False)

return test_loader

def get_cuda_available():

available=torch.cuda.is_available()

return available

def get_test_data_len():

return len(test_data)

然后是主模块,首先引入必要的模块:

import torch.nn as nn

import torch

import time

import tools

搭建CNN网络:

class CNN(nn.Module):

def __init__(self):

super(CNN, self).__init__()

self.conv1=nn.Sequential(

nn.Conv2d(

in_channels=1,

out_channels=16,

kernel_size=5,

stride=1,

padding=2

),

nn.ReLU(),

nn.MaxPool2d(kernel_size=2)

)

self.conv2=nn.Sequential(

nn.Conv2d(16,32,5,1,2),

nn.ReLU(),

nn.MaxPool2d(2)

)

self.out=nn.Linear(32*7*7,10)

def forward(self,x):

x = self.conv1( x )

x = self.conv2( x )

x=x.view(x.size(0),-1)

output=self.out(x)

return output

输出CNN的结构如下:

CNN(
  (conv1): Sequential(
    (0): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (1): ReLU()
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (conv2): Sequential(
    (0): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (1): ReLU()
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (out): Linear(in_features=1568, out_features=10, bias=True)
)

定义常量:

EPOCH=50

BATCH_SIZE=20

LR=0.03

DOWNLOAD_MNIST=False

定义损失函数和优化器、加载数据、更改网络到gpu上运行(如果GPU可用的话):

cnn=CNN()

cuda_available=tools.get_cuda_available()

if cuda_available==True:

cnn.cuda()

optimizer=torch.optim.Adam(cnn.parameters(),lr=LR)

loss_function=nn.CrossEntropyLoss()

train_loader=tools.get_trainLoader(BATCH_SIZE)

test_loader=tools.get_testLoader(BATCH_SIZE*10)

最后是训练和测试:

for ep in range(EPOCH):

startTick = time.clock()

for data in train_loader:

img, label = data

if cuda_available:

img = img.cuda()

label = label.cuda()

out = cnn( img )

loss = loss_function( out, label )

optimizer.zero_grad()

loss.backward()

optimizer.step()

num_correct = 0

for data in test_loader:

img, label = data

if cuda_available:

img = img.cuda()

label = label.cuda()

out = cnn( img )

_, prediction = torch.max( out, 1 )

num_correct += (prediction == label).sum()

accuracy = num_correct.cpu().numpy() / tools.get_test_data_len()

timeSpan = time.clock() - startTick

print( "第%d迭代期,准确率为%f,耗时%dS" % (ep + 1, accuracy, timeSpan) )

整个模块的代码:

import torch.nn as nn

import torch

import time

import tools

class CNN(nn.Module):

def __init__(self):

super(CNN, self).__init__()

self.conv1=nn.Sequential(

nn.Conv2d( #(1,28,28)

in_channels=1,

out_channels=16,

kernel_size=5,

stride=1,

padding=2 #padding=(kernelsize-stride)/2

),#(16,28,28)

nn.ReLU(),

nn.MaxPool2d(kernel_size=2)#(16,14,14)

)

self.conv2=nn.Sequential(#(16,14,14)

nn.Conv2d(16,32,5,1,2),#(32,14,14)

nn.ReLU(),#(32,14,14)

nn.MaxPool2d(2)#(32,7,7)

)

self.out=nn.Linear(32*7*7,10)

def forward(self,x):

x = self.conv1( x )

x = self.conv2( x ) #(batch,32,7,7)

x=x.view(x.size(0),-1) #(batch,32*7*7)

output=self.out(x)

return output

print("start")

EPOCH=50#总的训练次数

BATCH_SIZE=20#批次的大小

LR=0.03#学习率#交叉熵损失函数不需要太大的学习率

DOWNLOAD_MNIST=False#运行代码的时候是否下载数据集

cnn=CNN()

cuda_available=tools.get_cuda_available()

if cuda_available==True:

cnn.cuda()

optimizer=torch.optim.Adam(cnn.parameters(),lr=LR)

loss_function=nn.CrossEntropyLoss()

train_loader=tools.get_trainLoader(BATCH_SIZE)

test_loader=tools.get_testLoader(BATCH_SIZE*10)

#训练过程

for ep in range(EPOCH):

# 记录把所有数据集训练+测试一遍需要多长时间

startTick = time.clock()

for data in train_loader: # 对于训练集的每一个batch

img, label = data

if cuda_available:

img = img.cuda()

label = label.cuda()

out = cnn( img ) # 送进网络进行输出

loss = loss_function( out, label ) # 获得损失

optimizer.zero_grad() # 梯度归零

loss.backward() # 反向传播获得梯度,但是参数还没有更新

optimizer.step() # 更新梯度

num_correct = 0 # 正确分类的个数,在测试集中测试准确率

for data in test_loader:

img, label = data

if cuda_available:

img = img.cuda()

label = label.cuda()

out = cnn( img ) # 获得输出

_, prediction = torch.max( out, 1 )

# torch.max()返回两个结果,

# 第一个是最大值,第二个是对应的索引值;

# 第二个参数 0 代表按列取最大值并返回对应的行索引值,1 代表按行取最大值并返回对应的列索引值。

num_correct += (prediction == label).sum() # 找出预测和真实值相同的数量,也就是以预测正确的数量

accuracy = num_correct.cpu().numpy() / tools.get_test_data_len() # 计算正确率,num_correct是gpu上的变量,先转换成cpu变量

timeSpan = time.clock() - startTick

print( "第%d迭代期,准确率为%f,耗时%dS" % (ep + 1, accuracy, timeSpan) )

相关知识

CNN卷积神经网络:花卉分类
深度学习机器学习卷积神经网络的花卉识别花种类识别
卷积神经网络的算法范文
基于python编程的五种鲜花识别
colab cnn实现花卉图片分类识别
深度学习之基于Tensorflow卷积神经网络花卉识别系统
看图识花的算法,如何识别植物?
基于深度卷积神经网络的移动端花卉识别系统
卷积神经网络训练花卉识别分类器
应用卷积神经网络识别花卉及其病症

网址: pytorch实现简单卷积神经网络(CNN)网络完成手写数字识别 https://m.huajiangbk.com/newsview112550.html

所属分类:花卉
上一篇: 摆花花卉汇总(18页)
下一篇: 空气能热泵绽放节能环保之花 成花