神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

目录

一、简介

二、原理及代码

1、数据准备

2、构造神经网络

3、Python代码实现(训练-效果)

参考

一、简介

PyTorch是一个开源Python机器学习库,基于Torch,用于自然语言处理等应用程序。2017年1月, Facebook 人工智能 研究院(FAIR)基于Torch推出了PyTorch。它是一个基于Python的可续计算包,提供两个高级功能:1、具有强大的GPU加速的张量计算(如NumPy)。2、包含自动求导系统的深度神经网络[1]。

二、原理及代码

1、数据准备

我们用美国国家标准与技术研究所的数据集-MNIST。这个数据集有两部分:训练集和测试集,顾名思义训练集是用来训练神经网络的,测试集是用来测试神经网络训练后的效果。训练集由250个人手写的数字构成,其中50%是高中学生,50%是人口普查的工作人员。测试数据集也是同样比例的手写数字。这些图片都是28X28灰度像素的。如:

神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

下载

import torchvision.datasets as dsets

#MNIST dataset
train_dataset = dsets.MNIST(root='/ml/pymnist',  #选择数据的根目录
                            train=True,#选择训练集
                            transform=None,#不考虑使用数据预处理
                            download=True #是否从网络上下载图片
)

test_dataset = dsets.MNIST(root='/ml/pymnist',#选择数据的根目录
                           train=False,#选择测试集
                           transform=None,#不考虑使用任何数据预处理
                           download=True #是否从网络上下载图片
)

查看数据​​​​​​​

x_train=train_dataset.train_data.numpy().reshape(-1,28*28)  #将6万张28X28的图片,转换为一维数组
#print(x_train.shape)  #输出;(60000, 784)

imgIndex = 22

#取其中的一个图片
x1 = x_train[imgIndex].reshape(28,28)  #将一维数组转换为二阶矩阵 28X28,还原图片矩阵
#print(x1)  #输出28X28二维矩阵

y_train = train_dataset.train_labels.numpy()  #转换为numpy数据
#print(y_train.shape) #输出torch.Size([60000]) ,有60000张图片的标签,正好与上面图片数量对应

y1 = y_train[imgIndex]
#print(y1)  #输出:5

#图片显示
import matplotlib.pyplot as plt
plt.imshow(x1,cmap=plt.cm.binary)  #显示图片设置
plt.title("number:" + str(y1))
plt.show()

神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

2、构造神经网络

从上述的数据集我们知道一个图片有28X28 = 784个像素,因此,输入层有784个神经元。隐藏层的神经元可以自定义,这里就设置50个。输出层的神经元个数和数据集元素的类别有关,因为数据集中的数字只有0~9,即只有10种类别,因此,我们将输出层的神经元个数设置为10个。激活函数选择现在比较流行的ReLU函数:

神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

图 ReLU函数图

ReLU函数的特点是:在程序中计算快(因为不需要计算指数);在输入为正数的时候不存在梯度饱和问题。

神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

图 神经元连接

神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

图 神经网络层

Affine表示将输入进行加权求和,然后传给激活函数ReLU,也可以认为是隐藏层的子层。

在输出层中加入了Softmaxwithloss层处理误差。由于Softmaxwithloss层之前没提到,现在介绍一下。

先选择损失函数:

神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

y:输出神经元的真实值

p:输出神经元的预测值

C:输出神经元的个数

其中y是经过编码变为one-hot code,即y中的元素只能有一个是1,其他为0, 这样输出神经元每输出一次,我们就可以告诉它那个输出神经元输出的是正确值。 详细可参考

神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

将预测值代入损失函数L即可求出误差。

3、Python代码实现(训练-效果)

from collections import OrderedDict

import numpy as np

import torch
from torch.utils.data import DataLoader
import torchvision.datasets as dsets
import torchvision.transforms as transforms

import numpy as np

batch_size = 100
#MNIST dataset
train_dataset = dsets.MNIST(root='/ml/pymnist',  #选择数据的根目录
                            train=True,#选择训练集
                            transform=None,#不考虑使用数据预处理
                            download=False #是否从网络上下载图片,第一次要选True
)

test_dataset = dsets.MNIST(root='/ml/pymnist',#选择数据的根目录
                           train=False,#选择测试集
                           transform=None,#不考虑使用任何数据预处理
                           download=False#是否从网络上下载图片,第一次要选True
)

x_train=train_dataset.train_data.numpy().reshape(-1,28*28)
y_train_tmp=train_dataset.train_labels.reshape(train_dataset.train_labels.shape[0],1)
y_train=torch.zeros(y_train_tmp.shape[0],10).scatter_(1,y_train_tmp,1).numpy()
#print(y_train)

x_test = test_dataset.test_data.numpy().reshape(-1,28*28)
y_test_tmp = test_dataset.test_labels.reshape(test_dataset.test_labels.shape[0],1)
y_test = torch.zeros(y_test_tmp.shape[0],10).scatter_(1,y_test_tmp,1).numpy()

class Relu:
    def __init__(self):
        self.x=None
        return
    def forward(self,x):
        self.x=np.maximum(0,x)
        out=self.x
        return out
    def backward(self,dout):
        dx=dout
        dx[self.x>> np.random.choice(5, 3)   输出array([0, 3, 4]) # random
                                                                #在train_size范围内随机选batch_size个数,形成一维数组
        #print(batch_mask)
        x_batch = x_train[batch_mask]  #在总数据中选一小批
        #print(x_batch.shape)
        y_batch = y_train[batch_mask]

##########################梯度下降法####################################
        grad = network.gradient(x_batch,y_batch)
       #print("grad",grad)

        for key in ('W1','b1','W2','b2'):
            network.params[key] -= learning_rate*grad[key]  #实现梯度下降学习
############################################################################
        loss = network.loss(x_batch,y_batch)  # 计算损失值
        if num % 100 ==0:
            print("loss: ",loss)
#print(x_test.shape,y_test.shape)
print('准确率:',network.accuracy(x_test,y_test)*100,'%')  #将10000张图片让其识别,看看正确率

"""
我们随机选一张图片让其识别
"""
x_train=train_dataset.train_data.numpy().reshape(-1,28*28)  #将6万张28X28的图片,转换为一维数组
#print(x_train.shape)  #输出;(60000, 784)

import random
imgIndex = random.randint(0,x_train.shape[0]) #在60000张图片中任选一张

#取其中的一个图片
x1 = x_train[imgIndex].reshape(28,28)  #将一维数组转换为二阶矩阵 28X28,还原图片矩阵
#print(x1)  #输出28X28二维矩阵

p = network.predict(x1.reshape(-1,28*28))
p = np.argmax(p,axis=1)
print("预测:",p)

y_train = train_dataset.train_labels.numpy()  #转换为numpy数据
#print(y_train.shape) #输出torch.Size([60000]) ,有60000张图片的标签,正好与上面图片数量对应

y1 = y_train[imgIndex]
#print(y1)  #输出:5

#图片显示
import matplotlib.pyplot as plt
plt.imshow(x1,cmap=plt.cm.binary)  #显示图片设置
plt.title("predicted number:" + str(y1))
plt.show()

训练过程损失函数输出

current epoch is:0
loss:  2.266151231985748
loss:  0.3724026421914155
loss:  0.19832547560691383
loss:  0.22490945327141837
loss:  0.1661208009051106
loss:  0.258948805644127
current epoch is:1
loss:  0.13390206665995094
loss:  0.1320481015568629
loss:  0.07788363928512003
loss:  0.19471398981094826
loss:  0.06045146962828367
loss:  0.22834023219954858
current epoch is:2
loss:  0.08998278435494232
loss:  0.13953232891168038
loss:  0.05586382405036148
loss:  0.058314648911912174
loss:  0.09738683049424073
loss:  0.05205461861693841
current epoch is:3
loss:  0.045705761642539054
loss:  0.12238526156163801
loss:  0.07323083292990847
loss:  0.0800588072480463
loss:  0.06406958008082181
loss:  0.09598045459144477
current epoch is:4
loss:  0.08828214574587279
loss:  0.15144249360478873
loss:  0.08583687343851693
loss:  0.09221907715731381
loss:  0.03905677555959257
loss:  0.0632881118798391
准确率:96.23 %

神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

最后预测正确。

参考

【1】PyTorch_百度百科

【2】《深度学习与图像识别原理与实践》 魏溪含等著

Original: https://blog.csdn.net/laoxue123456/article/details/121429507
Author: 维度攻城狮
Title: 神经网络实现手写数字识别(代码-训练-效果)- PyTorch框架

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/720379/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球