# 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

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


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



# 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)

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


# 3.训练模型

def fit(model, train_loader):
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)
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(



# 4.模型评估

def evaluate(model):
correct = 0
#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)


11-07 3747

07-31 5127
03-08 6388
04-18 2991
04-02
07-26 1376