【自学记录5】【Pytorch2.0深度学习从零开始学 王晓华】第五章 基于Pytorch卷积层的MNIST分类实战

5.1.2 PyTorch2.0中卷积函数实现详解

1、torch.nn.Conv2d

in_channels=3: 输入的通道数,对应图像的3个颜色通道。

out_channels=10: 输出的通道数,即卷积后我们想要得到的特征图的数量。

kernel_size=3: 卷积核的大小,这里使用的是3x3的卷积核。

stride=2: 卷积核移动的步长,这里步长为2,意味着卷积核每次移动2个像素。

padding=1: 在图像边缘添加的填充像素数。这通常用于保持输出尺寸,或确保卷积核可以到达图像的边缘。

源码\第二章\ 5_1_2.py

cpp 复制代码
import torch
image = torch.randn(size=(5,3,128,128))
#下面是定义的卷积层例子
"""
输入维度:3
输出维度:10
卷积核大小:3
步长:2
补偿方式:维度不变补偿(指的是图像大小(宽高))
"""
conv2d = torch.nn.Conv2d(3,10,kernel_size=3,stride=2,padding=1)
image_new = conv2d(image)
print(image_new.shape)

2、池化torch.nn.AvgPool2d

pool = torch.nn.AvgPool2d (kernel_size=3,stride=2,padding=0)

创建一个AvgPool2d对象,用于对image进行平均池化。参数说明:

kernel_size=3:池化窗口的大小是3x3。

stride=2:池化窗口的步长是2,意味着池化窗口每次移动2个像素。

padding=0:不使用填充。

image_pooled = torch.nn.AdaptiveAvgPool2d (1)(image)#全局池化

AdaptiveAvgPool2d是一种特殊的池化层,它可以将任何大小的输入张量调整为指定的输出大小。这里,我们指定输出大小为(1, 1)`,这实际上是一个全局池化操作,因为无论输入张量的空间维度是多少,输出都只有一个元素。这通常用于从特征图中提取全局特征。

cpp 复制代码
import torch
image =torch.full((1, 3, 5, 5), 10.0)  #生成大小为(1, 3, 3, 3),元素全为3的数组
pool = torch.nn.AvgPool2d(kernel_size=3,stride=2,padding=0)
image_pooled = pool(image)
print(image_pooled.shape)
print(image_pooled)

image_pooled = torch.nn.AdaptiveAvgPool2d(1)(image)#全局池化
print(image_pooled.shape)
print(image_pooled)

5.2 实战:基于卷积的MNIST手写体分类

5.2.1数据准备

前几章是对数据进行"折叠"处理

cpp 复制代码
# 数据处理
# 1. 改变输入数据尺寸, (图片数量,28,28) -> (图片数量,784) ,即图片由平面变成了直线
x_train = x_train.reshape(-1,784)
x_test = x_test.reshape(-1,784)

现在需要对数据升维,突出通道。(图片数量,28,28) -> (图片数量,1,28,28),第二维指的是图片的维度/通道,channel=1。

cpp 复制代码
x_train = np.expand_dims(x_train,axis=1)

以上都是对数据进行修正,能够更好的适应不同的模型嘛!

5.2.2 模型设计

源码\第三章\5_2_2.py

cpp 复制代码
import torch
import torch.nn as nn
import numpy as np
import einops.layers.torch as elt

class MnistNetword(nn.Module):
    def __init__(self):
        super(MnistNetword, self).__init__()
        self.convs_stack = nn.Sequential(

            nn.Conv2d(1,12,kernel_size=7),  #第一个卷积层
            nn.ReLU(),
            nn.Conv2d(12,24,kernel_size=5),  #第二个卷积层
            nn.ReLU(),
            nn.Conv2d(24,6,kernel_size=3)  #第三个卷积层
        )
        #最终分类器层
        self.logits_layer = nn.Linear(in_features=1536,out_features=10)

    def forward(self,inputs):
        image = inputs
        x = self.convs_stack(image)

        #elt.Rearrange的作用是对输入数据维度进行调整,读者可以使用torch.nn.Flatten函数完成此工作
        x = elt.Rearrange("b c h w -> b (c h w)")(x)
        logits = self.logits_layer(x)
        return logits
model = MnistNetword()
torch.save(model,"model.pth")

5.2.3基于卷积的MNIST分类模型

没有什么特别难的,就是用了卷积处理图像,再把数据送到全连接层,除了模型设计,之后的操作(分类、训练、backward跟第三章一样)

cpp 复制代码
import torch
import torch.nn as nn
import numpy as np
import einops.layers.torch as elt

#载入数据
x_train = np.load("../dataset/mnist/x_train.npy")
y_train_label = np.load("../dataset/mnist/y_train_label.npy")

x_train = np.expand_dims(x_train,axis=1)
print(x_train.shape)


class MnistNetword(nn.Module):
    def __init__(self):
        super(MnistNetword, self).__init__()
        self.convs_stack = nn.Sequential(
            nn.Conv2d(1,12,kernel_size=7),
            nn.ReLU(),
            nn.Conv2d(12,24,kernel_size=5),
            nn.ReLU(),
            nn.Conv2d(24,6,kernel_size=3)
        )

        self.logits_layer = nn.Linear(in_features=1536,out_features=10)

    def forward(self,inputs):
        image = inputs
        x = self.convs_stack(image)
        x = elt.Rearrange("b c h w -> b (c h w)")(x)
        logits = self.logits_layer(x)
        return logits


device = "cuda" if torch.cuda.is_available() else "cpu"
#注意记得需要将model发送到GPU计算
model = MnistNetword().to(device)
#model = torch.compile(model)
loss_fn = nn.CrossEntropyLoss()

optimizer = torch.optim.SGD(model.parameters(), lr=1e-4)

batch_size = 128
for epoch in range(42):
    train_num = len(x_train)//128
    train_loss = 0.
    for i in range(train_num):
        start = i * batch_size
        end = (i + 1) * batch_size

        x_batch = torch.tensor(x_train[start:end]).to(device)
        y_batch = torch.tensor(y_train_label[start:end]).to(device)

        pred = model(x_batch)
        loss = loss_fn(pred, y_batch)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        train_loss += loss.item()  # 记录每个批次的损失值

    # 计算并打印损失值
    train_loss /= train_num
    accuracy = (pred.argmax(1) == y_batch).type(torch.float32).sum().item() / batch_size
    print("epoch:",epoch,"train_loss:", round(train_loss,2),"accuracy:",round(accuracy,2))
相关推荐
谢眠23 分钟前
深度学习day3-自动微分
python·深度学习·机器学习
z千鑫32 分钟前
【人工智能】深入理解PyTorch:从0开始完整教程!全文注解
人工智能·pytorch·python·gpt·深度学习·ai编程
YRr YRr40 分钟前
深度学习:神经网络的搭建
人工智能·深度学习·神经网络
爱喝热水的呀哈喽1 小时前
torch张量与函数表达式写法
人工智能·pytorch·深度学习
LZXCyrus2 小时前
【杂记】vLLM如何指定GPU单卡/多卡离线推理
人工智能·经验分享·python·深度学习·语言模型·llm·vllm
YRr YRr2 小时前
深度学习神经网络中的优化器的使用
人工智能·深度学习·神经网络
幻风_huanfeng2 小时前
人工智能之数学基础:线性代数在人工智能中的地位
人工智能·深度学习·神经网络·线性代数·机器学习·自然语言处理
吾门3 小时前
YOLO入门教程(三)——训练自己YOLO11实例分割模型并预测【含教程源码+一键分类数据集 + 故障排查】
yolo·分类·数据挖掘
deephub3 小时前
使用 PyTorch-BigGraph 构建和部署大规模图嵌入的完整教程
人工智能·pytorch·深度学习·图嵌入
羞儿4 小时前
【读点论文】Text Detection Forgot About Document OCR,很实用的一个实验对比案例,将科研成果与商业产品进行碰撞
深度学习·ocr·str·std