手写体识别代码加超详细解释(pytorch+anaconda)

    # 1加载必要的库
import torch
import torch.nn as nn       #加入网络模型torch.nn,用nn作为代号,他是专门用于神经网络设计的模块化接口。有nn.Parameter;nn.linear;nn.functionann.Module;nn.Sequential
import torch.nn.functional as F  #创建了神经网络里面常用的处理函数。如没有激活函数的神经元,各种激活函数等等
                                    #https://blog.csdn.net/HiWangWenBing/article/details/120614234?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169837708216800188571816%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=169837708216800188571816&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-120614234-null-null.142^v96^pc_search_result_base9&utm_term=torch.nn%E5%BA%93&spm=1018.2226.3001.4187
import torch.optim as optim   #主要包含模型训练的优化器Optimizer,主要优化算法有SGD,adam,adagrad等等
from torchvision import datasets,transforms      #对数据库进行操作,包括transformation提供支持
torch.__version__ 
from torch.utils.data import DataLoader#datasets提供常用的数据集加载,transforms,提供常用的数据预处理操作 
   # 2定义超参数
BATCH_SIZE = 512 #每一批处理的数据
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")  #如果有gpu就用设备gpu,否则就用cpu
EPOCHS = 10 #训练数据集的轮数
   # 3构建pipeline(transforms),对图像做处理
pipeline = transforms.Compose([
    transforms.ToTensor(),#将图片转化为tensor
    transforms.Normalize((0.137,),(0.3081,))#正则化,防止模型出现过拟合的时候降低模型复杂度
    ])
    
   #下载、加载数据
from torch.utils.data import DataLoader 
    #下载数据
train_set = datasets.MNIST("data",train=True,download =True,transform=pipeline)
    #从MNIST里面下载训练数据,放入data文件里面,用pipe对图像做处理
test_set = datasets.MNIST("data",train=False,download =True,transform=pipeline)
    #和上面类似
    #加载数据
train_loader = DataLoader(train_set,batch_size= BATCH_SIZE,shuffle =True) 
    
test_loader = DataLoader(test_set,batch_size=BATCH_SIZE,shuffle =True)
    

#4 插入代码,显示MNIST的图片
with open("./data/MNIST/raw/train-images-idx3-ubyte","rb") as f:
    file =f.read()
#读取图片
imagel = [int(str(item).encode('ascii'),16) for item in file [16:16+784]]  #16+784存储的是图片
print(imagel) #输出图片
#显示保存
import cv2 
import numpy as np
imagel_np = np.array(imagel,dtype=np.uint8).reshape(28,28,1)  #先转化为数组形式,类型是无符号整型,因为是灰度,所以通道是1不是3
print(imagel_np.shape)#打印出来图片的高宽

cv2.imwrite("digit.jpg",imagel_np) #保存图片
  #5 构建网络模型
class Digit(nn.Module):    #构建一个Digit的网络模型,继承于父类Moudle
    def __init__(self):    #构造方法
        super().__init__()  #调用父类构造方法
                #卷积层
        self.conv1 = nn.Conv2d(1,10,5)  # 1:灰度图片的通道,也就是输入通道, 10:输出通道 5:卷积核
        self.conv2 = nn.Conv2d(10,20,3)  #  10: 输入通道  20:输出通道 3 :卷积核
                #全连接层
        self.fc1 = nn.Linear (20*10*10 ,500)  #20*10*10  输入通道, 500 输出通道
        self.fc2 = nn.Linear (500,10) #500:输入通道  10:输出通道
            
    def forward(self ,x):  #前向传播
        input_size = x.size(0) #取得是batch_size ,取的是第一个  格式是 batch_size x1 x28 x28
                #卷积
        x = self.conv1(x) #把数据丢进刚刚建立的卷积层里面去
                                    #输入:batch*1*28*28  ,输出 :batch*10*24*24(28-5+1=24)
                #激活
        x =F.relu(x)
                #池化
        x = F.max_pool2d(x,2,2)  #对图片进行压缩,减少数据量  卷积核2,步长2
                                          #输入:batch*10*24*24  输出:batch*10*12*12 (24/2)
                #重复卷积激活池化
        x =self.conv2(x) #输入:batch*10*12*12  输出:batch*20*10*10(12-3+1)
        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) #激活,shape不变  这里第一层就结束了
                
        x =self.fc2(x) #输入:batch *500  ,输出 10
                
                #返回是哪个数字最大的概率
        output= F.log_softmax(x,dim=1)
        return output
# 6定义优化器
model = Digit().to(DEVICE)

optimizer =optim.Adam(model.parameters())
  #7 定义训练方法
def train_model (model ,device ,train_loader,optimizer,epoch):#把模型,设备和训练集,优化器,epoch传入进去
        #模型训练
    model.train()
    for batch_index,(data,target) in enumerate(train_loader):   #batch_index,数据下标;从train_loader里面读取数据,一个是data(图片),一个是target(标签)
               #enmuerate函数如下   
               #部署到DEVICE上面
            data,target =data.to(device),target.to(device)
               #梯度初始化为0
            optimizer.zero_grad()
                #训练后的结果
            output =model(data)
                #计算损失,用output和target计算
            loss =F.cross_entropy(output,target)
                #反向传播
            loss.backward()
                #参数优化
            optimizer.step()
            if batch_index % 3000 ==0:
                    print("Train Epoch :{} \t Loss : {:.6f}".format(epoch,loss.item()))

  #8 定义测试方法
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)
            #计算测试损失
            test_loss +=F.cross_entropy(output,target).item()
            pred = torch.max(output.data ,1)[1]
            correct += pred.eq(target.view_as(pred)).sum().item()
            #找到概率值的最大下标
            #pred =output.max(1,keepdim=True)#值,索引
            #计算正确的值
            #correct += pred.eq(target.view_as(pred)).sum().item()
        test_loss /=len(test_loader.dataset)
        print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))
       # print("Test--Average loss:{:.4f},Accuracy :{:3.f}\n".format(
        #       test_loss,100.0*correct / len(test_loader.dataset)))
    
  # 9  调用  方法7/8
for epoch in range (1,EPOCHS+1):
    train_model(model,DEVICE,train_loader,optimizer,epoch)
    test_model(model,DEVICE,test_loader)

结果:

Train Epoch :1 	 Loss : 2.312109

Test set: Average loss: 0.0002, Accuracy: 9748.0/10000 (97%)

Train Epoch :2 	 Loss : 0.118887

Test set: Average loss: 0.0001, Accuracy: 9848.0/10000 (98%)

Train Epoch :3 	 Loss : 0.052688

Test set: Average loss: 0.0001, Accuracy: 9846.0/10000 (98%)

Train Epoch :4 	 Loss : 0.018144

Test set: Average loss: 0.0001, Accuracy: 9829.0/10000 (98%)

Train Epoch :5 	 Loss : 0.043597

Test set: Average loss: 0.0001, Accuracy: 9879.0/10000 (99%)

Train Epoch :6 	 Loss : 0.024002

Test set: Average loss: 0.0001, Accuracy: 9874.0/10000 (99%)

Train Epoch :7 	 Loss : 0.018111

Test set: Average loss: 0.0001, Accuracy: 9895.0/10000 (99%)

Train Epoch :8 	 Loss : 0.015440

Test set: Average loss: 0.0001, Accuracy: 9912.0/10000 (99%)

Train Epoch :9 	 Loss : 0.027070

Test set: Average loss: 0.0001, Accuracy: 9889.0/10000 (99%)

Train Epoch :10 	 Loss : 0.013400

Test set: Average loss: 0.0001, Accuracy: 9859.0/10000 (99%)
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值