[学习笔记]基于paddle(飞桨)的手写数字识别

发布时间:2022-06-08 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了[学习笔记]基于paddle(飞桨)的手写数字识别脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

放暑假了,但是还没有期末考试。

这个学期也算是学了不少神奇的东西,那就先回顾整理一下吧。

先是跟着学长的步骤使用百度的paddlepaddle框架进行入门学习,以后应该会转移到pytorch框架。

首先就是深度学习之中的“hello world”使用MINST中的数据集进行手写数字识别。

分为几个步骤吧:

1、环境搭建

2、学习历程

 

 

一、环境搭建(又一次折腾了许久)

本机环境:Win11,i7,GeForce卡

首先是安装cuda与cudnn

查了NVIDIA的表,本机的cuda需要11.x。因为手快了,直接安了一个11.6,但是paddle最高支持11.2,于是又卸载重来(环境混乱程度更盛)

因为百度那边貌似还没有win11版本的paddle,所以安装了win10版本的(虽然win11对win10的兼容性是不错的)

其次是安装Anaconda,用来创建和管理python的虚拟环境。(Anaconda是真的挺大的)

之后就是安装paddle了,直接用官网的命令一键安装。当时也是安装了许多遍没弄好最后发现是我自己代码的问题(哭)

 

二、学习历程

经历了千辛万苦地环境搭建,终于是能用了。

经过大概一周地学习,这个“hello world”我还是没有明白,一方面也和我的python不是很熟练有关。

还有对paddle的API们不是很明白

先贴代码,内容全在注释里。

 

# -*- coding: utf-8 -*-
# LeNet 识别手写数字# 训练使用的代码:train.py
From mpl_toolkITs.mplot3d import Axes3D#绘图所需库
from matplotlib import pyplot as plt#绘图所需的库
import numpy as np
import paddle
from model import LeNet#使用LeNet网络
from paddle.vision.transforms import ToTensor
from paddle.vision.datasets import MNIST
#epochs=[]#记录轮数的列表
#Loss=[]#记录每张图片LOSS的列表

def train(model, opt, train_loader, valid_loader):#opt:优化器 train_loader:评价集 valid_loader:训练集
    use_gpu = True#是否使用gpu
    paddle.device.set_device('gpu:0') if use_gpu else paddle.device.set_device('cpu')#0号gpu
    model.train()#切换到训练模式
    for epoch in range(EPOCH_NUM):
        for batch_id, data in enumerate(train_loader()):#将可遍历的对象组合为一个索引序列,用在for循环中   
            img = data[0]              #[10,1,28,28]
            label = data[1]            #[10,1]
            # 计算模型输出
            LOGits = model(img)
            # 计算损失函数
            loss_func = paddle.nn.CrossEntropyLoss(reduction='none')#交叉熵
            loss = loss_func(logits, label)
            avg_loss = paddle.mean(loss)

            if batch_id % 500 == 0:
                PRint("epoch: {}, batch_id: {}, loss is: {:.4f}".format(epoch+1, batch_id, float(avg_loss.numpy())))
            avg_loss.backward()
            opt.step()#反馈器,修改回调函数
            opt.clear_grad()

        model.eval()#评价模式
        accuracies = []#初始化两个列表
        losses = []
        for batch_id, data in enumerate(valid_loader()):
            img = data[0]#把图片放到评价集中
            label = data[1] 
            # 计算模型输出
            logits = model(img)
            # 计算损失函数
            loss_func = paddle.nn.CrossEntropyLoss(reduction='none')
            loss = loss_func(logits, label)
            acc = paddle.metric.accuracy(logits, label)#预测值,标签值
            accuracies.apPEnd(acc.numpy())
            losses.append(loss.numpy())
            #Loss.append(np.mean(losses))
        #print("[validation] accuracy/loss: {:.4f}/{:.4f}".format(np.mean(accuracies), np.mean(losses)))
        model.train()

    # 保存模型参数
    paddle.save(model.state_dict(), 'mnist.pdparams')#保存,模型‘’中是名字


model = LeNet(num_classes=10)
EPOCH_NUM = 5#训练轮数
opt = paddle.optimizer.Momentum(learning_rate=0.001, parameters=model.parameters())#定义优化器
train_loader = paddle.io.DataLoader(MNIST(mode='train', transform=ToTensor()), batch_size=20, shuffle=True)#定义训练集,从MINST中导入数据集
valid_loader = paddle.io.DataLoader(MNIST(mode='test', transform=ToTensor()), batch_size=20)#定义评价集               batch_Size:每次导入gpu的图片数量
train(model, opt, train_loader, valid_loader)#以下为可视化LOSS曲线的内容
'''
for i in np.arange(0,EPOCH_NUM,EPOCH_NUM/len(Loss)):#离散化,把图片映射在0-5
    epochs.append(i)
plt.xlabel('epochs')#用取得的列表绘制图像
plt.ylabel('Loss')
plt.title("一元一次函数")
plt.plot(epochs, Loss)
plt.show()
'''

model.py(用于构建卷积神经网络以备train.py调用)

import paddle
import numpy as np
from paddle.nn import Conv2D, Maxpool2D, Linear
import paddle.nn.functional as F

# 定义 LeNet 网络结构
class LeNet(paddle.nn.Layer):
    def __init__(self, num_classes=1):
        super(LeNet, self).__init__()
        self.conv1 = Conv2D(in_channels=1, out_channels=6, kernel_size=5)#维度,卷积核大小
        self.max_pool1 = MaxPool2D(kernel_size=2, stride=2)#一层卷积,一层池化
        self.conv2 = Conv2D(in_channels=6, out_channels=16, kernel_size=5)#二层卷积,二层池化
        self.max_pool2 = MaxPool2D(kernel_size=2, stride=2)
        self.conv3 = Conv2D(in_channels=16, out_channels=120, kernel_size=4)#三层卷积
        self.fc1 = Linear(in_features=120, out_features=64)
        self.fc2 = Linear(in_features=64, out_features=num_classes)
    def forward(self, x):                        #[N,1,28,28] 
        x = self.conv1(x)                        #[N,6,24,24]
        x = F.sigmoid(x)                         #[N,6,24,24]
        x = self.max_pool1(x)                    #[N,6,12,12]
        x = F.sigmoid(x)                         #[N,6,12,12]
        x = self.conv2(x)                        #[N,16,8,8]
        x = self.max_pool2(x)                    #[N,16,4,4]
        x = self.conv3(x)                        #[N,120,1,1]
        x = paddle.reShape(x, [x.shape[0], -1])  #[N,120]
        x = self.fc1(x)                          #[N,64] 全连接层
        x = F.sigmoid(x)                         #[N,64] 激活函数
        x = self.fc2(x)                          #[N,10] 线性层
        return x

test.py(测试模型的代码)

import numpy as np
import paddle
from model import LeNet
from paddle.vision.datasets import MNIST
from paddle.vision.transforms import ToTensor
import paddle.nn.functional as F
import matplotlib.pyplot as plt
import random
valid_loader = MNIST(mode='test', transform=ToTensor())#载入数据集
x=random.randint(0,100)
img = np.array(valid_loader[20][0])#获取一张图片


plt.imshow(img.squeeze(), cmap='gray')#这两行是从MINST中获取一张图片,并且显示之
plt.show()#以下为测试模型的部分
'''
model = LeNet(num_classes=10)#加载模型
model_dict = paddle.load("mnist.pdparams")#加载模型
model.set_state_dict(model_dict)#加载模型
model.eval()
x = valid_loader[0][0].reshape((1,1,28,28)).astype('float32')
plt.imshow(img.squeeze(), cmap='gray')
plt.show()
result = F.softmax(model(x))
print(result.numpy()[0])
'''

 

 

以上就是识别手写数字的全部内容,还有许多要学习。

脚本宝典总结

以上是脚本宝典为你收集整理的[学习笔记]基于paddle(飞桨)的手写数字识别全部内容,希望文章能够帮你解决[学习笔记]基于paddle(飞桨)的手写数字识别所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。