手写数字识别
虽然但是还是没学懂,不明白原理但是好像照葫芦画瓢也能运行,能实现测试集的正常测试,代码如下
(其实主要都是copliot写的(大悲))
CNN类
import torch
class CNN(torch.nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = torch.nn.Sequential(
#1.卷积操作卷积层
torch.nn.Conv2d(
in_channels=1,
out_channels=16,
kernel_size=5,
stride=1,
padding=2
),
#2.归一化BN层
torch.nn.BatchNorm2d(16),
#3.激活层 Relu函数
torch.nn.ReLU(inplace=True),
#4.池化层 最大池化
torch.nn.MaxPool2d(kernel_size=2, stride=2),
#5.丢弃层 Dropout
torch.nn.Dropout(p=0.2)
)
self.conv2 = torch.nn.Sequential(
torch.nn.Conv2d(16, 32, kernel_size=5),
torch.nn.ReLU(inplace=True),
torch.nn.MaxPool2d(kernel_size=2, stride=2)
)
self.flatten_features = self._get_flatten_features((1, 28, 28))
self.fc1 = torch.nn.Linear(in_features = 50 * 4 * 4, out_features = 10)
# self.fc2 = torch.nn.Linear(120, 84)
# self.fc3 = torch.nn.Linear(84, 10)
def _get_flatten_features(self, input_size):
"""计算卷积层输出展平后的特征数量"""
with torch.no_grad():
x = torch.zeros(1, *input_size)
x = self.conv1(x)
x = self.conv2(x)
return x.numel()
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = x.view(x.size(0), -1)
x = self.fc1(x)
# x = self.fc2(x)
# x = self.fc3(x)
return x
pytorch_mnist.py文件
import torch
import torchvision.datasets as dataset
import torchvision.transforms as transforms
import torch.utils.data as data_utils
from CNN import CNN
#######数据加载########
train_data = dataset.MNIST(
root='mnist',
train=True,
transform=transforms.ToTensor(),
download=True
)
test_data = dataset.MNIST(
root='mnist',
train=False,
transform=transforms.ToTensor(),
download=True
)
# print('train_data:', train_data)
# print('test_data:', test_data)
#########分批加载##########
train_loader = data_utils.DataLoader(dataset=train_data, batch_size=64, shuffle=True)
test_loader = data_utils.DataLoader(dataset=test_data, batch_size=64, shuffle=False)
print('train_loader:', train_loader)
print('test_loader:', test_loader)
# for index, value in enumerate(train_loader):
# print('index:', index)
# print('value:', value)
# break
cnn = CNN()
#如果安装了显卡加速,可以放到cuda上运行,会比在CPU运行会快一点
cnn = cnn.cuda()
#############损失函数#########利用交叉熵损失函数进行运算
loss_function = torch.nn.CrossEntropyLoss()
##########优化器############利用随机梯度下降进行优化
optimizer = torch.optim.SGD(cnn.parameters(), lr=0.01, momentum=0.9) #如需精确lr=0.001
for epoch in range(10):
for index, (images, label) in enumerate(train_loader):
# print('index:', index)
# print('images:', images.shape)
# print('label:', label.shape)
images = images.cuda()
label = label.cuda()
#上面两行可写可不写
#前向传播
outputs = cnn(images)
#传入输出层节点和真实标签来计算损失函数
loss = loss_function(outputs, label)
#先清空梯度
optimizer.zero_grad()
#反向传播
loss.backward()
#更新参数
optimizer.step()
print("当前批次为{}/{},loss为{}".format(epoch+1,index+1, len(train_loader), loss.item()))
###########测试##############
loss_test = 0.0
for index, (images, label) in enumerate(test_loader):
images = images.cuda()
label = label.cuda()
outputs = cnn(images)
test_loss = loss_function(outputs, label)
_, predicted = torch.max(outputs.data, 1)
total = label.size(0)
correct = (predicted == label).sum().item()
print('测试集准确率为:{}%'.format(100 * correct / total))
torch.save(cnn, f"model/mnist_model.pkl")

浙公网安备 33010602011771号