手把手教你用PyTorch实现一个简单的卷积神经网络

准备工作:导入必要的库

在开始构建卷积神经网络(CNN)之前,我们首先需要导入所需的PyTorch模块。PyTorch提供了`torch.nn`模块,其中包含了构建神经网络所需的所有核心构件。我们将主要使用它来定义我们的网络层。

```pythonimport torchimport torch.nn as nnimport torch.nn.functional as F```

这段代码导入了PyTorch库本身(`torch`)、神经网络的模块(`nn`)和函数接口(`functional`,通常简写为`F`)。`nn.Module`是所有神经网络模块的基类,我们自定义的网络将继承自它。

第一步:定义CNN模型类

接下来,我们将创建一个新的类来定义我们的卷积神经网络结构。这个类需要继承自`nn.Module`,并至少包含两个方法:`__init__`和`forward`。

```pythonclass SimpleCNN(nn.Module): def __init__(self): super(SimpleCNN, self).__init__() # 定义第一个卷积层 self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=1) # 定义第二个卷积层 self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=1) # 定义最大池化层 self.pool = nn.MaxPool2d(kernel_size=2, stride=2) # 定义全连接层 self.fc1 = nn.Linear(in_features=64 7 7, out_features=128) self.fc2 = nn.Linear(in_features=128, out_features=10)```

初始化函数详解

在`__init__`方法中,我们初始化了网络的所有层:

  • nn.Conv2d: 这是二维卷积层。我们定义了两层卷积:
    • conv1: 输入通道数为1(例如MNIST数据集的黑白图像),输出通道数为32,使用3x3的卷积核,并设置填充(padding)为1以保证输出尺寸与输入尺寸一致(当步长stride=1时)。
    • conv2: 输入通道数为32(承接上一层的输出),输出通道数为64,同样使用3x3卷积核和填充1。
  • nn.MaxPool2d: 这是最大池化层,我们使用2x2的窗口,步长为2,这将把特征图的宽度和高度减少一半。
  • nn.Linear: 这是全连接层。我们定义了两个全连接层:
    • fc1: 将池化后的特征图展平后的数据作为输入。假设输入图像是28x28(如MNIST),经过两次池化后变为7x7(28/2/2=7),且有64个通道,因此输入特征数为6477。输出特征数设为128。
    • fc2: 将128个特征映射到10个输出节点(对应10个分类,如0-9的数字)。

第二步:定义前向传播

`forward`方法定义了数据如何从输入流经网络的每一层,最终得到输出。这是模型的核心逻辑。

```python def forward(self, x): # 第一次卷积 -> 激活函数 -> 池化 x = self.pool(F.relu(self.conv1(x))) # 第二次卷积 -> 激活函数 -> 池化 x = self.pool(F.relu(self.conv2(x))) # 将多维特征图展平为一维向量,以便输入全连接层 x = x.view(-1, 64 7 7) # 第一个全连接层 -> 激活函数 x = F.relu(self.fc1(x)) # 第二个全连接层(输出层) x = self.fc2(x) return x```

前向传播流程

在前向传播中,我们依次执行以下操作:

  1. 输入张量`x`通过第一卷积层`conv1`。
  2. 然后通过ReLU激活函数(使用`F.relu`)引入非线性。
  3. 接着通过最大池化层`pool`进行下采样。
  4. 重复步骤1-3,通过第二组卷积、激活和池化层。
  5. 使用`x.view(-1, 6477)`将特征图展平。`-1`表示让PyTorch自动计算该维度的大小(通常是批处理大小batch size)。
  6. 将展平后的数据传入第一个全连接层`fc1`,再经过ReLU激活函数。
  7. 最后,数据通过第二个全连接层`fc2`,得到最终的输出(如10个类别的分数/logits)。

第三步:实例化模型并检查结构

定义好类之后,我们可以创建一个模型实例,并打印其结构以确认每一层的设置是否正确。

```python# 创建模型实例model = SimpleCNN()# 打印模型结构print(model)```

为了测试数据是否能正确通过模型,我们可以创建一个随机输入张量(模拟一批数据)并进行前向传播。

```python# 生成一个随机张量模拟输入数据:批量大小=4,通道数=1,高度=28,宽度=28input_data = torch.randn(4, 1, 28, 28)# 将数据输入模型output = model(input_data)# 打印输出的形状,应为 [4, 10] (4个样本,10个类别分数)print(output.shape)```

理解输入和输出

这个简单的CNN模型现在已经构建完成。它接收一个形状为`[batch_size, 1, 28, 28]`的四维张量(分别代表批处理大小、通道数、高度、宽度),并输出一个形状为`[batch_size, 10]`的二维张量,其中包含了每个样本属于10个类别中每一类的原始分数。

要完成一个完整的图像分类任务,后续步骤通常还包括:定义损失函数(如交叉熵损失`nn.CrossEntropyLoss`)、选择优化器(如`torch.optim.Adam`)、在训练数据集上循环进行前向传播、计算损失、反向传播和参数更新。但本教程的核心目标——用PyTorch实现一个简单的CNN模型——已经成功达成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值