【pytorch 深度学习】7.pytorch手写数字识别

1.数据集下载

首先我们下载数据集并查看数据集:

import os
 
#third-party library
import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.utils.data as Data
import torchvision
import matplotlib.pyplot as plt
%matplotlib inline

torch.manual_seed(1)    # reproducible
 
#Hyper Parameters
EPOCH = 5               # train the training data n times, to save time, we just train 1 epoch
BATCH_SIZE = 50
LR = 0.001              # learning rate
DOWNLOAD_MNIST = False
 
 
#Mnist digits dataset
train_data = torchvision.datasets.MNIST(
    root='./mnist/',
    train=True,                                     # this is training data
    transform=torchvision.transforms.ToTensor(),    # Converts a PIL.Image or numpy.ndarray to
                                                    # torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0]
    download=True,
)
 
#plot one example
print(train_data.train_data.size())                 # (60000, 28, 28)
print(train_data.train_labels.size())               # (60000)
plt.imshow(train_data.train_data[0].numpy(), cmap='gray')
plt.title('%i' % train_data.train_labels[0])
plt.show()

结果如下:
在这里插入图片描述

2. 定义网络

网络定义如下:

import torch.nn.functional as F

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=5)
        self.conv2 = nn.Conv2d(32, 32, kernel_size=5)
        self.conv3 = nn.Conv2d(32,64, kernel_size=5)
        self.fc1 = nn.Linear(3*3*64, 256)
        self.fc2 = nn.Linear(256, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        #x = F.dropout(x, p=0.5, training=self.training)
        x = F.relu(F.max_pool2d(self.conv2(x), 2))
        x = F.dropout(x, p=0.5, training=self.training)
        x = F.relu(F.max_pool2d(self.conv3(x),2))
        x = F.dropout(x, p=0.5, training=self.training)
        x = x.view(-1,3*3*64 )
        x = F.relu(self.fc1(x))
        x = F.dropout(x, training=self.training)
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

3.训练

我将batch_size设置为50,即每50个数据作一次训练,epoch设置为5,即全部数据总共训练五次。
训练数据准备:

train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)

训练:

net=CNN().cuda()
optimizer = torch.optim.Adam(net.parameters(), lr=LR)   # optimize all cnn parameters
loss_func = nn.CrossEntropyLoss()                       # the target label is not one-hotted
def train_mnist(train_loader,net,optimizer,loss_func):
   l_his = []   # 记录 training 时不同神经网络的 loss
   acc_his = []   # 记录 training 时不同神经网络的 准确率
   # training and testing
   for epoch in range(5):
       right_num=0
       print("start!")
       for step, (x, y) in enumerate(train_loader):   # gives batch data, normalize x when iterate train_loader
           v_x=Variable(x).cuda()
           v_y=Variable(y).cuda()
           out = net(v_x)  #这里省略了 mo_net.forward()
           loss = loss_func(out,v_y)
           #--------------------用于预测对的个数-------------------------#
           out_class=torch.max(out.data, 1)[1].data.squeeze()  
           right_num +=(out_class==v_y).sum().float()  #分类对的数值,因为每次对50个数据处理,所以预测对的个数是加起来
           #--------------------求预测对的个数结束-------------------------#
           optimizer.zero_grad()    
           loss.backward()
           optimizer.step()
           if (step + 1) % 50 == 0:
               l_his.append(loss.data[0])
               acc_his.append(right_num/((step+1)*50))
           if (step + 1) % 500 == 0:
               print('epoch:{},step : {}, loss: {},precision{},right_num{}'.format(epoch+1,step +1, loss.data[0],right_num/((step+1)*50),right_num))
   return l_his,acc_his,net
   
l_his,acc_his,net=train_mnist(train_loader,net,optimizer,loss_func)
x1=list(range(len(l_his)))
plt.plot(x1, l_his,c='red',label='loss')
plt.plot(x1, acc_his,c='blue',label='precision')
plt.legend()            

结果:
在这里插入图片描述
图:
在这里插入图片描述

4.测试

test_data = torchvision.datasets.MNIST(root='./mnist/', train=False)
test_x = Variable(torch.unsqueeze(test_data.test_data, dim=1), volatile=True).type(torch.FloatTensor)[:2000]/255.   # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
test_y = test_data.test_labels[:2000]
v_x_test=Variable(test_x).cuda()
v_y_test=Variable(test_y).cuda()
def test_mnist(v_x_test,v_y_test,net):
    out_test=net(v_x_test) 
    loss_test = loss_func(out_test, v_y_test)
    out_class=torch.max(out_test.data, 1)[1].data.squeeze()  #将out矩阵中大于0的转化为1,小于0的转化为0,存入a中
    right_num_test =(out_class==v_y_test).sum().float()  #分类对的数值
    precision_test=right_num_test/out_test.shape[0]  #准确率
    loss_test=loss_test.data[0]
    print('loss_test:{},precision_test:{},right_num_test:{}'.format(loss_test,precision_test,right_num_test))
test_mnist(v_x_test,v_y_test,net)

结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值