一、nn.Linear()
nn.Linear 是 PyTorch 中用于全连接层(线性层)的模块,常用于构建神经网络中的全连接层。
# 参数
torch.nn.Linear(in_features, # 输入特征数,即每个样本的维度out_features, # 输出特征数,即全连接层的神经元数量bias=True # 是否使用偏置
)
在神经网络中,out_features 参数决定了全连接层(nn.Linear)的输出特征数,也就是该层神经元的数量。确定 out_features 的值需要根据具体的任务和网络设计目标来决定。常见的确定 out_features 的方法和考虑因素:
-
任务需求
分类任务:如果任务是分类问题,输出层的 out_features 应该等于类别数。例如,对于一个有 10 个类别的分类任务,输出层的 out_features 应该是 10。
回归任务:如果任务是回归问题,输出层的 out_features 应该等于回归目标的维度。例如,如果预测一个标量值,out_features 应该是 1;如果预测一个向量,out_features 应该是向量的维度。 -
数据集特性
输入特征数:输入层的 out_features 通常等于输入数据的特征数。例如,对于 MNIST 数据集,输入图像大小为 28x28,输入特征数为 784。
中间层特征数:中间层的 out_features 可以根据经验或实验来确定。通常,中间层的神经元数量可以是输入特征数的一定比例,或者根据网络的复杂度来调整。 -
网络架构设计
逐步降维:在多层网络中,可以逐步减少特征数。例如,输入层 784,第一隐藏层 256,第二隐藏层 128,输出层 10。
对称设计:有时会设计对称的网络结构,例如输入层 784,隐藏层 256,输出层 10。
参考已有模型:可以参考已有的成功模型架构,例如 ResNet、VGG 等,了解它们在不同层的特征数设计。 -
实验和调整
网格搜索:通过实验不同的 out_features 值,找到最佳的网络性能。可以使用网格搜索或随机搜索来尝试不同的配置。
验证集评估:在验证集上评估不同配置的网络性能,选择性能最佳的配置。
二、构建卷积神经网络(CNN)处理 MNIST 数据集数据流分析解释
MNIST 数据集的图像大小为 28×28,经过两次最大池化(2),变成7*7
在 MNIST 数据集中,数据流从输入图像开始,经过卷积层提取特征,通过激活函数引入非线性,使用池化层降低特征图的大小,最后通过全连接层将特征映射到类别得分。
在使用 PyTorch 构建卷积神经网络(CNN)处理 MNIST 数据集时,数据流的处理分析。
import torch
import torch.nn as nn
import torch.nn.functional as Fclass CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1) # 卷积层1self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1) # 卷积层2self.pool = nn.MaxPool2d(2, 2) # 最大池化层self.fc1 = nn.Linear(64 * 7 * 7, 128) # 全连接层1self.fc2 = nn.Linear(128, 10) # 全连接层2(输出层)def forward(self, x):# 输入 x 的形状:[batch_size, 1, 28, 28]x = self.conv1(x) # 卷积层1,输出形状:[batch_size, 32, 28, 28]x = F.relu(x) # 激活函数x = self.pool(x) # 最大池化,输出形状:[batch_size, 32, 14, 14]x = self.conv2(x) # 卷积层2,输出形状:[batch_size, 64, 14, 14]x = F.relu(x) # 激活函数x = self.pool(x) # 最大池化,输出形状:[batch_size, 64, 7, 7]x = x.view(-1, 64 * 7 * 7) # 展平,输出形状:[batch_size, 64*7*7]x = F.relu(self.fc1(x)) # 全连接层1,输出形状:[batch_size, 128]x = self.fc2(x) # 全连接层2,输出形状:[batch_size, 10]return x# 创建模型实例
model = CNN()# 输入张量 (批次大小为 64,输入通道数为 1,高度和宽度为 28x28)
input_tensor = torch.randn(64, 1, 28, 28)# 前向传播
output_tensor = model(input_tensor)# 输出张量的形状
print(output_tensor.shape) # 输出: torch.Size([64, 10])
输入数据
- 形状:
[batch_size, 1, 28, 28]
- 解释:
batch_size
是批次大小(例如 64),1
是输入通道数(灰度图像),28x28
是图像的大小。
卷积层1 (conv1
)
- 输入:
[batch_size, 1, 28, 28]
- 输出:
[batch_size, 32, 28, 28]
- 计算:
- 卷积核大小为 3x3,步长为 1,填充为 1,因此输出的大小与输入相同。
- 输出通道数为 32,因此每个样本有 32 个特征图。
o u t p u t _ s i z e = i n p u t _ s i z e − k e r n e l _ s i z e + 2 ∗ p a d d i n g s t r i d e + 1 output\_size = \frac{input\_size-kernel\_size+2*padding}{stride}+1 output_size=strideinput_size−kernel_size+2∗padding+1
最大池化层 (pool
)
- 输入:
[batch_size, 32, 28, 28]
- 输出:
[batch_size, 32, 14, 14]
- 计算:使用 2x2 的池化窗口,步长为 2,将每个特征图的大小减半。
展平 (view
)
- 输入:
[batch_size, 64, 7, 7]
- 输出:
[batch_size, 64 * 7 * 7]
- 计算:将每个样本的特征图展平为一维向量。
全连接层1 (fc1
)
- 输入:
[batch_size, 64 * 7 * 7]
- 输出:
[batch_size, 128]
- 计算:将展平后的特征向量映射到 128 维的特征空间。
全连接层2 (fc2
)
- 输入:
[batch_size, 128]
- 输出:
[batch_size, 10]
- 计算:将 128 维的特征向量映射到 10 维的输出空间,表示每个类别的得分。