Ultralytics:解读DWConvTranspose2d模块

前言
- 由于本人水平有限,难免出现错漏,敬请批评改正。
- 更多精彩内容,可点击进入Python日常小操作专栏、OpenCV-Python小应用专栏、YOLO系列专栏、自然语言处理专栏、人工智能混合编程实践专栏或我的个人主页查看
- YOLOs-CPP:一个免费开源的YOLO全系列C++推理库(以YOLO26为例)
- PaddleOCR:Win10上安装使用PPOCRLabel标注工具
- 目标检测:使用自己的数据集微调DEIMv2进行物体检测
- 图像分割:PyTorch从零开始实现SegFormer语义分割
- 图像超分:使用自己的数据集微调Real-ESRGAN-x4plus进行超分重建
- 图像生成:PyTorch从零开始实现一个简单的扩散模型
- Stable Diffusion:使用自己的数据集微调 Stable Diffusion 3.5 LoRA 文生图模型
- 图像超分:使用自己的数据集微调Real-ESRGAN-x2plus进行超分重建
- Anomalib:使用Anomalib 2.1.0训练自己的数据集进行异常检测
- Anomalib:在Linux服务器上安装使用Anomalib 2.1.0
- 人工智能混合编程实践:C++调用封装好的DLL进行异常检测推理
- 人工智能混合编程实践:C++调用封装好的DLL进行FP16图像超分重建(v3.0)
- 隔离系统Python:源码编译3.11.8到自定义目录(含PGO性能优化)
- 在线机的Python环境迁移到离线机上
- Nuitka 将 Python 脚本封装为 .pyd 或 .so 文件
- Ultralytics:使用 YOLO11 进行速度估计
- Ultralytics:使用 YOLO11 进行物体追踪
- Ultralytics:使用 YOLO11 进行物体计数
- Ultralytics:使用 YOLO11 进行目标打码
- 人工智能混合编程实践:C++调用Python ONNX进行YOLOv8推理
- 人工智能混合编程实践:C++调用封装好的DLL进行YOLOv8实例分割
- 人工智能混合编程实践:C++调用Python ONNX进行图像超分重建
- 人工智能混合编程实践:C++调用Python AgentOCR进行文本识别
- 通过计算实例简单地理解PatchCore异常检测
- Python将YOLO格式实例分割数据集转换为COCO格式实例分割数据集
- YOLOv8 Ultralytics:使用Ultralytics框架训练RT-DETR实时目标检测模型
- 基于DETR的人脸伪装检测
- YOLOv7训练自己的数据集(口罩检测)
- YOLOv8训练自己的数据集(足球检测)
- YOLOv5:TensorRT加速YOLOv5模型推理
- YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
- 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
- YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
- YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
- Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
- YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
- 使用Kaggle GPU资源免费体验Stable Diffusion开源项目
- Stable Diffusion:在服务器上部署使用Stable Diffusion WebUI进行AI绘图(v2.0)
- Stable Diffusion:使用自己的数据集微调训练LoRA模型(v2.0)
相关介绍
Ultralytics 简介
Ultralytics 基于多年的计算机视觉和人工智能基础研究,创建了最先进的 (SOTA) YOLO 模型。我们的模型不断更新性能和灵活性,快速、准确且易于使用。他们擅长对象检测、跟踪、实例分割、语义分割、图像分类和姿势估计任务。
前提条件
- 熟悉Python、Pytorch
实验环境
Package Version
------------------------ ------------
Python 3.11.8
absl-py 2.4.0
accelerate 1.13.0
annotated-doc 0.0.4
anyio 4.13.0
calflops 0.3.2
certifi 2026.4.22
charset-normalizer 3.4.7
click 8.3.3
colorama 0.4.6
contourpy 1.3.3
cycler 0.12.1
filelock 3.29.0
flatbuffers 25.12.19
fonttools 4.62.1
fsspec 2026.4.0
grpcio 1.80.0
h11 0.16.0
hf-xet 1.5.0
httpcore 1.0.9
httpx 0.28.1
huggingface_hub 1.14.0
idna 3.15
Jinja2 3.1.6
kiwisolver 1.5.0
Markdown 3.10.2
markdown-it-py 4.2.0
MarkupSafe 3.0.3
matplotlib 3.10.9
mdurl 0.1.2
ml_dtypes 0.5.0
mpmath 1.3.0
networkx 3.6.1
numpy 1.26.4
nvidia-cublas-cu12 12.8.3.14
nvidia-cuda-cupti-cu12 12.8.57
nvidia-cuda-nvrtc-cu12 12.8.61
nvidia-cuda-runtime-cu12 12.8.57
nvidia-cudnn-cu12 9.7.1.26
nvidia-cufft-cu12 11.3.3.41
nvidia-cufile-cu12 1.13.0.11
nvidia-curand-cu12 10.3.9.55
nvidia-cusolver-cu12 11.7.2.55
nvidia-cusparse-cu12 12.5.7.53
nvidia-cusparselt-cu12 0.6.3
nvidia-nccl-cu12 2.26.2
nvidia-nvjitlink-cu12 12.8.61
nvidia-nvtx-cu12 12.8.55
onnx 1.19.0
onnxruntime-gpu 1.26.0
onnxslim 0.1.94
opencv-python 4.6.0.66
packaging 26.2
pillow 12.2.0
pip 24.0
polars 1.40.1
polars-runtime-32 1.40.1
protobuf 7.34.1
psutil 7.2.2
pycocotools 2.0.11
Pygments 2.20.0
pyparsing 3.3.2
python-dateutil 2.9.0.post0
PyYAML 6.0.3
regex 2026.5.9
requests 2.34.1
rich 15.0.0
safetensors 0.7.0
scipy 1.16.0
setuptools 65.5.0
shellingham 1.5.4
six 1.17.0
sympy 1.14.0
tabulate 0.10.0
tensorboard 2.20.0
tensorboard-data-server 0.7.2
tokenizers 0.22.2
torch 2.7.1+cu128
torchaudio 2.7.1+cu128
torchvision 0.22.1+cu128
tqdm 4.67.3
transformers 5.8.1
triton 3.3.1
typer 0.25.1
typing_extensions 4.15.0
ultralytics 8.4.58
ultralytics-thop 2.0.19
urllib3 2.7.0
Werkzeug 3.1.8
DWConvTranspose2d(深度可分离转置卷积)
DWConvTranspose2d 是对 nn.ConvTranspose2d 的简单封装,通过设置分组数 groups = gcd(c1, c2) 实现深度可分离的转置卷积(Depthwise Transpose Convolution)。它常用于生成模型(如 GAN、VAE)或语义分割中的上采样操作,可在扩大特征图尺寸的同时大幅降低参数量。
代码实现
import cv2
import math
import torch
import numpy as np
import matplotlib.pyplot as plt
from torch import nn
class DWConvTranspose2d(nn.ConvTranspose2d):
"""Depth-wise transpose convolution module."""
def __init__(self, c1, c2, k=1, s=1, p1=0, p2=0):
"""Initialize depth-wise transpose convolution with given parameters.
Args:
c1 (int): Number of input channels.
c2 (int): Number of output channels.
k (int): Kernel size.
s (int): Stride.
p1 (int): Padding.
p2 (int): Output padding.
"""
super().__init__(c1, c2, k, s, p1, p2, groups=math.gcd(c1, c2))
功能
- 深度可分离转置卷积:将标准转置卷积的分组数设为
gcd(c1, c2),使得每个输出通道仅与部分输入通道相关联,减少参数。 - 与普通转置卷积的参数量对比:
- 标准转置卷积: k 2 ⋅ c 1 ⋅ c 2 k^2 \cdot c_1 \cdot c_2 k2⋅c1⋅c2
- 深度转置卷积(当
g=c1且c2是c1的倍数): k 2 ⋅ c 1 k^2 \cdot c_1 k2⋅c1
- 输出尺寸变化:根据转置卷积的公式,输出尺寸 H o u t = ( H i n − 1 ) ⋅ s − 2 ⋅ p 1 + k + p 2 H_{out} = (H_{in}-1) \cdot s - 2 \cdot p_1 + k + p_2 Hout=(Hin−1)⋅s−2⋅p1+k+p2,宽度同理。
- 无 BN 与激活:与
Conv系列不同,该模块仅包含卷积操作,不附加批归一化和激活函数,使用者可根据需求自行添加。
初始化参数
| 参数 | 类型 | 说明 |
|---|---|---|
c1 | int | 输入通道数 |
c2 | int | 输出通道数 |
k | int | 卷积核大小(默认 1) |
s | int | 步长(默认 1) |
p1 | int | 填充(默认 0) |
p2 | int | 输出填充(默认 0) |
与
DWConv类似,分组数g = gcd(c1, c2),当c2是c1的整数倍时,g = c1,实现真正的深度卷积(每个输入通道独立生成输出通道)。
与标准转置卷积的区别
| 特性 | 标准转置卷积 (nn.ConvTranspose2d) | 深度转置卷积 (DWConvTranspose2d) |
|---|---|---|
分组数 g | 默认 1 | gcd(c1, c2)(通常为 c1) |
| 参数量 | k 2 ⋅ c 1 ⋅ c 2 k^2 \cdot c_1 \cdot c_2 k2⋅c1⋅c2 |
k
2
⋅
c
1
k^2 \cdot c_1
k2⋅c1(当 g=c1) |
| 计算量 | 较大 | 较小 |
| 通道混合 | 所有通道混合 | 仅分组内混合 |
使用示例

if __name__ == '__main__':
# 1. 读取图像
img_path = "cat_640x640.png"
img_bgr = cv2.imread(img_path)
if img_bgr is None:
raise FileNotFoundError(f"图片 {img_path} 不存在!")
# 2. 转为张量 (1,3,640,640)
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
img_tensor = torch.from_numpy(img_rgb).float().permute(2, 0, 1).unsqueeze(0)
# 3. 创建 DWConvTranspose2d 层:输入3通道,输出16通道,核3×3,步长2,填充1,输出填充0
# 步长2使尺寸翻倍(上采样),注意转置卷积的填充公式
dw_transpose = DWConvTranspose2d(c1=3, c2=16, k=3, s=2, p1=1, p2=0)
# 4. 前向传播
with torch.no_grad():
out = dw_transpose(img_tensor)
print("输出形状:", out.shape) # 计算:(640-1)*2 - 2*1 + 3 + 0 = 1278+3? 实际应为 1281? 需核对公式
# 重新计算:H_out = (H_in - 1)*s - 2*p1 + k + p2 = (640-1)*2 -2*1 +3 +0 = 1278 -2 +3 = 1279? 实际上公式是 (H_in-1)*s -2*p1 + k + p2,代入得 (640-1)*2 -2*1 +3 = 1278 -2 +3 = 1279? 但通常用 (H_in -1)*s - 2*p1 + dilation*(k-1) + 1 + p2,对于转置卷积,通常用 nn.ConvTranspose2d 的输出尺寸:H_out = (H_in - 1)*s - 2*padding + dilation*(kernel_size-1) + output_padding + 1。这里未给 dilation,默认为1。所以 H_out = (640-1)*2 -2*1 + 1*(3-1) + 0 + 1 = 1278 -2 +2 +1 = 1279? 再检查:标准公式:H_out = (H_in -1)*stride - 2*padding + dilation*(kernel_size-1) + output_padding + 1。所以 H_out = 639*2 -2 +2 +0 +1 = 1278 -2 +2 +1 = 1279? 实际上 1278-2=1276, +2=1278, +1=1279。但通常希望上采样2倍,即 640 -> 1280,这里得到1279,是因为填充选择导致不对称。若设置 p1=1, p2=1 可得到1280。为了演示,我们选择 p1=1, p2=1。
# 修改参数为 p1=1, p2=1 得到 (640-1)*2 -2 +2 +1 = 1280
# 下面重新创建
dw_transpose = DWConvTranspose2d(c1=3, c2=16, k=3, s=2, p1=1, p2=1)
with torch.no_grad():
out = dw_transpose(img_tensor)
print("输出形状 (调整后):", out.shape) # torch.Size([1, 16, 1280, 1280])
# 5. 可视化第一个通道(需下采样或裁剪以显示,因为尺寸变大)
feat_map = out[0, 0, :, :].cpu().numpy()
# 归一化到 0~255
feat_map = (feat_map - feat_map.min()) / (feat_map.max() - feat_map.min() + 1e-8)
feat_map = (feat_map * 255).astype(np.uint8)
# 为便于显示,将特征图缩放到与原始图像相近尺寸(或保持原样,但显示时可能太大)
# 这里我们直接显示(matplotlib会自动缩放)
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB))
plt.title("Original (640x640)")
plt.axis("off")
plt.subplot(1, 2, 2)
plt.imshow(feat_map, cmap='gray')
plt.title("DWConvTranspose2d (1280x1280, Ch0)")
plt.axis("off")
plt.tight_layout()
plt.savefig("dwconvtranspose_output.png", dpi=150)
# plt.show()
print("可视化已保存为 dwconvtranspose_output.png")

输出示例:
输出形状: torch.Size([1, 16, 1279, 1279])
输出形状 (调整后): torch.Size([1, 16, 1280, 1280])
可视化已保存为 dwconvtranspose_output.png
流程示意图

代码解读
__init__ 方法
- 直接调用父类
nn.ConvTranspose2d的构造函数,传入groups=math.gcd(c1, c2)。 - 父类会创建对应的转置卷积层,分组数被设置,实现深度分离效果。
与 DWConv 的异同
- 相同点:都使用
gcd作为分组数,目标都是减少参数。 - 不同点:
DWConv继承自Conv,包含 BN 和激活。DWConvTranspose2d继承自nn.ConvTranspose2d,无 BN 和激活,纯粹是一个卷积层。- 使用场景不同:前者用于特征提取(下采样/同尺寸),后者用于上采样。
转置卷积输出尺寸计算
给定输入尺寸
H
i
n
H_{in}
Hin,输出尺寸为:
H
o
u
t
=
(
H
i
n
−
1
)
⋅
s
−
2
⋅
p
1
+
k
+
p
2
H_{out} = (H_{in} - 1) \cdot s - 2 \cdot p_1 + k + p_2
Hout=(Hin−1)⋅s−2⋅p1+k+p2
其中
k
k
k 为核大小,
s
s
s 为步长,
p
1
p_1
p1 为填充,
p
2
p_2
p2 为输出填充。
本模块未引入膨胀(dilation=1),若有需要可扩展。
注意事项
- 无 BN 和激活:该模块仅做卷积,不附加归一化或非线性,使用时需在外部添加(如
nn.BatchNorm2d和nn.ReLU),否则网络可能难以训练。 - 参数选择技巧:
- 若希望输出尺寸为输入尺寸的
s倍(例如s=2实现 2× 上采样),通常设置p1 = k//2,p2 = k%2以保持对齐。 - 对于奇数核(如
k=3,s=2),推荐p1=1, p2=1得到H_out = 2*H_in(如 640 → 1280)。
- 若希望输出尺寸为输入尺寸的
- 分组数限制:
groups必须能同时整除c1和c2,gcd保证这一点,但当gcd=1时退化为标准转置卷积,节省效果消失。 - 与
ConvTranspose2d的兼容性:由于继承自nn.ConvTranspose2d,所有父类参数(如dilation,bias等)均可通过*args, **kwargs扩展,但本实现未暴露,需要修改源码。 - 适用场景:生成对抗网络(GAN)中的上采样层、语义分割的解码器、自编码器等。
优缺点
优点
-
参数量和计算量大幅减少
当g=c1时,参数量从 k 2 ⋅ c 1 ⋅ c 2 k^2 \cdot c_1 \cdot c_2 k2⋅c1⋅c2 降至 k 2 ⋅ c 1 k^2 \cdot c_1 k2⋅c1,节省了 c 2 c_2 c2 倍,适合轻量级上采样。 -
结构简单,易于使用
直接继承nn.ConvTranspose2d,无需额外封装,可无缝替换原有转置卷积。 -
内存友好
分组操作减少了中间计算量,降低显存占用,适合大尺寸输入。
缺点
-
表达能力受限
缺少通道间的混合(因分组),上采样后的特征图可能不够丰富,需配合后续 1×1 卷积增强。 -
无内置归一化与激活
使用者需手动添加 BN 和激活,增加了设计步骤,且若忘记添加可能影响训练收敛。 -
参数调整较复杂
转置卷积的填充、输出填充需要精确计算,否则尺寸不对齐,尤其当核大小和步长不匹配时,容易产生棋盘效应(checkerboard artifacts)。 -
硬件加速受限
分组转置卷积在部分深度学习框架中的实现可能不如标准转置卷积优化,尤其在 GPU 上性能提升不明显。
在 YOLOv8 中,转置卷积通常用于特征金字塔的上采样路径(如 nn.Upsample + 卷积),DWConvTranspose2d 可作为轻量替代,但需注意与 BN/激活的搭配以及尺寸对齐。
参考文献
[1] https://docs.ultralytics.com/
[2] https://github.com/ultralytics/ultralytics.git
- 由于本人水平有限,难免出现错漏,敬请批评改正。
- 更多精彩内容,可点击进入Python日常小操作专栏、OpenCV-Python小应用专栏、YOLO系列专栏、自然语言处理专栏、人工智能混合编程实践专栏或我的个人主页查看
- YOLOs-CPP:一个免费开源的YOLO全系列C++推理库(以YOLO26为例)
- PaddleOCR:Win10上安装使用PPOCRLabel标注工具
- 目标检测:使用自己的数据集微调DEIMv2进行物体检测
- 图像分割:PyTorch从零开始实现SegFormer语义分割
- 图像超分:使用自己的数据集微调Real-ESRGAN-x4plus进行超分重建
- 图像生成:PyTorch从零开始实现一个简单的扩散模型
- Stable Diffusion:使用自己的数据集微调 Stable Diffusion 3.5 LoRA 文生图模型
- 图像超分:使用自己的数据集微调Real-ESRGAN-x2plus进行超分重建
- Anomalib:使用Anomalib 2.1.0训练自己的数据集进行异常检测
- Anomalib:在Linux服务器上安装使用Anomalib 2.1.0
- 人工智能混合编程实践:C++调用封装好的DLL进行异常检测推理
- 人工智能混合编程实践:C++调用封装好的DLL进行FP16图像超分重建(v3.0)
- 隔离系统Python:源码编译3.11.8到自定义目录(含PGO性能优化)
- 在线机的Python环境迁移到离线机上
- Nuitka 将 Python 脚本封装为 .pyd 或 .so 文件
- Ultralytics:使用 YOLO11 进行速度估计
- Ultralytics:使用 YOLO11 进行物体追踪
- Ultralytics:使用 YOLO11 进行物体计数
- Ultralytics:使用 YOLO11 进行目标打码
- 人工智能混合编程实践:C++调用Python ONNX进行YOLOv8推理
- 人工智能混合编程实践:C++调用封装好的DLL进行YOLOv8实例分割
- 人工智能混合编程实践:C++调用Python ONNX进行图像超分重建
- 人工智能混合编程实践:C++调用Python AgentOCR进行文本识别
- 通过计算实例简单地理解PatchCore异常检测
- Python将YOLO格式实例分割数据集转换为COCO格式实例分割数据集
- YOLOv8 Ultralytics:使用Ultralytics框架训练RT-DETR实时目标检测模型
- 基于DETR的人脸伪装检测
- YOLOv7训练自己的数据集(口罩检测)
- YOLOv8训练自己的数据集(足球检测)
- YOLOv5:TensorRT加速YOLOv5模型推理
- YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
- 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
- YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
- YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
- Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
- YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
- 使用Kaggle GPU资源免费体验Stable Diffusion开源项目
- Stable Diffusion:在服务器上部署使用Stable Diffusion WebUI进行AI绘图(v2.0)
- Stable Diffusion:使用自己的数据集微调训练LoRA模型(v2.0)


3140

被折叠的 条评论
为什么被折叠?



