各版本ResNet变体通道数解析

📊 各版本ResNet通道数对比表

模型变体 Layer1 Layer2 Layer3 Layer4 总参数量
基础残差块系列
ResNet18 64 128 256 512 11.7M
ResNet34 64 128 256 512 21.8M
瓶颈块系列
ResNet50 256 512 1024 2048 25.6M
ResNet101 256 512 1024 2048 44.5M
ResNet152 256 512 1024 2048 60.2M

浅层:通道少,空间大 → 细节信息

深层:通道多,空间小 → 语义信息

🔬 各版本ResNet详细通道数

ResNet18

结构:8个基础残差块

输入 (3, H, W)

Conv1 (64, H/2, W/2) # 7x7, stride=2

MaxPool (64, H/4, W/4) # 3x3, stride=2

Layer1: 64 → 64 × 2 # 2个残差块,通道数不变

Layer2: 64 → 128 × 2 # 2个残差块,通道数翻倍

Layer3: 128 → 256 × 2 # 2个残差块,通道数翻倍

Layer4: 256 → 512 × 2 # 2个残差块,通道数翻倍

输出通道数 :[64, 128, 256, 512]

ResNet34

结构:16个基础残差块

输入 (3, H, W)

Conv1 (64, H/2, W/2)

MaxPool (64, H/4, W/4)

Layer1: 64 → 64 × 3 # 3个残差块

Layer2: 64 → 128 × 4 # 4个残差块

Layer3: 128 → 256 × 6 # 6个残差块

Layer4: 256 → 512 × 3 # 3个残差块

输出通道数 :[64, 128, 256, 512]

ResNet50

结构:16个瓶颈块

输入 (3, H, W)

Conv1 (64, H/2, W/2)

MaxPool (64, H/4, W/4)

Layer1: 64 → 64 → 256 × 3 # 瓶颈块:64→64(3x3)→256

Layer2: 256 → 128 → 512 × 4 # 256→128(3x3)→512

Layer3: 512 → 256 → 1024 × 6 # 512→256(3x3)→1024

Layer4: 1024 → 512 → 2048 × 3 # 1024→512(3x3)→2048

输出通道数 :[256, 512, 1024, 2048]

ResNet101

结构:33个瓶颈块

输入 (3, H, W)

Conv1 (64, H/2, W/2)

MaxPool (64, H/4, W/4)

Layer1: 64 → 64 → 256 × 3 # 3个瓶颈块

Layer2: 256 → 128 → 512 × 4 # 4个瓶颈块

Layer3: 512 → 256 → 1024 × 23 # 23个瓶颈块 ⭐

Layer4: 1024 → 512 → 2048 × 3 # 3个瓶颈块

输出通道数 :[256, 512, 1024, 2048]

ResNet152

结构:50个瓶颈块

输入 (3, H, W)

Conv1 (64, H/2, W/2)

MaxPool (64, H/4, W/4)

Layer1: 64 → 64 → 256 × 3 # 3个瓶颈块

Layer2: 256 → 128 → 512 × 8 # 8个瓶颈块

Layer3: 512 → 256 → 1024 × 36 # 36个瓶颈块 ⭐

Layer4: 1024 → 512 → 2048 × 3 # 3个瓶颈块

输出通道数 :[256, 512, 1024, 2048]

📏 各层级特征图详细尺寸表

经典ResNet (18/34/50/101/152)

层级 输入尺寸 输出尺寸 下采样倍数 相对输入比例
Conv1 224×224 112×112 2 1/2
MaxPool 112×112 56×56 4 1/4
Layer1 56×56 56×56 4 1/4
Layer2 56×56 28×28 8 1/8
Layer3 28×28 14×14 16 1/16
Layer4 14×14 7×7 32 1/32

对于ResNet,由于采用了大量的步长为2的卷积和池化,特征图尺寸呈现规律性的减半

🎨 代码模板:ResNet特征提取器

python 复制代码
import torch
import torch.nn as nn
import torchvision.models as models

class ResNetFeatureExtractor(nn.Module):
    def __init__(self, backbone_name='resnet34', pretrained=True):
        super().__init__()
        
        # 获取预训练模型
        self.backbone = self._get_backbone(backbone_name, pretrained)
        
        # 根据backbone类型设置输出通道数
        self.output_channels = self._get_output_channels(backbone_name)
        
        # 拆解网络
        self._build_feature_extractor()
        
    def _get_backbone(self, name, pretrained):
        weights = 'IMAGENET1K_V1' if pretrained else None
        if name == 'resnet18':
            return models.resnet18(weights=weights)
        elif name == 'resnet34':
            return models.resnet34(weights=weights)
        elif name == 'resnet50':
            return models.resnet50(weights=weights)
            
    def _get_output_channels(self, name):
        # 返回各阶段的输出通道数
        channels_dict = {
            'resnet18': [64, 128, 256, 512],
            'resnet34': [64, 128, 256, 512],
            'resnet50': [256, 512, 1024, 2048],
        }
        return channels_dict.get(name, [])
    
    def _build_feature_extractor(self):
        # 提取各层
        self.conv1 = self.backbone.conv1
        self.bn1 = self.backbone.bn1
        self.relu = self.backbone.relu
        self.maxpool = self.backbone.maxpool
        self.layer1 = self.backbone.layer1
        self.layer2 = self.backbone.layer2
        self.layer3 = self.backbone.layer3
        self.layer4 = self.backbone.layer4
        
    def forward(self, x):
        # 逐层前向传播
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)
        
        c1 = self.layer1(x)   # 1/4分辨率
        c2 = self.layer2(c1)  # 1/8分辨率
        c3 = self.layer3(c2)  # 1/16分辨率
        c4 = self.layer4(c3)  # 1/32分辨率
        
        return {
            'c1': c1,  # 浅层特征
            'c2': c2,  # 中層特征
            'c3': c3,  # 深层特征
            'c4': c4,  # 最深层特征
        }

# 使用示例
extractor = ResNetFeatureExtractor('resnet50')
x = torch.randn(1, 3, 224, 224)
features = extractor(x)

for name, feat in features.items():
    print(f"{name}: {feat.shape}")
# 输出:
# c1: torch.Size([1, 256, 56, 56])
# c2: torch.Size([1, 512, 28, 28]) 
# c3: torch.Size([1, 1024, 14, 14])
# c4: torch.Size([1, 2048, 7, 7])

🚀 实践中的选择策略

何时使用哪一层特征?

任务类型 推荐使用的特征层 原因
小目标检测 Layer2 (1/8) 保留更多空间细节
大目标检测 Layer4 (1/32) 语义信息丰富
实例分割 Layer2 + Layer3 平衡细节和语义
图像分类 Layer4 只需高层语义

📌 选择建议

初学者/快速实验:ResNet18 或 ResNet34

工业级应用:ResNet50 或 ResNeXt50

竞赛/高精度:ResNet101 或 ResNeXt101

超大模型:Wide ResNet系列

移动端部署:ResNet18(可考虑量化)

理解这些通道数设计,能帮助你更好地选择和调整backbone,为下游任务提供最合适的特征表示。

相关推荐
冬奇Lab18 小时前
Workflow 系列(03):状态管理——持久化、幂等性与版本绑定
人工智能·工作流引擎
冬奇Lab18 小时前
每日一个开源项目(第146篇):openpilot - 开源自动驾驶辅助系统,曾在 Consumer Reports 评测中超过特斯拉 Autopilot
人工智能·开源·自动驾驶
吴佳浩20 小时前
AI 工程师知识地图:模型格式、框架、部署工具一次讲明白
人工智能·aigc·ai编程
IT_陈寒20 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
码农胖大海20 小时前
AI额度不够用的解决方案
人工智能
后端小肥肠21 小时前
小红书虚拟商品怎么做?我先用 Skill 跑通了壁纸品类
人工智能·aigc·agent
feiyu_gao21 小时前
从零搭建个人 AI 工作台:一个管理者的 3 个月实验
人工智能·aigc·团队管理
程序员cxuan1 天前
一句话,让你用上 GPT-5.6
人工智能·后端·程序员
机器之心1 天前
AI圈刚开始谈Loop Engineering,两位95后博士已经盯上了人类闭环数据
人工智能·openai