
CNN在卷什么:五大组件详解,一文讲透卷积神经网络副标题: 从LeNet到ResNet,为什么这5个组件是CNN的标配痛点:CNN的五大组件是什么?学CNN的时候,你是不是分不清这些概念?卷积层vs池化层:都是"滑动",有什么区别?BatchNorm到底在做什么?为什么需要它?Dropout随机丢弃神经元,不会破坏网络吗?激活函数:ReLU vs Sigmoid vs Tanh,该用哪个?更关键的是:这五个组件为什么总是成对出现?今天这篇文章,就是要把CNN的五大组件讲透。一、卷积层(Conv Layer):信息的抽象化1.1 卷积层在做什么?核心功能:提取特征classConvLayer(nn.Module):def__init__(self,in_channels,out_channels,kernel_size=3):super().__init__()self.conv=nn.Conv2d(in_channels,out_channels,kernel_size=kernel_size,padding=kernel_size//2# 保持尺寸)self.activation=nn.ReLU()defforward(self,x):returnself.activation(self.conv(x))输入:原始像素 / 低级特征输出:高级特征1.2 逐通道分析:卷积层学什么?importtorchimporttorchvision.modelsasmodelsimportmatplotlib.pyplotasplt# 加载ResNet18预训练模型model=models.resnet18(pretrained=True)# 获取第一层卷积核conv1_weights=model.conv1.weight.data# [64, 3, 7, 7]# 可视化前12个卷积核fig,axes=plt.subplots(3,4,figsize=(12,9))fori,axinenumerate(axes.flat):ifi12:# 前3个通道的RGB可视化kernel=conv1_weights[i].cpu().numpy()# [3, 7, 7]# 归一化到0-1kernel=(kernel-kernel.min())/(kernel.max()-kernel.min()+1e-8)ax.imshow(kernel.transpose(1,2,0))ax.set_title(f'Filter{i+1}')ax.axis('off')观察:前几个卷积核类似边缘检测器(黑白条纹)中间层卷积核开始出现纹理检测器最后层卷积核是复杂的模式检测器1.3 感受野:卷积核的"视野"为什么需要深层网络:defcompute_receptive_field(layers_info):""" 计算每一层的感受野 layers_info: [{'kernel': 7, 'stride': 2}, ...] """rf=1forinfoinlayers_info:kernel=info['kernel']stride=info['stride']rf=rf*stride+(kernel-stride)returnrf# ResNet18的感受野计算resnet18_layers=[{'kernel':7,'stride':2},# conv1{'kernel':3,'stride':2},# maxpool{'kernel':3,'stride':1},# layer1 (大部分是stride=1){'kernel':3,'stride':2},# layer2{'kernel':3,'stride':2},# layer3{'kernel':3,'stride':2},# layer4]foriinrange(len(resnet18_layers)):print(f"Layer{i}: RF ={compute_receptive_field(resnet18_layers[:i+1])}")输出:Layer 0: RF = 7 Layer 1: RF = 10 Layer 2: RF = 12 Layer 3: RF = 16 Layer 4: RF = 24 Layer 5: RF = 321.4 通道数设计:深度网络的宽度为什么ResNet通道数是64→128→256→512?# 经典CNN通道数设计classCNNDesign(nn.Module):def__init__(self):super().__init__()# 逐层翻倍通道数self.conv1=nn.Conv2d(3,64,7,stride=2)# 64self.conv2=nn.Conv2d(64,128,3,stride=2)# 128 (×2)self.conv3=nn.Conv2d(128,256,3,stride=2)# 256 (×2)self.conv4=nn.Conv2d(256,512,3,stride=2)# 512 (×2)设计原则:通道数翻倍:保持计算量合理空间尺寸减半:补偿通道数增加FLOPs近似:每一层计算量接近二、池化层(Pooling Layer):信息的压缩2.1 池化层的类型最大池化 vs 平均池化:classPoolingComparison(nn.Module):def__init__(self):super().__init__()self.max_pool=nn.MaxPool2d(2,stride=2)self.avg_pool=nn.AvgPool2d(2,stride=2)defforward(self,x):returnself.avg_pool(self.max_pool(x))数值对比:输入MaxPool输出AvgPool输出[[1,5,3],[4,2,6]][[5,6]][[3,4]]特征最显著特征平滑特征2.2 池化层的数学本质最大池化:max(xi,j)=maxm,nxi+m,j+n\max(x_{i,j}) = \max_{m,n} x_{i+m,j+n}max(xi,j)=