深度学习速成(4)Pytorch实现数字识别

四层网络结构实现数字识别,我们这里对MNIST进行处理,初始的MNIST是 28 * 28,我们把它处理成 96 * 96 的torch.Tensor的格式。

首先导入需要的包。

import torch
import numpy as np
import os                                                     #对文件,文件夹执行操作的一个模块。
from torch.utils.data import DataLoader
import torch.nn as nn                                         #torch.nn模块包含torch为我们准备好的各种层,方便我们调用以构建网络。
import torch.nn.functional as F                               #导入激活函数
from torch.optim import Adam                                  #导入优化器
from torchvision.datasets import MNIST                        #导入数据集
from torchvision.transforms import ToTensor,Compose,Normalize #导入三个方法

 1,准备数据集

先转变图片的格式,将其标准化,再对MNIST实例化,最后调用DataLoader对数据进行处理,批处理和打乱数据,返回处理好的数据。

BATCH_SIZE=128      #定义批处理一批的大小
#1,准备数据集
def get_dataloader(train=True):
    transform_fn=Compose([
        ToTensor(),#ToTensor()将shape为(H, W, C)的nump.ndarray或img转为shape为(C, H, W)的tensor,其将每一个数值归一化到[0,1]
        Normalize(mean=(0.1307,),std=(0.3081,))
    ])
    dataset=MNIST(root='./data',train=train,transform=transform_fn)         #实例化
    #root表示存放的位置,train表示使用训练集的数据还是测试集,download表示是否下载数据到root目录,transform实现对图片的处理函数
    #train=True表示训练集,train=False表示测试集
    data_loader=DataLoader(dataset,batch_size=BATCH_SIZE,shuffle=True)      #使用DataLoader对数据进行处理,批处理和打乱数据
    return data_loader

2,构建模型

构建自己的类,继承自基类nn.Module。

__init__()函数是调用基类的__init__()方法,forward()的作用是向前传播。

#2,构建模型
class MnistModel(nn.Module):                    #构建自己的类,继承自基类nn.Module
    def __init__(self):
        super(MnistModel,self).__init__()       #调用基类的__init__()方法
        self.fc1=nn.Linear(1*28*28,28)          #nn.Linear定义一个神经网络的线性层
        self.fc2=nn.Linear(28,10)

    def forward(self,input):
        #1.修改形状
        x=input.view([-1,1*28*28])              #-1表示该位置根据后面的形状自动调整
        #2.进行全连接的操作
        x=self.fc1(x)
        #3.经过激活函数的处理
        x=F.relu(x)
        #4.输出层
        out=self.fc2(x)
        #对数取值计算softmax并取对数,返回
        return F.log_softmax(out,dim=-1)

3,训练

输出的是轮次,索引,损失值(越小越好)

#3,训练
model=MnistModel()                           #把前面定义的模型实例化
optimizer=Adam(model.parameters(),lr=0.001)  #实例化,传模型的参数,学习率两个参数

if os.path.exists("./model/model.pkl"):                                  #如果路径存在
     model.load_state_dict(torch.load("./model/model.pkl"))              #加载已保存的数据
     optimizer.load_state_dict(torch.load("./model/optimizer.pkl"))      #加载已保存的数据

def train(epoch):
    data_loader=get_dataloader()                 #把函数处理过后的数据拿过来
    #这个循环进行训练操作
    for idx,(input,target) in enumerate(data_loader):#idx是索引,(input,target)是一个元组,(输入,目标值)
        #enumerate这个函数的基本应用就是用来遍历一个集合对象,它在遍历的同时还可以得到当前元素的索引位置。
        optimizer.zero_grad()                   #把梯度置为零
        output = model(input)                    #调用模型,得到预测值output
        loss=F.nll_loss(output,target)           #得到损失函数
        loss.backward()                          #反向传播
        optimizer.step()                         #梯度更新
        if idx%100==0:
            print(epoch,idx,loss.item())

        #模型的保存
        if idx % 100 == 0:
            torch.save(model.state_dict(),"./model/model.pkl")
            torch.save(optimizer.state_dict(), "./model/optimizer.pkl")

4,测试

输出平均损失和平均准确率。

def text():
    #定义两个列表来存放损失和准确率
    loss_list=[]
    acc_list=[]
    text_dataloader=get_dataloader(train=False)                #实例化,train=False表示测试集
    for idx, (input, target) in enumerate(text_dataloader):
        with torch.no_grad():
            output=model(input)
            cur_loss=F.nll_loss(output,target)                 #当前的损失
            loss_list.append(cur_loss)                         #存放损失
            #计算准确率
            pred=output.max(dim=-1)[-1]                        #预测值
            cur_acc=pred.eq(target).float().mean()             #float()转化为浮点数,mean()求均值
            acc_list.append(cur_acc)                           #存放准确率
    print("平均损失:",np.mean(loss_list),"平均准确率:",np.mean(acc_list))

5,运行

注释的代码是训练的代码。先训练,再测试。

#5,运行
if __name__=='__main__':

    # for i in range(3):
    #      train(i)
    for i in range(3):
        text()

训练的结果如下图示:

 

测试的结果如下图示:

 我们看到平均损失越来越小,准确率越来越高。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哥兜兜有糖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值