论文地址: [2303.03667] Run, Don’t Walk: Chasing Higher FLOPS for Faster Neural Networks (arxiv.org)
项目地址: github.com/JierunChen/…
关键词: PConv、 FasterNet
前言
CVPR是核算机视觉领域的尖端国际会议之一,每年都吸引了来自全球各地的学者和从业人员参与,2023年的CVPR也不破例。在本文中为咱们介绍本年新出炉的网络——Backbone FasterNet。
在这里咱们想要知道更具体的关于论文的内容,咱们可以点击上方的论文链接,翻阅原文查看。博主在这里从尝试实操给咱们带来Backbone FasterNet。
导读
在FasterNet中处理的核心问题是低FLOPS运算的高频次拜访带来的延迟,为了处理这个痛点,论文作者们提出了一种新的卷积结构:partial convolution(PConv)。该卷积经过削减冗余核算和内存拜访可以更有用的提取空间特征。根据PConv进一步提出FasterNet。
Pconv算子
Pconv它只对几个输入通道应用滤波器,而不影响其他的输入通道。PConv比惯例卷积取得更低的FLOPs,而比深度/组卷积取得更高的FLOPs。PConv的FLOPs比惯例Conv低,而比DWConv/GConv有更高的FLOPs。换句话说,PConv更好地利用了设备上的核算才能。PConv在提取空间特征方面也很有用。
贡献如下:
- 咱们指出完成更高的FLOPS的重要性,而不仅仅是为了更快的神经网络而简略地下降FLOPS。
- 咱们介绍了一个简略而快速且有用的运算符PConv,它有很大的潜力替代现有的首选DWConv。
- 咱们介绍了fastnet,它在各种设备(如GPU、CPU和ARM处理器)上运转杰出且一致快速。
- 咱们对各种任务进行了广泛的实验,并验证了咱们的PConv和FasterNet的高速和有用性。
import torch
import torch.nn as nn
from torch import Tensor
class PConv(nn.Module):
"""
Partial convolution (PConv).
"""
def __init__(self, dim: int, n_div: int, forward: str = "split_cat", kernel_size: int = 3) -> None:
"""
Construct a PConv layer.
:param dim: Number of input/output channels
:param n_div: Reciprocal of the partial ratio.
:param forward: Forward type, can be either ’split_cat’ or ’slicing’.
:param kernel_size: Kernel size.
"""
super().__init__()
self.dim_conv = dim // n_div
self.dim_untouched = dim - self.dim_conv
self.conv = nn.Conv2d(
self.dim_conv,
self.dim_conv,
kernel_size,
stride=1,
padding=(kernel_size - 1) // 2,
bias=False
)
if forward == "slicing":
self.forward = self.forward_slicing
elif forward == "split_cat":
self.forward = self.forward_split_cat
else:
raise NotImplementedError
def forward_slicing(self, x: Tensor) -> Tensor:
""" Apply forward pass for inference. """
x[:, :self.dim_conv, :, :] = self.conv(x[:, :self.dim_conv, :, :])
return x
def forward_split_cat(self, x: Tensor) -> Tensor:
""" Apply forward pass for training. """
x1, x2 = torch.split(x, [self.dim_conv, self.dim_untouched], dim=1)
x1 = self.conv(x1)
x = torch.cat((x1, x2), 1)
return x
FasterNet Block
PWConv的基本思想是在每个像素点上分别进行卷积核算,然后完成卷积操作。相对于传统的卷积操作,PWConv具有核算效率高和模型参数较少等优势,其主要优势在于它可以用较少的参数完成模型的有用表达,然后削减模型核算量和内存耗费。此外,PWConv还可以用于完成多通道特征的通道关系转换和紧缩。
由下图所示的fasterNet Block(下述简称FNB)图,咱们可以得到主要组成的结构是PConv conv_1x1、BN、Relu组合而成。在本文中上面已经得到了PConv层,剩余的便是组件FNB层了。
import torch
import torch.nn as nn
from torch import Tensor
def Conv1x1(nin, nf, stride=1):
return nn.Sequential(
nn.Conv2d(nin, nf, 3, stride, 1, bias=False),
nn.BatchNorm2d(nf),
nn.ReLU(inplace=True)
)
class PConv(nn.Module):
pass
class FasterNetBlock(nn.Module):
def __init__(self, inp: int, outp: int, dim: int, n_div: int, forward: str = "split_cat", kernel_size: int = 3) -> None:
super().__init__()
self.pconv = PConv(dim=dim, n_div=n_div, forward=forward, kernel_size=kernel_size)
self.conv1_1 = Conv1x1(inp, outp)
self.bn = nn.BatchNorm2d(outp)
self.relu = nn.ReLU(inplace=True)
def forward(self, x):
x = self.pconv(x)
x = self.conv1_1(x)
x = self.bn(x)
x = self.relu(x)
x = self.conv_1x1(x)
return x
本文正在参与「金石计划」