1、Inception Depthwise Convolution
大核深度可分离卷积效率低下,尽管大核深度可分离卷积的 FLOPs 较低,但其内存访问成本高,在强大计算设备上(如 GPU)成为瓶颈。同时,小核卷积无法有效扩大感受野, 减小卷积核尺寸可以提高速度,但会限制模型的感受野,导致性能下降。这篇论文提出一种 Inception深度卷积(Inception Depthwise Convolution),通过保留部分通道不变,仅对部分通道进行处理来达到更好的效果。
IDConv 受 Inception 思想启发,将大核深度可分离卷积分解为多个并行分支,包括:小方核分支、正交带核分支以及恒等映射分支: 保持部分通道不变,避免信息丢失。
对于输入X,IDConv 的实现过程:
- 输入通道分割: 将输入通道沿通道维度分割为四组,分别对应四个分支。
- 恒等映射分支: 直接输出。
- 小方核分支: 使用 3x3 深度可分离卷积进行特征提取。
- 正交带核分支: 分别使用 1xk 和 kx1 深度可分离卷积进行特征提取。
- 特征融合: 将四个分支的输出进行拼接,得到最终的特征图。
优势:
- 提高效率: Inception Depthwise Conv 避免了计算量大且效率低的大核深度可分离卷积,通过并行分支和部分通道处理,显著提高了模型效率。
- 扩大感受野: 通过正交带核分支,模型能够有效扩大感受野,从而获得更好的性能。
- 易于实现: Inception Depthwise Conv 结构简单,易于实现和部署。
Inception Depthwise Convolution 结构图:
2、代码实现
import math
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.nn.modules.utils import _triple
class InceptionDWConv2d(nn.Module):
""" Inception depthweise convolution
"""
def __init__(self, in_channels, square_kernel_size=3, band_kernel_size=11, branch_ratio=0.125):
super().__init__()
gc = int(in_channels * branch_ratio) # channel numbers of a convolution branch
self.dwconv_hw = nn.Conv2d(gc, gc, square_kernel_size, padding=square_kernel_size // 2, groups=gc)
self.dwconv_w = nn.Conv2d(gc, gc, kernel_size=(1, band_kernel_size), padding=(0, band_kernel_size // 2),
groups=gc)
self.dwconv_h = nn.Conv2d(gc, gc, kernel_size=(band_kernel_size, 1), padding=(band_kernel_size // 2, 0),
groups=gc)
self.split_indexes = (in_channels - 3 * gc, gc, gc, gc)
def forward(self, x):
x_id, x_hw, x_w, x_h = torch.split(x, self.split_indexes, dim=1)
return torch.cat(
(x_id, self.dwconv_hw(x_hw), self.dwconv_w(x_w), self.dwconv_h(x_h)),
dim=1,
)
if __name__ == '__main__':
x = torch.randn(2, 64, 128, 128)
model = InceptionDWConv2d(64)
output = model(x)
print(output.shape)