PyCharm-MNIST手写数字的识别
本文是将PyTorch上的MNIST手写数字的识别、CNN网络 在PyCharm 上进行展示
可以看我这篇博客
关于MNIST数据集无法下载的问题 可以看我另一篇博客
PyTorch-MNIST数据集无法下载-采用手动下载的方式
在PyCharm中导入PyTorch环境可以看我下面这篇博客
本实例的代码
import torch
import numpy as np
import torchvision #torch的视觉包
import torchvision.datasets as datasets
import torchvision.transforms as transforms
from torch.utils.data.dataloader import DataLoader
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plt
import PIL.Image as Image
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torch.optim as optim
mnist=torchvision.datasets.MNIST('./mnist_dataset',train=True,transform=ToTensor(),target_transform=None,download=False)
#print(mnist) #输出MNIST数据集的详细信息
data=[d[0].data.cpu().numpy() for d in mnist]
print(np.mean(data))
print(np.std(data))
bs=32
train_data_loader=torch.utils.data.DataLoader(
dataset=torchvision.datasets.MNIST('./mnist_dataset',train=True,transform=transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.1307,),(0.3081,))]),target_transform=None,download=False),
#其中,0.1307和0.3081是mnist数据集的均值和标准差,因为mnist数据值都是灰度图,所以图像的通道数只有一个,因此均值和标准差各一个。
# 要是imagenet数据集的话,由于它的图像都是RGB图像,因此他们的均值和标准差各3个,分别对应其R,G,B值。
# 例如([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])就是Imagenet dataset的标准化系数(RGB三个通道对应三组系数)。
# 数据集给出的均值和标准差系数,每个数据集都不同的,都是数据集提供方给出的。
batch_size=bs,
shuffle=True,
pin_memory=True
#“pin_memory就是锁页内存,创建DataLoader时,设置pin_memory=True,
# 则意味着生成的Tensor数据最开始是属于内存中的锁页内存, 这样将内存的Tensor转义到GPU的显存就会更快一些。
)
test_data_loader=torch.utils.data.DataLoader(
dataset=torchvision.datasets.MNIST('./mnist_dataset',train=False,transform=transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.1307,),(0.3081,))]),target_transform=None,download=False),
batch_size=bs,
shuffle=True,
pin_memory=True
)
class CNNModel(nn.Module):
def __init__(self): # 初始化
super(CNNModel, self).__init__() # 调用父类
self.conv1 = nn.Conv2d(1, 20, 5, 1) # 1维->20维 卷积核大小为5
self.conv2 = nn.Conv2d(20, 50, 5, 1) # 20维->50维 卷积核大小为5
self.fc1 = nn.Linear(4 * 4 * 50, 500) # 线性层
self.fc2 = nn.Linear(500, 10) # 线性层
def forward(self, x):
# x:1*28*28 1代表通道
x = F.relu(self.conv1(x)) # 前向卷积 28*28 -> (28+1-5)=24 24*24
x = F.max_pool2d(x, kernel_size=2, stride=2) # 12*12
x = F.relu(self.conv2(x)) # 8*8
x = F.max_pool2d(x, kernel_size=2, stride=2) # 4*4
x = x.reshape(-1, 4 * 4 * 50)
# 或者用 x = x.view(-1,4*4*50)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return F.log_softmax(x, dim=1)
#创建网络实例
cnnmodel=CNNModel()
print(cnnmodel)
for name,param in cnnmodel.named_parameters():
print(name,param.shape)
#准确度的评估
optimizer=torch.optim.SGD(cnnmodel.parameters(),lr=0.1,momentum=0.5)
for epoch in range(5):
total_loss=0
total_correct=0
for batch in train_data_loader:
image,labels=batch
optimizer.zero_grad()
out=cnnmodel(image)
loss=F.cross_entropy(out,labels)
total_loss+=loss.item() #把数值取出来
loss.backward()
optimizer.step()
total_correct+=out.argmax(dim=1).eq(labels).sum().item()
print("epoch:",epoch,"loss:",total_loss,"acc:",total_correct/60000)
运行结果如下所示
转载请注明出处,欢迎讨论和交流!