如何把 wide_resnet50_2.tv2_in1k 用作特征骨干(Feature Backbone):特征图提取完整教程
如何把 wide_resnet50_2.tv2_in1k 用作特征骨干(Feature Backbone):特征图提取完整教程
wide_resnet50_2.tv2_in1k 是 timm 生态中在 ImageNet-1k 上预训练的高性能 Wide ResNet 图像分类模型,同时也是目标检测、语义分割等下游任务中非常实用的特征骨干(Feature Backbone)。本教程面向新手,手把手教你如何用几行代码提取它的多尺度特征图,并理解每一层输出的尺寸与含义。
📦 模型速览:宽版 ResNet-50 凭什么好用?
wide_resnet50_2 采用"加宽不加深"的设计思路——在 ResNet-50 的骨干网络上将每层通道数扩大一倍,用更宽的卷积提取更丰富的特征。它的几个关键特点:
- ReLU 激活:结构直接,推理开销小
- 单层 7×7 卷积 + 池化:输入端先做一次下采样
- 1×1 卷积 shortcut 下采样:跳连中用轻量卷积完成通道与分辨率对齐
核心指标一览(详见 README.md#L21-L31):
| 指标 | 数值 |
|---|---|
| 参数量 | 68.9M |
| 计算量 | 7.3 GMACs |
| 训练 / 测试输入尺寸 | 176×176 / 224×224 |
| Top-1 准确率(224) | 81.61% |
| 推理速度 | 1930 img/sec |
💡 在同参数量的模型中,它以不到 10 GMACs 的计算量跑出了 81%+ 的 Top-1 准确率,是"精度-速度"平衡非常出色的特征提取器。
🔍 什么是特征骨干模式?features_only 参数详解
默认情况下,ResNet 的完整前向流程是:
卷积骨干 → 全局平均池化 → 全连接分类头 → 1000 类 logits
而做检测、分割时,我们不需要最后那个"分类头",需要的是骨干网络逐层输出的多尺度特征图(Feature Pyramid)。timm 只需用一个参数就能切换模式:
features_only=True
设置后,模型会跳过池化和分类层,前向时直接返回 5 张特征图,从高分辨率低层到高语义高层,正好对应特征金字塔的 5 个阶段。
🚀 特征图提取:三步走完整步骤
以下是完整的最小可用示例(完整版见 README.md#L56-L89):
import timm
from PIL import Image
from urllib.request import urlopen
# 第 1 步:以特征骨干模式加载预训练模型
model = timm.create_model(
'wide_resnet50_2.tv2_in1k',
pretrained=True,
features_only=True, # 关键参数:只输出特征图
)
model = model.eval()
# 第 2 步:构建与模型匹配的数据增强(resize + 归一化)
data_config = timm.data.resolve_model_data_config(model)
transforms = timm.data.create_transform(**data_config, is_training=False)
# 第 3 步:前向推理,直接得到特征图列表
img = Image.open(urlopen('https://example.com/cat.png'))
output = model(transforms(img).unsqueeze(0))
for o in output:
print(o.shape)
运行后你会得到这样一组输出:
| 特征层 | 形状(batch=1) | 空间分辨率 | 说明 |
|---|---|---|---|
| 第 1 层 | [1, 64, 88, 88] |
88×88 | 边缘、纹理等底层特征 |
| 第 2 层 | [1, 256, 44, 44] |
44×44 | 局部结构 |
| 第 3 层 | [1, 512, 22, 22] |
22×22 | 部件级特征 |
| 第 4 层 | [1, 1024, 11, 11] |
11×11 | 语义信息增强 |
| 第 5 层 | [1, 2048, 6, 6] |
6×6 | 高层语义,通道数最多 |
📌 注意空间分辨率从 88 逐步降到 6,是输入 224×224 经 4 次 2 倍下采样的结果;通道数则从 64 逐层翻倍到 2048。
🧩 三种输出模式怎么选?
timm 提供了三种典型用法,按需切换即可:
| 使用场景 | 加载方式 | 前向输出 | 典型任务 |
|---|---|---|---|
| 特征骨干 | features_only=True |
5 张特征图 | 检测、分割 |
| 图像嵌入 | num_classes=0 |
(1, 2048) 向量 |
检索、相似度 |
| 图像分类 | 默认 | 1000 维 logits | 图像分类 |
如果只需单个特征向量做图像检索,也可以用等价写法:先 forward_features() 拿到未池化的 (1, 2048, 6, 6),再 forward_head(..., pre_logits=True) 完成池化,得到 2048 维向量(参考 README.md#L91-L121)。
⚙️ 数据预处理:归一化参数从哪里来?
timm 模型会自动解析数据配置,但了解底层参数有助于排查问题。本模型的预处理配置记录在 config.json 中:
- 均值 mean:
[0.485, 0.456, 0.406](标准 ImageNet 均值) - 标准差 std:
[0.229, 0.224, 0.225] - 插值方式:
bilinear - 是否固定输入尺寸:
false(即不强制 224,可按需调整)
fixed_input_size 为 false 意味着你可以喂入任意尺寸的图片,只是推荐保持 224 的倍数以获得最佳精度。
💡 常见问题 FAQ
Q1:预训练权重如何获取?
通过 pretrained=True 会自动下载;也可以直接使用本仓库内的本地权重文件 model.safetensors 或 pytorch_model.bin,通过 pretrained='./model.safetensors' 指定路径加载,避免重复下载。
Q2:为什么我的特征图尺寸和表里不一样?
特征图空间尺寸 = 输入尺寸 ÷ 下采样倍数。输入 224×224 时输出 88/44/22/11/6;输入 176×176(训练尺寸)时会按同比例缩小。
Q3:特征骨干可以微调吗?
可以。提取出 5 层特征图后,接上 FPN、检测头或分割解码器,对骨干部分做低学习率微调,是目标检测和语义分割的标准做法。
✅ 小结
- 用
features_only=True一行参数即可把 wide_resnet50_2.tv2_in1k 切换为特征骨干模式 - 前向输出 5 张特征图,空间分辨率 88→6,通道数 64→2048
- 预处理均值/标准差等配置可从 config.json 查看,
fixed_input_size=false支持可变输入尺寸 - 模型完整说明与示例代码见 README.md
掌握以上内容,你就能把这个 81.61% Top-1 的预训练模型变成自己检测、分割项目的"特征提取引擎"了 🎯