织梦 帝国 php cms 媒体网站 哪个,烟台 做网站,做企业网站cms,做网站前端后台在人工智能和机器学习的广阔领域中#xff0c;手写数字识别是一个经典的入门级问题#xff0c;它不仅能够帮助我们理解深度学习的基本原理#xff0c;还能作为实践编程和模型训练的良好起点。本文将带您踏上手写数字识别的深度学习之旅#xff0c;从数据集介绍、模型构建到…
在人工智能和机器学习的广阔领域中手写数字识别是一个经典的入门级问题它不仅能够帮助我们理解深度学习的基本原理还能作为实践编程和模型训练的良好起点。本文将带您踏上手写数字识别的深度学习之旅从数据集介绍、模型构建到训练与评估一步步深入探索。
一、引言
手写数字识别Handwritten Digit Recognition是指通过计算机程序自动识别手写数字的过程。最著名的手写数字数据集之一是MNISTModified National Institute of Standards and Technology database它包含了大量的手写数字图片每张图片都被标记了对应的数字0-9。这个数据集成为了初学者学习深度学习尤其是卷积神经网络CNN的首选。
二、MNIST数据集简介
MNIST数据集由60,000个训练样本和10,000个测试样本组成每个样本都是一张28x28像素的灰度图像代表了一个手写数字。这些图像已经被归一化并居中在图像中心使得数字不会受到位置变化的影响。 PyTorch 和 torchvision 库来下载并准备 MNIST 数据集包括训练集和测试集
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor下载训练数据集图片标签
training_data datasets.MNIST(rootdata,trainTrue,downloadTrue,transformToTensor()
)
test_data datasets.MNIST(rootdata,trainFalse,downloadTrue,transformToTensor()
)打印设备信息您的代码已经很好地检查了CUDA和MPS针对Apple M系列芯片的可用性并设置了相应的设备。但是在打印设备信息时有一个小错误在字符串格式化上。您需要确保在字符串中正确地包含变量名。 打印数据形状您已经正确地设置了DataLoader并打印了测试数据集中的一个批次的数据和标签的形状。这是一个很好的实践可以帮助您了解数据的维度。
train_dataloader DataLoader(training_data, batch_size64, shuffleTrue) # 通常训练时会打乱数据
test_dataloader DataLoader(test_data, batch_size64, shuffleFalse) # 测试时不需要打乱数据 # 打印测试数据集的一个批次的数据和标签的形状
for x, y in test_dataloader: print(fShape of x [N,C,H,W]: {x.shape}) # 注意这里的x是图像但MNIST是灰度图所以C1 print(fShape of y: {y.shape}, {y.dtype}) # y是标签通常是一维的且为long类型 break # 判断当前设备是否支持GPU其中mps是苹果m系列芯片的GPU
device cuda if torch.cuda.is_available() else (mps if torch.backends.mps.is_available() else cpu)
print(fUsing {device} device) # 确保在字符串中正确地包含了变量名 三、训练模型选择
一、创建一个具有多个隐藏层的神经网络这些层都使用了nn.Linear来定义全连接层并使用torch.sigmoid作为激活函数。
import torch
import torch.nn as nn class NeuralNetwork(nn.Module): def __init__(self): super().__init__() self.flatten nn.Flatten() self.hidden1 nn.Linear(28 * 28, 256) self.relu1 nn.ReLU() self.hidden2 nn.Linear(256, 128) self.relu2 nn.ReLU() self.hidden3 nn.Linear(128, 64) self.relu3 nn.ReLU() self.hidden4 nn.Linear(64, 32) self.relu4 nn.ReLU() self.out nn.Linear(32, 10) # 输出层对应于10个类别的得分 def forward(self, x):x self.flatten(x)x self.hidden1(x)x torch.sigmoid(x)x self.hidden2(x)x torch.sigmoid(x)x self.hidden3(x)x torch.sigmoid(x)x self.hidden4(x)x torch.sigmoid(x)x self.out(x)return x model NeuralNetwork().to(device)
print(model)
二、定义了一个具有三个卷积层的CNN每个卷积层后面都跟着ReLU激活函数前两个卷积层后面还跟着最大池化层。最后通过一个全连接层将卷积层的输出转换为10个类别的得分。
import torch
import torch.nn as nn class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() self.conv1 nn.Sequential( nn.Conv2d(in_channels1, out_channels16, kernel_size5, stride1, padding2), nn.ReLU(), nn.MaxPool2d(kernel_size2), ) self.conv2 nn.Sequential( nn.Conv2d(16, 32, 5, 1, 2), nn.ReLU(), nn.Conv2d(32, 32, 5, 1, 2), nn.ReLU(), nn.MaxPool2d(2), ) self.conv3 nn.Sequential( nn.Conv2d(32, 64, 5, 1, 2), nn.ReLU(), ) self.out nn.Linear(64 * 7 * 7, 10) # 确保这里的输入特征数与卷积层输出后的特征数相匹配 def forward(self, x): x self.conv1(x) x self.conv2(x) x self.conv3(x) # 输出应为(batch_size, 64, 7, 7) x x.view(x.size(0), -1) # 展平操作输出为(batch_size, 64*7*7) output self.out(x) return output model CNN().to(device)
print(model) in_channels1这指定了输入图像的通道数。 out_channels16这指定了卷积操作后输出的通道数也就是卷积核或称为滤波器的数量。 kernel_size5这定义了卷积核的大小。 stride1这指定了卷积核在输入数据上滑动的步长。 padding2这定义了要在输入数据周围添加的零填充zero-padding的数量。
四、处理数据集和测试集
训练集处理
def train(dataloader, model, loss_fn, optimizer): model.train() # 将模型设置为训练模式 batch_size_num 1 # 这不是标准的用法但在这里用作计数已处理批次的数量 for x, y in dataloader: # 遍历数据加载器中的每个批次 x, y x.to(device), y.to(device) # 将数据和标签移动到指定的设备如GPU pred model(x) # 通过模型进行前向传播 loss loss_fn(pred, y) # 计算预测和真实标签之间的损失 optimizer.zero_grad() # 清除之前的梯度 loss.backward() # 反向传播计算当前梯度 optimizer.step() # 更新模型的权重 loss_value loss.item()if batch_size_num % 200 0:print(f{loss_value:7f}[number:{batch_size_num}])#打印结果batch_size_num 1 # 增加已处理批次的数量
测试集处理
def test(dataloader, model, loss_fn):size len(dataloader.dataset)num_batches len(dataloader)model.eval()test_loss, correct 0, 0with torch.no_grad():for x, y in dataloader:x, y x.to(device), y.to(device)pred model(x)test_loss loss_fn(pred, y).item()correct (pred.argmax(1) y).type(torch.float).sum().item()a (pred.argmax(1) y)b (pred.argmax(1) y).type(torch.float)test_loss / num_batchescorrect / sizeprint(fTest result: \n Accuracy: {(100 * correct)}%, Avg loss: {test_loss})模型训练
loss_fn nn.CrossEntropyLoss()optimizer torch.optim.Adam(model.parameters(), lr0.001)epochs 10
for t in range(epochs):print(f-----------------------------------------------\nepcho{t1})train(train_dataloader, model, loss_fn, optimizer)
print(Done!)
test(test_dataloader, model, loss_fn)train(train_dataloader,model,loss_fn,optimizer)
test(test_dataloader,model, loss_fn)结果
神经网络 cnn