文章目录
- 实现基于CNN网络的手写字体识别
-
- 1、搭建CNN网络模型;
- 2、设计损失函数,选择优化函数;
- 3、实现模型训练与测试。
- 代码:
实现基于CNN网络的手写字体识别
首先下载数据
1、搭建CNN网络模型;
class CNN(nn.Module):
def __init__(self):
super(CNN,self).__init__()
'''
一般来说,卷积网络包括以下内容:
1.卷积层
2.神经网络
3.池化层
'''
self.conv1=nn.Sequential(
nn.Conv2d(
in_channels=1,
out_channels=16,
kernel_size=5,
stride=1,
padding=2,
),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2),
)
self.conv2=nn.Sequential(
nn.Conv2d(
in_channels=16,
out_channels=32,
kernel_size=5,
stride=1,
padding=2,
),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2),
)
self.out=nn.Linear(32*7*7,10)
def forward(self,x):
x=self.conv1(x)
x=self.conv2(x)
x=x.view(x.size(0),-1)
output=self.out(x)
return output
2、设计损失函数,选择优化函数;
optimizer=torch.optim.Adam(cnn.parameters(),lr=LR)
loss_fn=nn.CrossEntropyLoss()
3、实现模型训练与测试。
step=0
for epoch in range(EPOCH):
for step,data in enumerate(train_loader):
x,y=data
b_x=Variable(x)
b_y=Variable(y)
output=cnn(b_x)
loss=loss_fn(output,b_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (step%50==0):
test_output=cnn(test_x)
y_pred=torch.max(test_output,1)[1].data.squeeze()
accuracy=sum(y_pred==test_y).item()/test_y.size(0)
print('now epoch : ', epoch, ' | loss : %.4f ' % loss.item(), ' | accuracy : ' , accuracy)
代码:
import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.utils.data as Data
import torchvision
EPOCH=1
BATCH_SIZE=50
LR=0.001
DOWNLOAD_MNIST=False
train_data = torchvision.datasets.MNIST(
root='./mnist',
train=True,
transform=torchvision.transforms.ToTensor(),
download=DOWNLOAD_MNIST
)
train_loader=Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
test_data=torchvision.datasets.MNIST(
root='./mnist',
train=False,
)
with torch.no_grad():
test_x=Variable(torch.unsqueeze(test_data.data, dim=1)).type(torch.FloatTensor)[:2000]/255
test_y=test_data.targets[:2000]
'''开始建立CNN网络'''
class CNN(nn.Module):
def __init__(self):
super(CNN,self).__init__()
'''
一般来说,卷积网络包括以下内容:
1.卷积层
2.神经网络
3.池化层
'''
self.conv1=nn.Sequential(
nn.Conv2d(
in_channels=1,
out_channels=16,
kernel_size=5,
stride=1,
padding=2,
),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2),
)
self.conv2=nn.Sequential(
nn.Conv2d(
in_channels=16,
out_channels=32,
kernel_size=5,
stride=1,
padding=2,
),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2),
)
self.out=nn.Linear(32*7*7,10)
def forward(self,x):
x=self.conv1(x)
x=self.conv2(x)
x=x.view(x.size(0),-1)
output=self.out(x)
return output
cnn=CNN()
optimizer=torch.optim.Adam(cnn.parameters(),lr=LR)
loss_fn=nn.CrossEntropyLoss()
'''
开始训练我们的模型哦
'''
step=0
for epoch in range(EPOCH):
for step,data in enumerate(train_loader):
x,y=data
b_x=Variable(x)
b_y=Variable(y)
output=cnn(b_x)
loss=loss_fn(output,b_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (step%50==0):
test_output=cnn(test_x)
y_pred=torch.max(test_output,1)[1].data.squeeze()
accuracy=sum(y_pred==test_y).item()/test_y.size(0)
print('now epoch : ', epoch, ' | loss : %.4f ' % loss.item(), ' | accuracy : ' , accuracy)
'''
打印十个测试集的结果
'''
test_output=cnn(test_x[:10])
y_pred=torch.max(test_output,1)[1].data.squeeze()
print(y_pred.tolist(),'predecton Result')
print(test_y[:10].tolist(),'Real Result')