《人工智能概论》实验5 知识点复习提纲
一、卷积神经网络核心概念
1. 卷积操作
-
卷积核在输入图像上滑动,计算对应位置元素相乘再求和,得到输出特征图的一个像素。
-
卷积核大小(kernel_size):通常是奇数,如 3×3、5×5。
2. 填充(Padding)
-
在输入边界周围补充像素(通常补0),作用:控制输出尺寸,保护边缘信息。
-
padding=1表示上下左右各补1行/列0。 -
Same padding:
padding = (kernel_size - 1) // 2,当 stride=1 时,输出尺寸等于输入尺寸。
3. 步幅(Stride)
-
卷积核每次滑动的步长。步幅越大,输出尺寸越小。
4. 卷积输出尺寸计算公式(必考)
(宽度同理)
5. 池化层(Pooling)
-
最大池化:取窗口内的最大值。
-
平均池化:取窗口内的平均值。
-
池化层参数:
kernel_size(窗口大小)、stride(步幅)。 -
输出尺寸公式:(H_in - kernel_size) // stride + 1
-
池化层作用:降维、减少计算量、增强平移不变性。
6. 多输入 / 多输出通道
-
输入通道(in_channels):彩色图像为3(RGB),灰度图为1。
-
输出通道(out_channels):每个输出通道对应一组独立的卷积核,提取不同特征。
-
卷积层构造参数:
nn.Conv2d(in_channels, out_channels, kernel_size, ...) -
卷积核权重张量的形状(通过
conv.weight.shape查看):(out_channels, in_channels, kernel_height, kernel_width)-
注意:第一个维度是输出通道数,第二个是输入通道数。
-
例如:
Conv2d(3, 16, 3)的权重形状为(16, 3, 3, 3)。
-
7. 感受野(Receptive Field)
-
定义:某一层的一个神经元在原始输入图像上所能看到的区域大小。
-
计算公式(从最后一层向前递推):
-
初始 RF = 1
-
从后向前遍历每一层:
RF = (RF - 1) * stride + kernel_size
-
-
作用:感受野越大,能捕捉越全局的信息。
8. 数据增强
-
对训练图像进行随机变换(旋转、翻转、缩放等),增加样本多样性,防止过拟合。
-
测试集不使用数据增强,以保持评估的公平性。
二、LeNet 网络结构(适配MNIST 28×28)
| 层 | 参数 | 输入形状 | 输出形状 |
|---|---|---|---|
| conv1 | 1→6, k5, s1, p0 | 1×28×28 | 6×24×24 |
| pool1 | 2×2, s2 | 6×24×24 | 6×12×12 |
| conv2 | 6→16, k5, s1, p0 | 6×12×12 | 16×8×8 |
| pool2 | 2×2, s2 | 16×8×8 | 16×4×4 |
| flatten | view(x.size(0), -1) |
16×4×4 | 256 |
| fc1 | 256→120 | 256 | 120 |
| fc2 | 120→84 | 120 | 84 |
| fc3 | 84→10 | 84 | 10 |
-
x.view(x.size(0), -1)的作用:将每个样本的特征图展平成一维向量,以输入全连接层。
三、PyTorch 中维度操作
-
unsqueeze(dim):在指定位置增加一个大小为1的维度。 -
squeeze():移除所有大小为1的维度(或指定维度)。 -
池化和卷积层要求输入为4维:
(batch, channels, height, width)。
《人工智能概论》实验5 考试题
一、单选题(每题3分)
-
给定输入尺寸
28×28,卷积核大小5×5,步幅1,填充0,卷积输出尺寸是( )
A. 24×24
B. 28×28
C. 26×26
D. 20×20 -
关于填充(padding)的说法,正确的是( )
A. 填充只能在输入四周补0
B. 填充会降低输出特征图的分辨率
C.padding=1表示上下左右各补1圈
D. 填充不影响感受野大小 -
最大池化层
MaxPool2d(kernel_size=2, stride=2)对4×4特征图池化后,输出尺寸为( )
A. 2×2
B. 3×3
C. 4×4
D. 1×1 -
在LeNet中,
x.view(x.size(0), -1)的作用是( )
A. 增加一个维度
B. 将多维特征图展平成一维向量,保留batch维度
C. 转置特征图
D. 复制特征图 -
数据增强通常只应用于( )
A. 训练集
B. 测试集
C. 验证集
D. 所有数据集
二、填空题(每空2分)
-
卷积输出尺寸计算公式为:

-
一个
Conv2d(3, 16, kernel_size=3, stride=1, padding=1)层的卷积核形状是(16, _, _, _)。 -
感受野计算函数中,从最后一层向前递推:
rf = rf + (k - 1) * s。若两层卷积核均为3,步幅第一层2、第二层1,则最终感受野大小为 ____。 -
LeNet中,第二个池化层
pool2的输入通道数是 ____,输出通道数不变。池化层不会改变通道数。 -
在PyTorch中,
unsqueeze(0)是在第0维增加一个维度,squeeze()用于移除维度大小为 ____ 的维度。
三、判断题(正确打“√”,错误打“×”,每题2分)
-
( )卷积核的数量决定输出特征图的通道数。
-
( )池化层具有可训练参数。
-
( )感受野只与卷积核大小有关,与步幅无关。
-
( )数据增强可以帮助提高模型泛化能力。
-
( )在LeNet的forward中,
x = x.view(x.size(0), -1)之前不需要展平,因为全连接层会自动处理。
四、简答题(将原实验中的思考题整合,共35分)
简答题1(3分,来自3.1(1)) 写出卷积输出尺寸的计算公式。
简答题2(4分,来自3.1(3)) 使用给定参数(stride=1,padding=0),写出输出的第2行第1个数是如何计算出来的(可参考代码中的输入和卷积核)。
简答题3(4分,来自3.2(3)) 当 padding = (kernel_size - 1) // 2 且 stride=1 时,输出尺寸等于什么?这种填充方式叫什么?
简答题4(4分,来自3.2(4)) 在 nn.Conv2d 中,可以直接使用 padding='same' 参数实现相同效果吗?为什么?
简答题5(3分,来自3.3(5)) 代码中的 unsqueeze 和 squeeze 分别做了什么?为什么池化前需要增加维度?
简答题6(4分,来自3.3(6)) 最大池化和平均池化的输出结果分别是什么(针对给定的4×4特征图)?池化层的主要作用是什么?
简答题7(3分,来自3.4(7)) 为什么感受野很重要?如果网络更深,感受野会如何变化?
简答题8(4分,来自3.5(8)) 卷积核的形状 (16, 3, 3, 3) 四个数字分别代表什么?
简答题9(3分,来自4.1(9)) 数据增强的作用是什么?为什么测试集不使用数据增强?
简答题10(3分,来自4.2(11)) x.view(x.size(0), -1) 这一步的作用是什么?
五、计算题(20分)
5.1 特征图尺寸计算(8分)
完成下表(每空2分):
| 输入 | 操作 | 输出尺寸 |
|---|---|---|
| 32×32×3 | Conv2d(3,16,3,stride=1,padding=0) | ______ |
| 30×30×16 | MaxPool2d(2,stride=2) | ______ |
| 32×32×3 | Conv2d(3,16,5,stride=2,padding=1) | ______ |
| 28×28×6 | Conv2d(6,16,5,stride=1,padding=0) | ______ |
5.2 感受野计算(6分)
一个三层卷积网络:第一层 kernel=3, stride=2;第二层 kernel=3, stride=1;第三层 kernel=3, stride=1。请计算第三层(最后一层)特征图上每个神经元相对于原始输入的感受野大小。
5.3 LeNet特征图尺寸填空(6分)
补全LeNet各层输出形状(已知输入1×28×28):
| 层 | 输出形状 |
|---|---|
| conv1 (k5,s1,p0, 1→6) | ______ |
| pool1 (2×2,s2) | ______ |
| conv2 (k5,s1,p0, 6→16) | ______ |
| pool2 (2×2,s2) | ______ |
| flatten后 | ______ |
六、代码填空题(每空2分)
卷积层定义
import torch
import torch.nn as nn
# 定义卷积层:输入通道1,输出通道6,卷积核5×5,步幅1,填充0
conv1 = nn.Conv2d(in_channels=______, out_channels=______, kernel_size=______, stride=1, padding=0)
# 创建一个模拟输入 (batch=1, channel=1, height=28, width=28)
x = torch.randn(1, 1, 28, 28)
out = conv1(x)
print("输出形状:", out.shape) # 期望输出: torch.Size([1, 6, 24, 24])
池化层
# 定义最大池化层:核大小2×2,步幅2
pool = nn.MaxPool2d(kernel_size=______, stride=______)
# 对上面卷积的输出进行池化
pooled = pool(out)
print("池化后形状:", pooled.shape) # 期望输出: torch.Size([1, 6, 12, 12])
感受野函数
def receptive_field(kernel_sizes, strides):
"""
计算输出层相对于原始输入的感受野大小
kernel_sizes: 各层卷积核大小列表,从输入层到输出层顺序
strides: 各层步幅列表,从输入层到输出层顺序
"""
rf = 1
# 从最后一层向第一层遍历
for k, s in zip(reversed(kernel_sizes), reversed(strides)):
rf = rf + (______ - 1) * ______
return rf
# 示例:两层卷积,核大小均为3,步幅分别为2和1
rf = receptive_field([3, 3], [2, 1])
print("感受野大小:", rf) # 期望输出: 7
LeNet 展平
class LeNet(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 6, 5) # 输入1→6通道,核5
self.pool1 = nn.MaxPool2d(2, 2) # 2×2池化,步幅2
self.conv2 = nn.Conv2d(6, 16, 5) # 输入6→16通道,核5
self.pool2 = nn.MaxPool2d(2, 2) # 2×2池化,步幅2
self.fc1 = nn.Linear(16 * 4 * 4, 120) # 全连接层
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool1(torch.relu(self.conv1(x))) # 输出形状: (batch, 6, 12, 12)
x = self.pool2(torch.relu(self.conv2(x))) # 输出形状: (batch, 16, 4, 4)
x = x.______(x.size(0), -1) # 展平操作
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = self.fc3(x)
return x
# 测试模型
model = LeNet()
dummy = torch.randn(1, 1, 28, 28)
output = model(dummy)
print("输出形状:", output.shape) # 期望: torch.Size([1, 10])
数据增强旋转角度
from torchvision import transforms
train_transform = transforms.Compose([
transforms.RandomRotation(______), # 随机旋转 ±10度
transforms.RandomHorizontalFlip(), # 随机水平翻转
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,)) # MNIST归一化参数
])
# 测试一下变换(假设有一张PIL图像)
# from PIL import Image
# img = Image.open('test.png')
# img_tensor = train_transform(img)
参考答案与超详细解析(小白版)
一、单选题
第1题
题目:给定输入尺寸 28×28,卷积核大小 5×5,步幅 1,填充 0,卷积输出尺寸是( )
A. 24×24
B. 28×28
C. 26×26
D. 20×20
答案:A
详细解析:
-
首先回忆卷积输出尺寸公式:
输出尺寸 = (输入尺寸 + 2×填充 - 卷积核大小) ÷ 步幅 + 1
这里所有数字都是整数,除法是整数除法(向下取整)。 -
代入数字:输入=28,填充=0,核=5,步幅=1。
计算括号内:28 + 0 - 5 = 23。
除以步幅1:23 ÷ 1 = 23。
加1:23 + 1 = 24。 -
所以输出是 24×24。
-
为什么不是 28?因为卷积核滑动的过程中,边缘的像素只能被卷积核覆盖一部分,每滑动一步,输出尺寸就会减少 (核尺寸-1),这里 5-1=4,28-4=24。
第2题
题目:关于填充(padding)的说法,正确的是( )
A. 填充只能在输入四周补0
B. 填充会降低输出特征图的分辨率
C. padding=1 表示上下左右各补1行/列0
D. 填充不影响感受野大小
答案:C
详细解析:
-
A选项:填充通常使用0,但不是“只能”。PyTorch 的卷积层
nn.Conv2d的padding参数默认是补0,但也可以使用其他填充模式(如反射、重复等)。而且padding只是一个数值,表示补多少圈0,但如果你用torch.nn.functional.pad可以指定不同的填充值。所以“只能”这个词太绝对,错误。 -
B选项:填充是增加输出尺寸的。如果填充足够大,可以让输出尺寸等于输入尺寸(same padding)。即使填充很小,输出尺寸也比不填充时要大或相等。例如:输入5×5,核3,步幅1,无填充输出3×3;加上1圈填充(变成7×7),输出5×5。所以填充不会降低分辨率,反而可能维持或增大。
-
C选项:
padding=1表示在输入的四周各补1行/列(通常补0)。对于二维图像,上下各补1行,左右各补1列,所以总高度增加2,总宽度增加2。这个说法是正确的。 -
D选项:填充会影响感受野。因为填充相当于扩展了输入的有效范围,使得卷积核可以覆盖到原来边界的区域,从而影响后续层神经元能看到的原始输入范围。所以感受野会变化。
因此只有 C 正确。
第3题
题目:最大池化层 MaxPool2d(kernel_size=2, stride=2) 对 4×4 特征图池化后,输出尺寸为( )
A. 2×2
B. 3×3
C. 4×4
D. 1×1
答案:A
详细解析:
-
池化层输出尺寸公式与卷积类似:
输出尺寸 = (输入尺寸 - 核尺寸) ÷ 步幅 + 1(除法是整数除法,向下取整) -
输入=4,核=2,步幅=2。
(4 - 2) ÷ 2 = 2 ÷ 2 = 1,再加1得2。 -
或者直观理解:2×2的窗口,步长2,刚好不重叠地滑过4×4区域,可以分成2行2列窗口,所以输出2×2。
-
最大池化取每个窗口的最大值,所以输出四个值,排成2×2。
第4题
题目:在LeNet中,x.view(x.size(0), -1) 的作用是( )
A. 增加一个维度
B. 将多维特征图展平成一维向量,保留batch维度
C. 转置特征图
D. 复制特征图
答案:B
详细解析:
-
x的形状通常是(batch, channels, height, width),比如(64, 16, 4, 4)。 -
x.size(0)是 batch 大小(64)。 -
view(64, -1)表示将每个样本(每个64中的一行)的所有元素排成一列,-1表示自动计算该维度大小。因为原本每个样本有16*4*4=256个元素,所以输出形状为(64, 256)。 -
这样就将卷积层输出的特征图“展平”成二维矩阵,每一行对应一个样本的特征向量,以便输入全连接层。
-
A错:不是增加维度,而是合并后面的维度。
-
C错:不是转置。
-
D错:不是复制。
第5题
题目:数据增强通常只应用于( )
A. 训练集
B. 测试集
C. 验证集
D. 所有数据集
答案:A
详细解析:
-
数据增强是为了增加训练样本的多样性,防止过拟合,提升泛化能力。
-
测试集必须保持原始、未经修改的状态,因为我们要评估模型在真实数据上的表现。如果对测试集也做随机变换,那么评估结果就不稳定且不公平。
-
验证集同理,一般不使用数据增强,以保证其能真实反映模型性能。
-
所以只用于训练集。
二、填空题
第6题
题目:卷积输出尺寸计算公式为:Hout=(____+2×padding−kernel_size)//____+1Hout=(____+2×padding−kernel_size)//____+1。
答案:H_in;stride
详细解析:
-
标准公式中的分子部分是
H_in + 2*padding - kernel_size,分母是stride,然后向下取整再加1。 -
这里
//表示整数除法(向下取整)。
第7题
题目:一个 Conv2d(3, 16, kernel_size=3, stride=1, padding=1) 层的卷积核形状是 (16, _, _, _)。
答案:3;3;3
详细解析:
-
nn.Conv2d的卷积核形状为(out_channels, in_channels, kernel_height, kernel_width)。 -
这里 out_channels=16,in_channels=3(输入是RGB图像,3通道),kernel_size=3(正方形,所以高=3,宽=3)。
-
因此形状是
(16, 3, 3, 3)。 -
注意:顺序不能写错,第一个数是输出通道,第二个是输入通道。
第8题
题目:感受野计算函数中,从最后一层向前递推:rf = rf + (k - 1) * s。若两层卷积核均为3,步幅第一层2、第二层1,则最终感受野大小为 ______。
答案:7
详细解析:
-
感受野计算需要从最后一层往输入层方向递推。
-
初始
rf = 1(最后一层的输出神经元)。 -
考虑最后一层(第二层,因为它是最靠近输出的一层,通常我们说的“第一层”是靠近输入)。题目说“两层卷积核均为3,步幅第一层2、第二层1”,意思是第一层(靠近输入)stride=2,第二层(靠近输出)stride=1。
-
我们从最后一层(第二层)开始向前推:
-
处理第二层(从后往前第一个卷积层):k=3,s=1 →
rf = 1 + (3-1)*1 = 1 + 2 = 3 -
再往前处理第一层:k=3,s=2 →
rf = 3 + (3-1)*2 = 3 + 4 = 7
-
-
所以感受野大小为 7×7。
-
注意:如果题目说的是两层,顺序是输入→第一层(3×3, stride=2)→第二层(3×3, stride=1)→输出。那么计算正确。
第9题
题目:LeNet中,第二个池化层 pool2 的输入通道数是 ______,输出通道数不变。
答案:16
详细解析:
-
LeNet 中
conv2的输出通道是16,然后pool2紧接着conv2,所以pool2的输入通道数就是16。 -
池化层不会改变通道数,只改变空间尺寸。
第10题
题目:在PyTorch中,unsqueeze(0) 是在第0维增加一个维度,squeeze() 用于移除维度大小为 ______ 的维度。
答案:1
详细解析:
-
squeeze()默认移除所有长度为1的维度。例如形状(1, 3, 1, 5)经过squeeze()后变成(3, 5)。 -
若指定
squeeze(dim),则只移除该维度(前提是它长度为1)。 -
所以填空填
1。
三、判断题
第11题
题目:卷积核的数量决定输出特征图的通道数。
答案:√
详细解析:
-
卷积层中,每个输出通道对应一个独立的卷积核(一组权重)。
-
out_channels参数就是卷积核的数量,输出特征图的通道数等于out_channels。
第12题
题目:池化层具有可训练参数。
答案:×
详细解析:
-
池化层(最大池化、平均池化)没有权重和偏置,只是固定操作(取最大值或平均值),不参与梯度更新。
-
因此没有可训练参数。
第13题
题目:感受野只与卷积核大小有关,与步幅无关。
答案:×
详细解析:
-
感受野与卷积核大小和步幅都有关。步幅越大,每层向前跳跃的步长越大,感受野增长越快。
-
例如:单层卷积,核3,步幅1,感受野3;步幅2,感受野3?这里单层感受野就是核大小,步幅不影响单层的感受野,但影响多层叠加后的感受野。对多层网络,步幅会放大感受野。
第14题
题目:数据增强可以帮助提高模型泛化能力。
答案:√
详细解析:
-
数据增强通过对训练图像进行随机变换(旋转、翻转、缩放等),创建更多样化的样本,使模型学习到更鲁棒的特征,从而减少过拟合,提高泛化能力。
第15题
题目:在LeNet的forward中,x = x.view(x.size(0), -1) 之前不需要展平,因为全连接层会自动处理。
答案:×
详细解析:
-
nn.Linear层的输入要求是二维:(batch, features)。 -
卷积层输出的特征是四维:
(batch, channels, height, width),必须手动展平成二维,否则Linear会报错或产生错误结果。 -
因此展平是必要的。
四、简答题(仅选部分详细展开)
由于篇幅限制,这里只展示 简答题1、2、3 的超详细解析,其余同理。
简答题1
题目:写出卷积输出尺寸的计算公式。
答案:
其中 H_in 是输入高度,padding 是填充的圈数,kernel_size 是卷积核高度,stride 是步幅。宽度相同公式。
简答题2
题目:使用给定参数(stride=1,padding=0),写出输出的第2行第1个数是如何计算出来的(可参考代码中的输入和卷积核)。
详细答案:
-
输入是一个5×5矩阵(值1到25),卷积核是3×3(值 [[1,0,-1],[1,0,-1],[1,0,-1]])。
-
输出第2行第1个数对应卷积核中心与输入的第2行第1列对齐,此时卷积核覆盖输入的区域是:
输入的行索引1~3,列索引0~2(从0开始)。
这些位置的值为:
[ [6,7,8],
[11,12,13],
[16,17,18] ] -
与卷积核逐元素相乘再求和:
(6×1)+(7×0)+(8×(-1)) + (11×1)+(12×0)+(13×(-1)) + (16×1)+(17×0)+(18×(-1))
= (6 -8) + (11-13) + (16-18)
= (-2) + (-2) + (-2) = -6 -
因此程序输出的该位置值为 -6。
简答题3
题目:当 padding = (kernel_size - 1) // 2 且 stride=1 时,输出尺寸等于什么?这种填充方式叫什么?
答案:
-
代入公式:
H_out = (H_in + 2*((k-1)//2) - k) // 1 + 1
如果 k 是奇数,(k-1)//2 = (k-1)/2,则分子H_in + (k-1) - k = H_in -1,除以1得H_in -1,再加1得H_in。
所以输出尺寸等于输入尺寸。 -
这种填充方式称为 Same Padding(或保形填充)。
简答题4 在 nn.Conv2d 中,可以直接使用 padding='same' 参数实现相同效果吗?为什么?
答案:不能。nn.Conv2d 的 padding 参数只能接收整数或元组,不支持字符串 'same'。需要手动计算 padding = (kernel_size - 1) // 2 来实现 same padding(当 stride=1 时)。
详细解析:
-
PyTorch的
nn.Conv2d设计上padding参数接受int或tuple,表示填充的行/列数。 -
一些高级框架(如 TensorFlow)的卷积层支持
padding='same',但 PyTorch 没有直接支持。 -
如果希望自动计算 same padding,可以自己写函数或使用
torch.nn.functional.pad。 -
在 stride 不为1时,same padding 的定义更复杂(需要保证输出尺寸 = ceil(输入/步长)),此时不能简单用
(k-1)//2计算。 -
本实验只讨论 stride=1 的情况。
简答题5 unsqueeze 和 squeeze 的作用?为什么池化前需要增加维度?
答案:
-
unsqueeze(dim):在指定维度插入一个大小为1的新维度。 -
squeeze():移除所有大小为1的维度(或指定维度)。 -
池化前需要增加维度是因为 PyTorch 的池化层(
nn.MaxPool2d等)要求输入为4维张量:(batch, channels, height, width)。而手动创建的特征图通常是2维(height, width)或3维(channels, height, width),缺少 batch 或 channel 维度,因此需要用unsqueeze补充。
详细解析:
-
例如一个单通道特征图
(28,28),需要先unsqueeze(0)变为(1,28,28)添加 batch 维度,再unsqueeze(0)变为(1,1,28,28)添加 channel 维度。实际更常见的是直接构建4维张量。 -
在数据加载器中,返回的 batch 已经是
(batch, channels, H, W),不需要手动添加。但单独测试某个特征图时需要。 -
squeeze常用于移除不必要的单维度,以便显示或与全连接层对接。
简答题6 最大池化和平均池化对4×4特征图的结果(分别写出)?池化的主要作用?
题目中特征图:实验中给出的4×4矩阵(值1~16):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
池化参数:kernel_size=2, stride=2(不重叠)。
答案:
-
最大池化结果:
6 8 14 16
-
平均池化结果:
3.5 5.5 11.5 13.5
-
池化的主要作用:
-
降低特征图的空间尺寸(下采样),减少计算量和参数量。
-
增强平移不变性(对微小位移不敏感)。
-
最大池化保留最显著的特征,平均池化保留整体信息。
-
详细计算过程:
-
将4×4分成2×2不重叠的4个窗口:
-
窗口1(左上):[1,2;5,6] → 最大值6,平均值(1+2+5+6)/4=3.5
-
窗口2(右上):[3,4;7,8] → 最大值8,平均值(3+4+7+8)/4=5.5
-
窗口3(左下):[9,10;13,14] → 最大值14,平均值(9+10+13+14)/4=11.5
-
窗口4(右下):[11,12;15,16] → 最大值16,平均值(11+12+15+16)/4=13.5
-
-
池化输出尺寸 = 2×2。
简答题7 感受野为什么重要?网络更深时感受野如何变化?
答案:
-
感受野决定了某一层的神经元在原始输入图像上能看到的区域大小。感受野越大,神经元能整合更全局的上下文信息。
-
网络越深,感受野越大。因为每一层卷积都会扩大感受野(尤其是步幅大于1时)。
详细解析:
-
在目标检测中,如果感受野太小,可能看不清大物体;如果感受野太大,可能对小物体不敏感。设计网络时需要平衡。
-
感受野的计算公式(从后向前):
RF_prev = (RF_cur - 1) * stride + kernel_size。 -
随着层数增加,感受野呈指数级增长(如果步幅>1)或线性增长(步幅=1)。
-
例如:单层3×3卷积,步幅1,感受野=3;两层3×3卷积,步幅1,感受野=5;若步幅为2,感受野增长更快。
简答题8 对于卷积层 Conv2d(3, 16, kernel_size=3),其权重张量的形状是什么?各数字的含义是什么?
答案:
-
权重张量形状:
(16, 3, 3, 3) -
含义:
-
第一个
16:输出通道数(卷积核的个数) -
第二个
3:输入通道数(例如RGB图像的3个通道) -
第三个
3:卷积核的高度 -
第四个
3:卷积核的宽度
-
详细解析:
-
PyTorch中,卷积层的权重通过
conv.weight访问,形状为(out_channels, in_channels, kernel_h, kernel_w)。 -
构造函数参数顺序是
(in_channels, out_channels, kernel_size),容易混淆。但权重张量的第一个维度是out_channels。 -
每个输出通道对应一组独立的卷积核,该组内有
in_channels个二维核(每个输入通道一个)。 -
所以总参数量 =
16 × 3 × 3 × 3 = 432(不含偏置)。
简答题9 数据增强的作用?测试集为何不用?
答案:
-
作用:通过对训练图像进行随机变换(旋转、翻转、缩放、裁剪等),增加训练样本的多样性,防止模型过拟合,提高泛化能力。
-
测试集不用:测试集需要反映真实、未变形的数据分布,以公平评估模型的性能。对测试集使用数据增强会导致结果不稳定且不可重复,无法与其他模型公平比较。
详细解析:
-
数据增强相当于一种正则化方法,让模型看到更多变体,学会提取鲁棒特征。
-
常见增强:随机旋转±10°,水平翻转,随机裁剪,颜色抖动等。
-
测试集应保持原始状态,不做任何随机变换,通常只做归一化。
简答题10 x.view(x.size(0), -1) 的作用?
答案:将卷积输出的多维特征图展平为一维向量,同时保留 batch 维度,以便输入全连接层。
详细解析:
-
假设经过卷积和池化后,
x的形状为(batch, channels, height, width),例如(64, 16, 4, 4)。 -
x.size(0)是 batch 大小(64)。 -
-1表示自动计算该维度的大小,结果为channels * height * width = 16*4*4=256。 -
因此
x.view(64, -1)输出形状(64, 256),每个样本的特征被拉直成一维向量。 -
全连接层(
nn.Linear)要求输入是2维(batch, features),所以这一步是必须的。 -
不使用
reshape而用view是因为view要求内存连续,且不会复制数据,效率更高。如果内存不连续可用reshape。
五、计算题(详细步骤)
5.1 特征图尺寸计算(每题2分)
-
输入32×32×3,Conv2d(3,16,3, stride=1, padding=0)
-
公式:(32 + 0 - 3)/1 + 1 = 30 → 30×30(通道数16不变,但题目只要求尺寸,答30×30)
-
-
输入30×30×16,MaxPool2d(2, stride=2)
-
公式:(30 - 2)/2 + 1 = 28/2=14 +1=15 → 15×15(通道数16不变)
-
-
输入32×32×3,Conv2d(3,16,5, stride=2, padding=1)
-
公式:(32 + 2×1 - 5)/2 + 1 = (32+2-5)=29,29÷2=14(整数除法),+1=15 → 15×15
-
-
输入28×28×6,Conv2d(6,16,5, stride=1, padding=0)
-
(28 + 0 - 5)/1 + 1 = 24 → 24×24
-
注意:题目中要求输出尺寸,不需要写通道数,只写高×宽。
5.2 感受野计算(6分)
题目:三层卷积网络:第一层 kernel=3, stride=2;第二层 kernel=3, stride=1;第三层 kernel=3, stride=1。求第三层特征图上每个神经元相对于原始输入的感受野。
步骤:
-
从最后一层(第三层)开始向前计算。
-
初始 RF = 1(第三层输出神经元)。
-
处理第三层(这是反向第一层,即从后往前第一个卷积层):k=3, s=1
RF = 1 + (3-1)*1 = 3 -
处理第二层:k=3, s=1
RF = 3 + (3-1)*1 = 5 -
处理第一层:k=3, s=2
RF = 5 + (3-1)*2 = 5 + 4 = 9 -
所以感受野大小为 9×9。
解析:为什么这样算?因为感受野的计算可以理解为:当前层的神经元在上一层的输入区域大小是 (RF_prev - 1)*stride + kernel,从后向前递推。实验代码中的函数 receptive_field 正是这样实现的。
5.3 LeNet特征图填空(6分)
已知输入 1×28×28:
| 层 | 计算过程 | 输出形状 |
|---|---|---|
| conv1 (k5,s1,p0, 1→6) | (28-5)/1+1=24 | 6×24×24 |
| pool1 (2×2,s2) | 24/2=12 | 6×12×12 |
| conv2 (k5,s1,p0, 6→16) | (12-5)/1+1=8 | 16×8×8 |
| pool2 (2×2,s2) | 8/2=4 | 16×4×4 |
| flatten | 16×4×4=256 | 256(一维) |
六、代码填空题答案
-
1(in_channels) -
6(out_channels) -
5(kernel_size) -
2(kernel_size) -
2(stride) -
k -
s -
view -
10(旋转 ±10 度)
解析:
空1、空2、空3:分别填 1、6、5。
详细解析:
-
空1(in_channels):输入通道数。MNIST数据集的图像是灰度图,只有一个颜色通道,所以
in_channels=1。 -
空2(out_channels):输出通道数,也等于卷积核的个数。这里我们希望输出6个特征图(原LeNet设计),所以填
6。 -
空3(kernel_size):卷积核大小。LeNet中第一个卷积核是5×5,所以填
5。 -
为什么输出形状是 (1,6,24,24)?
使用公式:H_out = (H_in + 2*padding - kernel_size) // stride + 1
代入:H_in=28, padding=0, kernel_size=5, stride=1→(28+0-5)//1 +1 = 23+1=24。
输出通道数等于out_channels=6,batch=1,所以形状(1,6,24,24)。
空4、空5:分别填 2、2。
详细解析:
-
池化层的
kernel_size=2表示池化窗口是 2×2,stride=2表示窗口每次滑动2步(不重叠)。 -
输入特征图尺寸是 24×24,池化后尺寸减半:
24//2=12。通道数不变(仍为6),所以输出(1,6,12,12)。 -
公式验证:
(24 - 2)//2 +1 = 22//2+1=11+1=12。正确。
空6、空7:分别填 k、s。
详细解析:
-
感受野递推公式(从最后一层向第一层):
RF_prev = (RF_cur - 1) * stride + kernel_size -
在循环中,
k是当前层的卷积核大小,s是当前层的步幅。公式写成增量形式:RF_new = RF_old + (k - 1) * s -
所以
(______ - 1)应该填入k,* ______应该填入s。 -
如果填其他数字,计算结果就会错误。
空8:填 view。
详细解析:
-
经过两个卷积-池化块后,
x的形状是(batch, 16, 4, 4)。全连接层(nn.Linear)要求输入是二维:(batch, features)。 -
x.size(0)是 batch 大小,-1表示自动计算剩下的维度总数(16*4*4=256)。 -
view(x.size(0), -1)将每个样本的特征图拉直成一维,得到(batch, 256)。 -
PyTorch 中改变形状用
view,不能用reshape吗?也可以,但 LeNet 经典写法用view。题目填view是正确的。
空9:填 10。
详细解析:
-
RandomRotation(degrees)中degrees表示旋转角度的范围。如果填10,表示在[-10, +10]度之间随机旋转。 -
实验要求“随机旋转 ±10度”,所以填
10。 -
如果填
20,就变成 ±20 度,会旋转过大,可能影响识别。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)