卷积神经网络--手写数字识别

本文我们通过搭建卷积神经网络模型,实现手写数字识别。

pytorch中提供了手写数字的数据集 ,我们可以直接从pytorch中下载

MNIST中包含70000张手写数字图像:60000张用于训练,10000张用于测试

图像是灰度的,28x28像素

首先,下载数据集

import torch
from torchvision import datasets #封装与图像相关的模型,数据集
from torchvision.transforms import ToTensor # #数据转换,张量,将其他类型的数据转换为tensor张量

training_data=datasets.MNIST(
    root='data',#表示下载的手写数字到哪个路径
    train=True,#读取下载后数据中的训练集
    download=True,#如果之前已经下载过,就不用再下载
    transform=ToTensor(),#张量,图片不能直接传入神经网络模型
)

test_data=datasets.MNIST(
    root='data',
    train=False,
    download=True,
    transform=ToTensor(),
)

打包数据

from torch.utils.data import DataLoader 

train_dataloader=DataLoader(training_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)

判断当前设备是否支持GPU

device='cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu'
print(f'using {device} device')

构建卷积神经网络模型

from torch import nn #导入神经网络模块

class CNN(nn.Module):
    def __init__(self):#初始化类
        super(CNN,self).__init__()#初始化父类
        self.conv1=nn.Sequential(# 将多个层(如卷积、激活函数、池化等)按顺序打包,输入数据会​​依次通过这些层​​,无需手动编写每一层的传递逻辑。
            nn.Conv2d(#2D 卷积层,提取空间特征。
                in_channels=1,#输入通道数
                out_channels=16,#输出通道数
                kernel_size=3,#卷积核大小
                stride=1,#步长
                padding=1,#填充
            ),
            nn.ReLU(),#激活函数,引入非线性变换,使得神经网络能够学习复杂的非线性变换,增强表达能力
            nn.MaxPool2d(kernel_size=2)# 2x2最大池化(尺寸减半)
        )

        self.conv2=nn.Sequential(
            nn.Conv2d(16,32,3,1,1),
            nn.ReLU(),
            # nn.Conv2d(32,32,3,1,1),
            # nn.ReLU(),
            nn.MaxPool2d(2),
        )

        self.conv3=nn.Sequential(
            nn.Conv2d(32,64,3,1,1)
        )
        self.out=nn.Linear(64*7*7,10)

    def forward(self,x):#前向传播
        x=self.conv1(x)
        x=self.conv2(x)
        x=self.conv3(x)
        x=x.view(x.size(0),-1)# 展平为向量(保留batch_size,合并其他维度)
        output=self.out(x)  # 全连接层输出
        return output

返回的output结果大致如图所示

 模型传入GPU

model=CNN().to(device)
print(model)

  损失函数,衡量的是​​模型预测的概率分布​​与​​真实的类别分布​​之间的差异。

loss_fn=nn.CrossEntropyLoss()

  优化器,用于在训练神经网络时更新模型参数,目的是​​在神经网络训练过程中,自动调整模型的参数(权重和偏置),以最小化损失函数​​。

optimizer=torch.optim.Adam(model.parameters(),lr=0.01)

 模型训练

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)
        pred=model.forward(X)
        loss=loss_fn(pred,y)

        # Backpropagation 进来一个batch的数据,计算一次梯度,更新一次网络
        optimizer.zero_grad()               #梯度值清零
        loss.backward()                     #反向传播计算得到每个参数的梯度值
        optimizer.step()                    #根据梯度更新网络参数

        loss_value=loss.item()
        if batch_size_num%100==0:
            print(f'loss:{loss_value:>7f}[number:{batch_size_num}]')
        batch_size_num+=1

epochs=10

for i in range(epochs):
    print(f'第{i}次训练')
    train(train_dataloader, model, loss_fn, optimizer)

模型测试

def test(dataloader,model,loss_fn):

    size = len(dataloader.dataset)# 测试集总样本数
    num_batches = len(dataloader)# 测试集总批次数
    model.eval()#进入到模型的测试状态,所有的卷积核权重被设为只读模式
    test_loss, correct = 0, 0# 初始化累计损失和正确预测数
    #禁用梯度计算
    with torch.no_grad():#一个上下文管理器,关闭梯度计算。当你确认不会调用Tensor.backward()的时候。这可以减少计算所用内存消耗。
        for X,y in dataloader:
            X,y=X.to(device),y.to(device)
            pred=model.forward(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_batches
    correct/=size

    print(f'Test result: \n Accuracy:{(100*correct)}%,Avg loss:{test_loss}')

test(test_dataloader,model,loss_fn)

得到结果如图所示

卷积神经网络(Convolutional Neural Networks,简称CNN)是一种在图像处理中非常重要的神经网络结构。它可以用于手写数字识别等任务。下面是一个使用CNN进行手写数字识别的示例: ```python import tensorflow as tf from tensorflow.keras.datasets import mnist # 加载MNIST数据集 (x_train, y_train), (x_test, y_test) = mnist.load_data() # 数据预处理 x_train = x_train.reshape(-1, 28, 28, 1) / 255.0 x_test = x_test.reshape(-1, 28, 28, 1) / 255.0 y_train = tf.keras.utils.to_categorical(y_train, num_classes=10) y_test = tf.keras.utils.to_categorical(y_test, num_classes=10) # 构建卷积神经网络模型 model = tf.keras.models.Sequential([ tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)), tf.keras.layers.MaxPooling2D((2, 2)), tf.keras.layers.Flatten(), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dense(10, activation='softmax') ]) # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # 训练模型 model.fit(x_train, y_train, epochs=5, batch_size=32, validation_data=(x_test, y_test)) # 评估模型 test_loss, test_acc = model.evaluate(x_test, y_test) print('Test accuracy:', test_acc) ``` 这个示例使用了TensorFlow和Keras库来构建和训练一个卷积神经网络模型,用于手写数字识别任务。模型首先加载了MNIST数据集,并进行了数据预处理。然后,通过添加卷积层、池化层、全连接层和输出层来构建了一个简单的卷积神经网络模型。最后,使用训练集对模型进行训练,并使用测试集评估模型的准确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值