Architecture / Vision and Local Structure

CNN 卷积神经网络:局部感受野、参数共享与特征层级

用一个共享卷积核在局部窗口上滑动,把原始网格信号变成边缘、纹理、形状和任务特征。

Mechanism Lab

动画:卷积核如何把局部窗口变成特征图

动画展示共享卷积核在图像网格上滑动,局部窗口与权重相乘求和,经过 ReLU、池化和分类读出,形成可用于下游任务的特征。

Step 1 / 5

Patch

卷积层先读取局部窗口,而不是一次连接整张图。

R_{i,j}

Animation Control

Reduced-motion users receive the same step states without continuous motion.

01 / 直觉

核心直觉

CNN 的核心归纳偏置是局部性和平移等变:附近像素、表格邻域或时间窗口往往共同决定一个局部模式。

同一个卷积核在所有空间位置共享参数,因此模型不会为每个位置学习一套完全不同的检测器。

浅层卷积常检测边缘和局部纹理,深层卷积组合出更抽象的形状、结构或局部经济信号。

池化或 stride 会降低分辨率、扩大有效感受野,但也会丢失细节;现代网络常在下采样、残差和归一化之间做权衡。

02 / 数学

从离散卷积推导 CNN 层

01 / 局部窗口

对二维输入 X,每个输出位置只看以该位置为中心的 k_h x k_w 局部窗口,而不是连接到整张图。

R_{i,j} = X[i:i+k_h, j:j+k_w]

02 / 参数共享

同一组权重 W 在每个位置复用。若输入有 C_in 个通道、输出有 C_out 个通道,参数量与空间尺寸无关。

#params = k_h k_w C_in C_out + C_out

03 / 卷积输出

第 k 个输出通道是局部窗口与第 k 个卷积核的加权和,再加偏置。多个通道会在局部窗口内求和。

Y[i,j,k]=sum_{u,v,c} W[u,v,c,k] X[i+u,j+v,c]+b_k

04 / 平移等变

若边界效应忽略,输入平移后再卷积,等价于先卷积再平移。这解释了 CNN 为什么擅长检测“同一模式出现在不同位置”。

Conv(T_delta X) = T_delta Conv(X)

05 / 非线性与池化

ReLU 让网络组合多个局部检测器;pooling 或 stride 把局部激活压缩成更粗尺度表示。

Z = pool(phi(Y))

06 / 有效感受野

堆叠 L 层 3x3 stride-1 卷积时,理论感受野每层增加 2;深层单元能整合更大区域。

RF_L = 1 + 2L

03 / 代码

NumPy 演示:手写二维多通道卷积

这个例子不依赖深度学习框架,显式展示局部窗口、共享权重、ReLU 和 max pooling 如何生成特征图。

import numpy as np

def conv2d_valid(x, kernels, bias):
    # x: [height, width, in_channels]
    # kernels: [kernel_h, kernel_w, in_channels, out_channels]
    h, w, c = x.shape
    kh, kw, kc, out_channels = kernels.shape
    assert c == kc
    out = np.zeros((h - kh + 1, w - kw + 1, out_channels))

    for i in range(out.shape[0]):
        for j in range(out.shape[1]):
            patch = x[i:i + kh, j:j + kw, :]
            for k in range(out_channels):
                out[i, j, k] = np.sum(patch * kernels[..., k]) + bias[k]
    return out

def max_pool2d(x, size=2, stride=2):
    h, w, channels = x.shape
    out = np.zeros(((h - size) // stride + 1, (w - size) // stride + 1, channels))
    for i in range(out.shape[0]):
        for j in range(out.shape[1]):
            patch = x[i * stride:i * stride + size, j * stride:j * stride + size, :]
            out[i, j, :] = patch.max(axis=(0, 1))
    return out

rng = np.random.default_rng(5)
image = rng.normal(size=(8, 8, 1))

# A vertical-edge detector and a horizontal-edge detector.
kernels = np.zeros((3, 3, 1, 2))
kernels[:, :, 0, 0] = [[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]]
kernels[:, :, 0, 1] = [[-1, -1, -1], [0, 0, 0], [1, 1, 1]]
bias = np.zeros(2)

features = conv2d_valid(image, kernels, bias)
activated = np.maximum(features, 0.0)
pooled = max_pool2d(activated, size=2, stride=2)

print("feature map:", features.shape)
print("pooled map:", pooled.shape)
print("strongest vertical edge:", activated[..., 0].max())

04 / 案例

案例:把论文图表、遥感图像和网格化经济数据转成局部特征

  • 在研究场景中,CNN 不只用于猫狗图片。它可以处理论文图表截图、卫星夜光图、土地利用栅格、显微图像、交通热力图或局部时间-频率图。
  • 例如用夜间灯光预测经济活动时,浅层卷积检测亮度边界、道路纹理和城市斑块,深层特征把局部模式组合成区域活动强度。
  • 在论文图表理解中,卷积层可以识别轴线、点、误差线和表格边界;后续模型再把这些局部视觉信号接到 OCR、表格解析或 Transformer 表示。
  • 但 CNN 发现的是视觉/网格模式,不自动给出因果解释。政策评估仍需要明确处理组、对照组、时间结构、识别假设和稳健性检验。

05 / 风险

常见误区

把卷积写成全连接,丢掉参数共享和局部结构优势。
过早下采样导致小目标、细线或表格边界信息丢失。
认为 CNN 天然具有旋转、尺度或光照不变性;这些通常来自数据增强、架构设计或训练分布。
忽略 padding、stride 和 dilation 对输出尺寸与感受野的影响。
把卷积特征热力图当作因果解释;它只能说明模型使用了哪些视觉区域,不能证明真实机制。
在经济网格数据中忽视空间相关和样本泄漏,例如相邻地块同时出现在训练集和测试集。

参考资料