PyTorch使用CNN对手写数字进行识别

  MNIST数据集是学习各种神经网络的开胃菜。它的任务是识别手写数字(1~9),具体介绍官网http://yann.lecun.com/exdb/mnist/。这次我们用MNIST来小试牛刀。上次我们采用的是MLP网络,这次使用CNN网络。

1. 准备工作

1.1 导包和设置随机种子

import torchvision
import torchvision.datasets as datasets #为了下一步加载数据
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable

import numpy as np 
import random #设置随机数

USE_CUDA = torch.cuda.is_available() #GPU可用的标志位
random.seed(1)
np.random.seed(1)
torch.manual_seed(1)  

if USE_CUDA:
    torch.cuda.manual_seed(1)

1.2 加载数据和归一化

train_mnist = datasets.MNIST(root = './data', train = True, download = True) #训练集
test_mnist = datasets.MNIST(root = './data', train = False, download = True) #测试集

train_X, train_Y = train_mnist.data, train_mnist.targets
test_X, test_Y = test_mnist.data, test_mnist.targets

train_X = train_X.float()
test_X = test_X.float()

train_X = train_X / 255.0        #数据归一化
test_X = test_X / 255.0 

1.3 将数据加载到DataLoader中

# Pytorch train and test sets
train = torch.utils.data.TensorDataset(train_X, train_Y)
test = torch.utils.data.TensorDataset(test_X, test_Y)

# data loader
train_loader = torch.utils.data.DataLoader(train, batch_size = BATCH_SIZE, shuffle = False)
test_loader = torch.utils.data.DataLoader(test, batch_size = BATCH_SIZE, shuffle = False)

2. 构建CNN网络

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)

cnn = CNN()
print(cnn)

it = iter(train_loader)
X_batch, y_batch = next(it)
print(cnn.forward(X_batch).shape)

3.训练模型

def fit(model, train_loader):
    optimizer = torch.optim.Adam(model.parameters())#,lr=0.001, betas=(0.9,0.999))
    error = nn.CrossEntropyLoss()
    EPOCHS = 5
    model.train()
    for epoch in range(EPOCHS):
        correct = 0
        for batch_idx, (X_batch, y_batch) in enumerate(train_loader):
            var_X_batch = Variable(X_batch).float()
            var_y_batch = Variable(y_batch)
            optimizer.zero_grad()
            output = model(var_X_batch)
            loss = error(output, var_y_batch)
            loss.backward()
            optimizer.step()

            # Total correct predictions
            predicted = torch.max(output.data, 1)[1] 
            correct += (predicted == var_y_batch).sum()
            #print(correct)
            #print(loss.data.item())
            if batch_idx % 50 == 0:
                print('Epoch : {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}\t Accuracy:{:.3f}%'.format(
                    epoch, batch_idx*len(X_batch), len(train_loader.dataset), 100.*batch_idx / len(train_loader), loss.data.item(), float(correct*100) / float(BATCH_SIZE*(batch_idx+1))))

fit(cnn,train_loader)

4.模型评估

def evaluate(model):
    correct = 0 
    for test_imgs, test_labels in test_loader:
        #print(test_imgs.shape)
        test_imgs = Variable(test_imgs).float()
        output = model(test_imgs)
        predicted = torch.max(output,1)[1]
        correct += (predicted == test_labels).sum()
    print("Test accuracy:{:.3f}% ".format( float(correct) / (len(test_loader)*BATCH_SIZE)))
    
evaluate(cnn)

在这里插入图片描述

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付 79.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值