手写数字识别

手写数字识别

本文非常详细的介绍了每行代码的作用,能够非常容易的入门深度学习。

#加载必要的库
import torch
#nn网络库
import torch.nn as nn
import torch.nn.functional as F
#优化器
import torch.optim as optim
from torchvision import datasets, transforms
#画图
import matplotlib.pyplot as plt


#定义超参数
#batch_size批处理。每次处理的数据数量,
#意思为将海量的数据分批输入电脑中减少压力,一般设置为64,128,根据设备的性能调节
BATCH_SIZE = 64
#如果有GPU则用GPU训练,否则用cpu训练
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
#训练数据集的轮次,意思是你可以选择将6万张照片训练一次、10次、100次。。。。
EPOCHS = 20

#构建pipeline也就transfoms,对图像进行处理
#可以对图片转换成tensor,旋转图片,以及正则化,明亮度,等等进行处理
pipeline = transforms.Compose([
    transforms.ToTensor(),#将图片转换成tensor格式
    #nomalize正则化。模型出现过拟合现象时,降低模型复杂度
    #过拟合的含义:例如你训练出的模型只认识你自己写的字迹,你朋友写的字迹就不认识了。只认识见过的一模一样的,稍微改变一点就不认识了。
    transforms.Normalize((0.1307,), (0.3081,)) #正则化,如果不确定取多少值,那就选择这个官网给的值
])

#下载、加载数据·
#dataloader对数据进行处理
from torch.utils.data import DataLoader
#下载数据集
#train训练集train是true,test集train就要是false假了,transform=pipline是将数据transfom对数据处理
train_set = datasets.MNIST("data", train=True, download=True, transform=pipeline)
test_set =datasets.MNIST("data", train=False, download=True, transform=pipeline)
#加载数据
#shuffle=True是将图片打乱,是训练图片无顺序,有助于模型精度提高
train_loader = DataLoader(train_set, batch_size=BATCH_SIZE, shuffle=True)
test_loader = DataLoader(test_set, batch_size=BATCH_SIZE, shuffle=True)

#构建网络模型
class Digit(nn.Module): #构建名叫Digit网络模型继承nn.Module
    def __init__(self): #构造方法
        super().__init__() #调用方法
        self.conv1 = nn.Conv2d(1, 10, 5)#卷积层第1层 1: 灰度图片通道 10:输出通道 5:kernel卷积核
        self.conv2 = nn.Conv2d(10, 20, 3)#卷积层第2层 10:输入通道 20输出通道 3:kernel卷积核
        self.fc1 = nn.Linear(20*10*10, 500)#全连接层1 20*10*10:输入通道 ,500输出通道
        self.fc2 = nn.Linear(500, 10)#全连接层2 500:输入通道 10输出通道

        #前向传播
    def forward(self, x):
        input_size = x.size(0) #batch_size*1*28*28为1灰度28是像素
        x = self.conv1(x) #batch*1*28*28 ,输出:batch*10*24*24   24是28-5+1=24
        x = F.relu(x)#激活函数的作用就是,在所有的隐藏层之间添加一个激活函数,这样的输出就是一个非线性函数,神经网络的表达能力就更加强大了 保持shpae不变,输出:batch*10*24*24
        x = F.max_pool2d(x, 2, 2) #池化层,将特征更加明显,不明显的忽略。类似于降噪。 输入:batch*10*24*24 输出:batch*10*12*12


        x = self.conv2(x)#卷积层二层 输入:batch*10*12*12 输出层:batch*20*10*10 (12-3+1=10)
        x = F.relu(x)

        x = x.view(input_size, -1)#拉伸,将矩阵形式的图片拉伸成一列 -1自动计算维度,20*10*10=2000

        x = self.fc1(x) #输入:batch*2000 输出:batch*500
        x = F.relu(x)

        x = self.fc2(x) #输入:batch*500 输出:batch*10

        output = F.log_softmax(x, dim=1) #计算分类后,每个数字的概率值

        return output #返回概率值

#定义optimizer优化器 作用更新模型参数,使得最终的训练和测试的结果达到最优值
model = Digit().to(DEVICE)
optimizer = optim.Adam(model.parameters())

#定义训练的函数方法
def train_model(model, device, train_loader, optimizr, epoch):
    #模型训练
    model.train() #调用模型的train方法开始训练
    #batch_index每次读取下标, target是标签例如图片是5,则标签是5.
    for batch_index, (data, target) in enumerate(train_loader):
        #把训练部署到设备上去
        data, target = data.to(device), target.to(device)
        #梯度初始化为0
        optimizer.zero_grad()
        #训练后的结果
        output = model(data)
        #计算损失 损失用function中的函数cross_entropy计算,cross_entropy是交叉熵损失,交叉熵损失适用于多分类的任务
        loss = F.cross_entropy(output, target)
        #找到概率值最大的下标
        pred = output.max(1, keepdim=True)
        #反向传播
        loss.backward()
        #参数的更新优化
        optimizer.step()
        #每隔3000张图片打印一次结果
        if batch_index % 3000 == 0:
            #format是进行格式化的转换
            print("Train Epoch : {}\t Loss : {:.6f}".format(epoch,loss.item()))
# 定义测试方法
def test_model(model, device, test_loader):
    # 模型验证
    model.eval()
    #正确率初始化
    correct = 0.0
    #测试损失初始化
    test_loss = 0.0
    with torch.no_grad():#不计算梯度,也不会进行反向传播
        for data, target in test_loader:
            #部署到device上
            data, target = data.to(device), target.to(device)
            #测试后的结果
            output = model(data)
            #累计测试损失 损失用function中的函数cross_entropy计算,cross_entropy是交叉熵损失,交叉熵损失适用于多分类的任务
            test_loss += F.cross_entropy(output, target).item()
            #找到概率值最大的下标 
            pred = output.max(1, keepdim=True)[1]
            #累计正确的值
            correct += pred.eq(target.view_as(pred)).sum().item()
        #测试损失率
        test_loss /= len(test_loader.dataset)
        #正确率
        correct  /= len(test_loader.dataset)
        #{:.4f} 表示小数点后4位
        print("Test --Average loss:{:.4f},Accuracy : {:.3f}\n".format(
            test_loss, 100.0 * correct))
            # correct 是测试正确的  len(test_loader.dataset)是数据集。相除得到正确率
#调用方法7/8
for epoch in range(1,EPOCHS +1):
    train_model(model,DEVICE,train_loader,optimizer,epoch)
    test_model(model,DEVICE,test_loader)

https://github.com/haonanzhang314/Machine-Learning.git

这是代码实现的效果。对于数字的识别率能达到很好的效果

Train Epoch : 1 Loss : 2.300396
Test --Average loss:0.0008,Accuracy : 98.450

Train Epoch : 2 Loss : 0.023347
Test --Average loss:0.0009,Accuracy : 98.150

Train Epoch : 3 Loss : 0.058859
Test --Average loss:0.0005,Accuracy : 99.090

Train Epoch : 4 Loss : 0.021332
Test --Average loss:0.0007,Accuracy : 98.510

Train Epoch : 5 Loss : 0.020462
Test --Average loss:0.0006,Accuracy : 98.880

Train Epoch : 6 Loss : 0.000924
Test --Average loss:0.0005,Accuracy : 99.080

Train Epoch : 7 Loss : 0.001011
Test --Average loss:0.0007,Accuracy : 98.870

Train Epoch : 8 Loss : 0.019741
Test --Average loss:0.0006,Accuracy : 98.950

Train Epoch : 9 Loss : 0.001917
Test --Average loss:0.0006,Accuracy : 98.970

Train Epoch : 10 Loss : 0.000443
Test --Average loss:0.0007,Accuracy : 99.110

Train Epoch : 11 Loss : 0.000591
Test --Average loss:0.0006,Accuracy : 99.120

Train Epoch : 12 Loss : 0.000635
Test --Average loss:0.0010,Accuracy : 98.700

Train Epoch : 13 Loss : 0.000753
Test --Average loss:0.0009,Accuracy : 98.770

Train Epoch : 14 Loss : 0.005622
Test --Average loss:0.0009,Accuracy : 98.980

Train Epoch : 15 Loss : 0.000257
Test --Average loss:0.0009,Accuracy : 98.910

Train Epoch : 16 Loss : 0.000005
Test --Average loss:0.0010,Accuracy : 98.950

Train Epoch : 17 Loss : 0.000008
Test --Average loss:0.0008,Accuracy : 99.150

Train Epoch : 18 Loss : 0.000107
Test --Average loss:0.0009,Accuracy : 99.040

Train Epoch : 19 Loss : 0.000948
Test --Average loss:0.0011,Accuracy : 98.920

Train Epoch : 20 Loss : 0.000151
Test --Average loss:0.0009,Accuracy : 98.900

GitHub链接 https://github.com/haonanzhang314/Machine-Learning.git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值