Python 现代开发学习笔记

(二十一)池化、通道与图形分类网络

1. 从局部窗口取最大值

上节代码最后的池化按 2×2 窗口、每次跨两格,分别取最大值,得到 [[5,7],[6,9]]。MaxPool2d(2) 没有需要训练的窗口权重,它把每个局部区域概括为一个最大值,输出的空间长宽各缩为一半。

四乘四数据按四个不重叠窗口分别选出五、七、六、九,写入二乘二池化输出

2. 沿每一层核对形状

# 续写同一文件:training_project/src/readingtorch/models.py
class SymbolCNN(nn.Module):
    def __init__(self):
        super().__init__()
        # 空间大小依次为 8×8、4×4、2×2,最后每张图得到 32 个数。
        self.features = nn.Sequential(
            nn.Conv2d(1, 4, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2),
            nn.Conv2d(4, 8, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2),
        )
        self.head = nn.Sequential(nn.Flatten(), nn.Dropout(0.2), nn.Linear(32, 3))

    def forward(self, x):
        return self.head(self.features(x))  # 三个未做 softmax 的 logits。


def build_model(task):
    if task == "regression":
        return ReadingRegressor()
    if task == "images":
        return SymbolCNN()
    raise ValueError("未知模型任务")

第一层 Conv2d(1,4,3,padding=1) 用四组权重读单通道图,得到四张特征图;第二层把前一层的四个通道一起读入,每组卷积权重会合并四个通道的对应窗口,再输出八张特征图。

经过的动作 一批数据的形状
原始单通道图 (B,1,8,8)
第一层卷积与 ReLU (B,4,8,8)
第一次池化 (B,4,4,4)
第二层卷积与 ReLU (B,8,4,4)
第二次池化 (B,8,2,2)
Flatten() (B,32)
Dropout、线性分类层 (B,3)

Flatten 默认保留批次轴,把每张图的 8×2×2 个数排成 32 项。末层输出三个 logits,与长度 B 的类别编号一起进入交叉熵。

按样本通道高宽追踪两次卷积和池化,八个二乘二通道展开为三十二个特征,再映射为竖线横线十字三个分数

第一层参数数为 4×(1×3×3+1)=40,第二层为 8×(4×3×3+1)=296,末层为 3×(32+1)=99,合计 435。每组窗口权重在所有位置复用,参数数量没有再乘图像位置数。

笔记正文与全部题解 · Ctrl / ⌘ K