You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch中封装预训练DenseNet为nn.Sequential后输出张量异常如何解决

问题原因

你得到的[1, 1024, 7, 7]是DenseNet主干网络输出的特征图,属于正常现象,问题出在你提取模型结构的逻辑遗漏了原DenseNet的必要后处理步骤,和DenseNet的层间全连接特性无关:
原DenseNet的完整推理逻辑为:

  1. 经过features主干输出4维特征图
  2. 过ReLU激活
  3. 经过自适应全局平均池化压缩为[1, 1024, 1, 1]的张量
  4. 展平为[1, 1024]的一维特征向量
  5. 经过最后一层全连接层classifier输出[1, 1000]的分类结果
    你用list(base_model.children())[:-1]只提取了第一步的features主干,缺少后续的激活、池化、展平步骤,因此输出为4维特征图。
正确实现方案

方案1:单独提取特征提取器,输出1024维一维特征

适合需要拿到DenseNet输出的通用特征,后续接自定义逻辑的场景:

初始化代码

import torch
from torch import nn

base_model = torch.hub.load('pytorch/vision:v0.10.0', 'densenet121', pretrained=True)
# 可选:冻结主干参数,仅做特征提取不微调
for param in base_model.parameters():
    param.requires_grad = False

# 补齐缺失的后处理步骤
self.base_model = nn.Sequential(
    *list(base_model.children())[:-1],
    nn.ReLU(inplace=True),
    nn.AdaptiveAvgPool2d((1, 1)),
    nn.Flatten(start_dim=1)
)

前向调用

x = self.base_model(x)
# 输出尺寸为[1, 1024],符合特征向量预期

方案2:直接替换最后一层分类头

适合基于预训练DenseNet做自定义分类任务的场景,写法更简洁:

初始化代码

base_model = torch.hub.load('pytorch/vision:v0.10.0', 'densenet121', pretrained=True)
# 可选:冻结主干参数,仅微调分类头
for param in base_model.parameters():
    param.requires_grad = False

# 替换原1000类的分类头为自定义类别数,示例为10分类
in_features = base_model.classifier.in_features
base_model.classifier = nn.Linear(in_features, 10)
self.base_model = base_model

前向调用

x = self.base_model(x)
# 输出尺寸为[1, 10],符合自定义分类预期
注意事项

你提到的输入尺寸[1,3,244,244]属于常见笔误,官方预训练权重基于224x224输入训练,建议使用224x224的输入以获得最优精度;若使用其他尺寸输入,自适应平均池化层会自动适配,最终输出的特征向量维度仍为1024,不会影响后续逻辑。

内容的提问来源于stack exchange,提问作者itisyeetimetoday

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 14:06:03