入门深度学习——基于全连接神经网络的手写数字识别案例(python代码实现)

2023-11-06

入门深度学习——基于全连接神经网络的手写数字识别案例(python代码实现)

一、网络构建

1.1 问题导入

如图所示,数字五的图片作为输入,layer01层为输入层,layer02层为隐藏层,找出每列最大值对应索引为输出层。根据下图给出的网络结构搭建本案例用到的全连接神经网络
在这里插入图片描述

1.2 手写字数据集MINST

如图所示,MNIST数据集是机器学习领域中非常经典的一个数据集,由60000个训练样本和10000个测试样本组成,每个样本都是一张28 * 28像素的灰度手写数字图片。数据集也被嵌入到sklearn和pytorch框架中可以直接调用。这里我们默认已经安装了pytorch框架。不会使用的这里简单介绍一下。
大家可以用按住win+R键,打开运行窗口,输入cmd。
在这里插入图片描述
输入cmd,回车后,会显示如下。
在这里插入图片描述
输入以下的命令,可以看看自己的电脑的显卡是不是NVIDIA。如果是AMD的,那么就安装cpu的吧,毕竟CUDA内核,只支持NVIDIA的显卡。

#AMD显卡
pip install pytorch-cpu
#NVIDIA显卡
pip install pytorch
#如果速度慢的话,可以加入清华源的链接
pip install pytorch-cpu -i https://pypi.tuna.tsinghua.edu.cn/simple/
#NVIDIA显卡
pip install pytorch -i https://pypi.tuna.tsinghua.edu.cn/simple/

这样就完成了,仍然存在问题的小伙伴,可以参考小程序员推荐的这个up主的教程pytorch保姆级教程
这里我们输出几张图片和对应的标签。作为对数据集的了解,也方便我们针对性的设计网络结构,做到心中有数。
在这里插入图片描述

二、采用Pytorch框架编写全连接神经网络代码实现手写字识别

2.1 导入必要的包

import torch
import numpy as np
from torch import nn
import torch.nn.functional as F
from torchvision import datasets,transforms
from torch.utils.data import DataLoader

2.2 定义一些数据预处理操作

pipline=transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5],[0.5])])

2.3 下载数据集(训练集vs测试集)

train_dataset=datasets.MNIST('./data',train=True,transform=pipline,download=True)
test_dataset=datasets.MNIST('./data',train=False,transform=pipline,download=True)
print(len(train_dataset))
print(len(test_dataset))

60000
10000

2.4 分批加载训练集和测试集中的数据到内存里

train_loader=DataLoader(train_dataset,batch_size=32,shuffle=True)
test_loader=DataLoader(test_dataset,batch_size=32)

2.5 可视化数据集中的数据,做到心中有数

import matplotlib.pyplot as plt
examples=enumerate(train_loader)
_,(example_data,example_label)=next(examples)
print(example_data.shape)
for i in range(6):
    plt.subplot(2,3,i+1)
    plt.tight_layout()
    plt.imshow(example_data[i][0],cmap='gray')
#     plt.title('Ground Truth:{}'.format(example_label[i]))
    plt.title(f'Ground Truth:{example_label[i]}')

torch.Size([32, 1, 28, 28])
在这里插入图片描述

2.6 网络模型设计(有时也称为网络模型搭建)

class Net(nn.Module):
    def __init__(self,in_dim,n_hidden_1,n_hidden_2,out_dim):
        super(Net,self).__init__()
        self.layer1=nn.Sequential(nn.Linear(in_dim,n_hidden_1),nn.ReLU(True))
        self.layer2=nn.Sequential(nn.Linear(n_hidden_1,n_hidden_2),nn.Sigmoid())
        self.layer3=nn.Linear(n_hidden_2,out_dim)    
        
    def forward(self,x):
        x=self.layer1(x)
        x=self.layer2(x)
        x=self.layer3(x)
        return x
model=Net(28*28,300,100,10)
model

以下结果来自Jupyter Notebook
Net(
(layer1): Sequential(
(0): Linear(in_features=784, out_features=300, bias=True)
(1): ReLU(inplace=True)
)
(layer2): Sequential(
(0): Linear(in_features=300, out_features=100, bias=True)
(1): Sigmoid()
)
(layer3): Linear(in_features=100, out_features=10, bias=True)
)

import torch.optim as optim
criterion=nn.CrossEntropyLoss()   #选用Pytorch中nn模块封装好的交叉熵损失函数
optimizer=optim.SGD(model.parameters(),lr=0.01,momentum=0.5)  #选用随机梯度下降法(SGD)作为本模型的梯度下降法
device=torch.device('cuda' if torch.cuda.is_available() else 'cpu')   #确定代码运行设备究竟实在GPU还是CPU上跑
model.to(device)

2.7 训练网络模型

losses=[]
acces=[]

eval_losses=[]
eval_acces=[]

#训练轮数---epoch

for epoch in range(10):
    train_loss=0
    train_acc=0
    model.train()   #启用网络模型隐藏层中的dropout和BN(批归一化)操作
    
    if epoch%5==0:   #控制训练轮数间隔
        optimizer.param_groups[0]['lr']*=0.9    #动态调整学习率
        
    for img,label in train_loader:
        img=img.to(device)   #将训练图片写到设备里
        label=label.to(device)  #将图片类别写到设备里
        img=img.view(img.size(0),-1)
        
        out=model(img)   #调用前向传播函数得到预测值
        loss=criterion(out,label)   #计算预测值和真实值的损失
        
        optimizer.zero_grad()  #在新一轮反向传播开始前,清空上一轮反向传播得到的梯度
        loss.backward()  #把上一部得到的损失执行反向传播,得到新的网络模型参数(权值)
        optimizer.step()   #把上一部得到的新的权值更新到网络模型里
        
        #在前面前向传播和反向传播的额基础上,计算一些训练算法性能指标
        
        train_loss+=loss.item()  #记录反向传播每一轮得到的损失
        
        _,pred=out.max(1)   #得到图片的预测类别
        
        num_correct=(pred==label).sum().item()   #获取预测正确的样本数量
        acc=num_correct/img.shape[0]      #每一批次的正确率
        train_acc+=acc       #每一轮次的额正确率
        
    losses.append(train_loss/len(train_loader))    #所有轮次训练完之后总的损失
    acces.append(train_acc/len(train_loader))     #所有轮次训练完之后总的正确率

2.8 在测试集上测试网络模型,检验模型效果

eval_loss=0
eval_acc=0
model.eval()   #继续沿用BN操作,但是不再使用dropout操作

with torch.no_grad():
    for img,label in test_loader:
        img=img.to(device)
        label=label.to(device)
        
        img=img.view(img.size(0),-1)
        
        out=model(img)
        loss=criterion(out,label)
        
        eval_loss+=loss.item()   #记录每一批次的损失
        
        _,pred=out.max(1)
        
        num_correct=(pred==label).sum().item()
        acc=num_correct/img.shape[0]   #记录每一批次的准确率
        eval_acc+=acc     #记录每一轮的准确率
        

    eval_losses.append(eval_loss / len(test_loader))
    eval_acces.append(eval_acc / len(test_loader))
    print('epoch: {}, Train Loss: {:.4f}, Train Acc: {:.4f}, Test Loss: {:.4f}, Test Acc: {:.4f}'
      .format(epoch, train_loss / len(train_loader), train_acc / len(train_loader), 
                 eval_loss / len(test_loader), eval_acc / len(test_loader)))

epoch: 0, Train Loss: 1.1721, Train Acc: 0.6760, Test Loss: 0.4936, Test Acc: 0.8692
epoch: 1, Train Loss: 0.4093, Train Acc: 0.8866, Test Loss: 0.3368, Test Acc: 0.9020
epoch: 2, Train Loss: 0.3192, Train Acc: 0.9084, Test Loss: 0.2884, Test Acc: 0.9171
epoch: 3, Train Loss: 0.2755, Train Acc: 0.9194, Test Loss: 0.2552, Test Acc: 0.9271
epoch: 4, Train Loss: 0.2429, Train Acc: 0.9290, Test Loss: 0.2251, Test Acc: 0.9349
epoch: 5, Train Loss: 0.2160, Train Acc: 0.9367, Test Loss: 0.2001, Test Acc: 0.9405
epoch: 6, Train Loss: 0.1945, Train Acc: 0.9433, Test Loss: 0.1854, Test Acc: 0.9447
epoch: 7, Train Loss: 0.1761, Train Acc: 0.9494, Test Loss: 0.1716, Test Acc: 0.9504
epoch: 8, Train Loss: 0.1601, Train Acc: 0.9540, Test Loss: 0.1597, Test Acc: 0.9527
epoch: 9, Train Loss: 0.1468, Train Acc: 0.9572, Test Loss: 0.1434, Test Acc: 0.9567

2.10可视化训练及测试的损失值

plt.title('Train Loss')
plt.plot(np.arange(len(losses)),losses);
plt.legend(['Train Loss'],loc='upper right')                   

损失函数的结果:
在这里插入图片描述

三、代码文件

小程序员将代码文件和相关素材整理到了百度网盘里,因为文件大小基本不大,大家也不用担心限速问题。后期小程序员有能力的话,将在gitee或者github上上传相关素材。
链接:https://pan.baidu.com/s/1Ce14ZQYEYWJxhpNEP1ERhg?pwd=7mvf
提取码:7mvf

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

入门深度学习——基于全连接神经网络的手写数字识别案例(python代码实现) 的相关文章

随机推荐

  • Java架构直通车——以JDBC为例谈双亲委派模型的破坏

    文章目录 引入 JDBC4 0之前 JDBC4 0之后 引入 java给数据库操作提供了一个Driver接口 public interface Driver Connection connect String url java util P
  • apache工程jakarta(雅加达)家族介绍

    Apache Ant Project Ant 众所周知 Ant 蚂蚁 是一套基于java的程序打造工具 Apache Avalon Project 阿瓦隆 Avalon Avalon 阿瓦隆 凯尔特族传说中的西方乐土岛 据说亚瑟王及其部下死
  • 【数据结构理论】图

    定义 图由顶点集V和边集E组成 线性表和树都可以是空的 但图不可为空 但图的边集可以是空集 E是有向边 无向边决定图是有向图 无向图 AB为两端点 E的集合若是无向边 则E A B 若E的集合是有向边 则E
  • datagrid控件讲解

    使用场景 软件 VisualStudio 视图引擎 Razor编辑器 后台编程语言 C 引入 table class easyui datagrid table 配置格式 function initGrid ttt datagrid 配置各
  • CobalStrike的部署(附带资源)

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 CobalStrike是什么 二 CobalStrike的部署 总结 前言 作为刚入门网安的小白 挺久之前 就曾听说过CobalStrike这样的一个Re
  • 10LinuxC线程学习之pthread_detach函数,错误返回值分析及其案例

    1 pthread detach函数 int pthread detach pthread t thread 功能 1 实现线程分离 不再受主线程管理 由系统接任 线程结束后 其退出状态不由其他线程获取 而直接自己自动释放 网络 多线程服务
  • TypeScript 封装 Axios

    TypeScript 封装 Axios TypeScript 封装 Axios 为什么需要封装 axios 因为直接在项目中使用 axios axios 的 api 将会嵌入代码的各个地方 耦合程度太高 如果后期更换 Ajax 请求库 将会
  • QT学习笔记02信号与槽简介

    标准信号和槽 信号槽是 Qt 框架引以为豪的机制之一 所谓信号槽 实际就是观察者模式 当某个事件发生之后 比如 按钮检测到自己被点击了一下 它就会发出一个信号 signal 这种发出是没有目的的 类似广播 如果有对象对这个信号感兴趣 它就会
  • OpenTelemetry 项目解读

    点击一键订阅 云荐大咖 专栏 获取官方推荐精品内容 学技术不迷路 随着分布式应用越来越普遍 分布式应用需要依赖强大的可观测性设施来提供监控保障 强大的可观测性设施需要依赖高质量的遥测数据 虽然已经有许多开源或者商业供应商提供了遥测数据监测采
  • 华为eNSP实验-防火墙模拟配置(采用ping命令逐步分析)

    ensp防火墙模拟配置 采用ping命令逐步分析 1 各设备的IP地址配置 按如图所示配置好各个设备对应的IP地址 注意点 1 图中cloud2云处需要关联电脑上对应的虚拟网卡 2 实验中我使用的是华为USG6000V防火墙 需要下载软件包
  • 用批处理写修改注册表的命令

    一般书写格式 reg add 注册表路径 v 值名 t 要修改的数值类型 d 想要输入的数据 f 这个选项可根据情况自行添加 意为不用提示就强行改写现有注册表项 如果在批处理中不想显示出命令执行过程可以再reg前面加入 后面加上 gt nu
  • 使用python安装nginx

    肯定有小伙伴疑问哈 安装nginx仅仅需要几条命令如果只是单单安装简单使用os system os Popen几乎就足以完成 那么为什么要写这么多呢 笔者在写这段代码的时候一个是想让代码更加美观 显得比较专业 另一方面无论安装什么 配置什么
  • 前端 js实现模糊搜索

    前端 js实现模糊搜索 template
  • 全世界最好的编辑器VIM之Windows配置(gvim)

    全世界最好的编辑器VIM之Windows配置 gvim vundle插件管理 NERDTree插件 ctrlp插件 vim nerdtree tabs插件等 vim本来就是很强大 很方便的编辑器 再加上这些杀手级的插件 那就真的无敌了 官方
  • Caused by:org.springframework.beans.factory.NoSuchBeanDefinitionException:No qualifying bean of type

    今天使用Junit单元测试写了个测试spring的AnnotationConfigApplicationContext 的测试方法 代码如下 public class TestApplicationContext Test 较为经典的容器
  • 大数据学习-4.Hadoop运行环境搭建(二)

    文章目录 一 下载JDK和Hadoop安装包 二 安装JDK 三 安装Hadoop 1 单机模式搭建 2 分布式模式搭建 一 下载JDK和Hadoop安装包 下载地址 阿里云 提取码 q6y6 二 安装JDK 测试主机是否有java环境 如
  • 电磁场与电磁波第二章 电磁场的基本规律

    文章目录 第二章 电磁场的基本规律 电荷守恒定律 1 电荷与电荷密度 2 电流与电流密度 3 电荷守恒定律 电流连续性方程 真空中静电场的基本规律 1 库仑定律 电场强度 1 电场强度 2 几种典型电荷分布的电场强度 2 静电场的散度与旋度
  • 博弈论中存在的先动优势和后动优势

    博弈论中存在的先动优势和后动优势 完全信息动态博弈 Stackel berg寡头竞争模型属于先动优势 轮流出价的讨价还价模型 当均衡结果与T无关的时候且 1 贴现因子 2 1 双方无限的耐心 时 存在后动优势 因为他将拒绝任何自己不能得到全
  • idea中java源码英文注释的翻译

    效果展示 操作步骤两步 安装translation插件 设置翻译引擎 安装translation插件 选择该插件 安装好后重启idea即可使用 设置翻译引擎 这里用有道翻译演示 注册好后在业务里面创建翻译接口 创建好后把id和密钥复制填上去
  • 入门深度学习——基于全连接神经网络的手写数字识别案例(python代码实现)

    入门深度学习 基于全连接神经网络的手写数字识别案例 python代码实现 一 网络构建 1 1 问题导入 如图所示 数字五的图片作为输入 layer01层为输入层 layer02层为隐藏层 找出每列最大值对应索引为输出层 根据下图给出的网络