4 卷积层
1 常用卷积层
1.1 图像卷积
conv_layer = nn.Conv2d(
in_channels, # 输入通道数
out_channels, # 输出通道数(卷积核的个数)
kernel_size, # 卷积核尺寸
stride=1, # 滑动步长
padding=0, # 边缘填充
dilation=1, # 空洞卷积控制参数
groups=1, # 分组卷积控制参数
bias=True, # 是否使用偏置
padding_mode='zeros' # 填充模式
)
- 输入输出: 假设输入形状为
(batch_size, in_channels, H, W), 经过nn.Conv2d后, 变为(batch_size, out_channels, H_out, W_out), 这里H_outW_out可以通过步长、填充、卷积核尺寸计算. - 空洞卷积: 在卷积核像素间添加空洞来扩大感受野, 默认
dilation=1不做填充,dilation=2添加 1 个像素. - 分组卷积: 参见 AlexNet. 核心思想是将输入输出通道分成若干组, 每组独立进行卷积. 设
groups=g.g=1就是默认的不分组.- 输入通道分成了
g组, 每组有in_channels // g个通道. - 输出通道也变成
g组, 每组有out_channels // g个通道. - 每个输出组只与对应输入组卷积, 组间没有交互.
- 最后的
g组拼接得到最后输出. - 分组卷积阻隔了组间信息, 降低了模型的表示能力. 分组后通常要添加 1 x 1 卷积来混合组间信息
- 输入通道分成了
- 填充模式:
'zeros': 用 0 填充. 基本上足够了.'reflect': 反射填充. 以边界为对称轴进行镜像填充.'replicate': 复制填充. 将边界的像素复制.'circular': 周期填充. 只在严格周期边界使用.
1.2 最大池化层
pool_layer = nn.MaxPool2d(
kernel_size, # 池化窗口尺寸, 可以是整数或者(h,w)元组
stride=None, # 滑动步长, 默认为 kernel_size
padding=0,
dilation=1,
return_indices=False, # 返回最大值位置的索引
ceil_mode=False, #True为向上取整, False为向下取整
)
池化层没有可学习的参数, 只是进行下采样操作.
通常使用 kernel_size=2, stride=2, ceil_mode=False 组合.
1.3 平均池化层
pool_layer = nn.AvgPool2d(
kernel_size,
stride=None,
padding=0,
ceil_mode=False,
count_include_pad=True # 是否将填充像素计入平均值的分母, 不常用
)
1.4 自适应池化层
根据要求自动调整池化窗口的大小和步长, 得到期望的输出尺寸.
- 自适应平均池化:
nn.AdaptiveAvgPool2d(output_size) - 自适应最大池化:
nn.AdaptiveMaxPool2d(output_size)
output_size 可以是整数或者 (h,w) 元组.
1.5 上采样层
upsample_layer = nn.Upsample(
size=None, # 期望输出尺寸(int/tuple)
scale_factor=None, # 缩放倍数(float/tuple)
mode='nearest', # 插值模式
align_corners=None,# 是否对齐角点
)
mode可选'nearest''bilinear''bicubic''trilinear''linear'.align_corners仅在'bilinear''bicubic'下设置. 一般设为True.
1.6 转置卷积层
或者称为反卷积. 它是一种可学习的利用卷积核运算实现的上采样.
conv_trans = nn.ConvTranspose2d(
in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
output_padding=0 # 在输出时额外填充, 用于调整输出尺寸
)
1.7 展平层
CNN 中我们需要将多维张量 (如 (N, C, H, W)) 展平成一维的.
flatten_layer = nn.Flatten(
start_dim=1,# 从哪个维度开始展平, 默认1, 即保留batch维度
end_dim=-1 # 默认-1表示最后一维
)
- 例如, 如果指定
(1, -1), 则输出为(N, C*H*W). 如果start_dim=2, 则为(N, C, H*W) - 它和
x.view(x.size(0), -1)等价, 但是能放入nn.Sequential, 代码更简洁, 且无需自己计算维度
1.8 2D 批归一化层
nn.BatchNorm2d(num_features). 它会对每个通道独立进行归一化.
x = torch.randn(4, 16, 8, 8)
bn = nn.BatchNorm2d(num_features=16) # 指定通道数
y = bn(x)
print(y.shape) # torch.Size([4, 16, 8, 8])形状不变