论文:https://arxiv.org/pdf/1908.03930v1.pdf

代码:https://github.com/ShawnDing1994/ACN

通过非对称卷积块增强CNN的核骨架

  • 摘要
  • 1.研究背景
  • 2. 相关工作
    • 2.1 非对称卷积
    • 2.2 CNN架构中的中性结构
  • 3. 方法
    • 3.1 公式
    • 3.2 利用卷积的可加性
    • 3.3 ACB不增加任何推理时间开销
  • 4. 实验
    • 4.1 在CIFAR上的性能改进
    • 4.2 在ImageNet上的性能改进
    • 4.3 消融研究
    • 4.4 ACB增强方形核的骨架
  • 5. 结论
  • ACBlock
  • Demo

下面要介绍的论文发于ICCV2019,题为「ACNet:Strengthening the Kernel Skeletons for Powerful CNN via Asymmetric ConvolutionBlocks」

摘要

由于在给定的应用环境中,设计合适的卷积神经网络(CNN)结构,需要大量人工的工作或大量的GPU资源消耗,研究界正在寻找网络结构无关的CNN结构,这种结构可以很容易地插入到多个成熟的体系结构中,以提高我们实际应用程序的性能。我们提出了非对称卷积块(ACB)作为CNN的构造块,它使用一维非对称卷积核来增强方形卷积核,我们用ACBs代替标准的方形卷积核来构造一个非对称卷积网络ACNet,该网络可以训练到更高的精度。训练后,我们等价地将ACNet转换为相同的原始架构,因此将不需要额外的计算。实验证明,ACNet可以在CIFARImageNet上显著提高各种经典模型的性能。

1.研究背景

卷积神经网络在视觉理解方面取得了巨大的成功,这使得其可以应用在安全系统、移动电话、汽车等各种应用中。由于前端设备通常受限于计算资源,就要求网络在保证精度的条件下要尽可能轻量。另一方面,随着CNN架构设计的相关研究增多,模型的性能得到了显著改善,但当现有的模型不能满足我们的特定需求时,要定制一种新的架构需要花费极高的成本。最近,研究者们正在寻求与架构无关的新型CNN结构,例如SE块和准六边形内核,它们可以直接和各种网络结构结合使用,以提高它们的性能。最近对CNN结构的研究主要集中在以下两个方面:

1)层之间是如何相互连接的,例如简单的堆叠在一起、恒等映射、密集连接等;

2)如何组合不同层的输出以提高学习表示的质量;

本文提出了非对称卷积块(ACB),它是用三个并行的d×d,1×d,d×1d\times d,1\times d,d\times 1d×d,1×d,d×1核来代替原始的 d×dd\times dd×d 核,如图Figure1所示:


给定一个网络,我们通过将每个方形卷积核替换为ACB模块,并训练网络到收敛。之后我们将每个ACB中非对称核的权值加到方形核的对应位置,将ACNet转换为和原始网络等效的结构。ACNet可以提高基准模型的性能,在CIFAR和ImageNet上优势明显。更好的是,ACNet引入了0参数,因此无需仔细调参就能将其与不同的CNN结构结合起来,并且易于在主流CNN框架上实现,以及不需要额外的推理时间开销。

2. 相关工作

2.1 非对称卷积

非对称卷积通常用于逼近现有的正方形卷积以进行模型压缩和加速,先前的一些工作表明,可以将标准的 d×dd \times dd×d 卷积分解为 1×d1 \times d1×d 和 d×1d \times 1d×1 卷积,以减少参数量。其背后的理论相当简单:如果二维卷积核的秩为1,则运算可等价地转换为一系列一维卷积。然而,由于深度网络中下学习到的核具有分布特征值,其内在秩比实际中的高,因此直接将变换应用于核会导致显著的信息损失。Denton等人基于SVD分解找到一个低秩逼近,然后对上层进行精细化以恢复性能。Jaderberg等人通过最小化重构误差,成功学习了水平核和垂直核。Jin等人应用结构约束使二维卷积可分离,在获得相当精度的条件下时间加速了2倍。另一方面,非对称卷积也被广泛的用来做网络结构设计,例如Inception-v3中,7*7卷积被1*7卷积和7*1卷积代替。语义分割ENet网络也采用这种方法来设计高效的语义分割网络,虽然精度略有下降,但降低了33%的参数量。

2.2 CNN架构中的中性结构

我们不打算修改CNN架构,而是使用一些与架构无关的结构来增强现有的模型。因此,我们的方法对任何网络都是有效的。例如,SE块可以附加到卷积层后,使用学习到的权重重新缩放特征图通道数,从而在合理的附加参数量和计算代价下显著提高精度。作为另一个示例,可以将辅助分类器插入模型中以帮助监督学习过程,这确实可以提高性能,但是需要额外的人为调整超参数。相比之下,ACNet在训练中不会引入任何超参数,并且在推理过程中不需要额外的参数和计算。因此,在实际应用中,开发人员可以使用ACNet来增强各种模型,而无需进行详细的参数调整,并且最终用户可以享受性能提升而又不会减慢推理速度。

3. 方法

3.1 公式

对于一个尺寸为 H×WH \times WH×W 通道数为D的卷积核,以通道数为C的特征图作为输入,我们使用 F∈RH×W×CF \in R^{H\times W\times C}F∈RH×W×C 表示卷积核, M∈RU×V×CM \in R^{U\times V\times C}M∈RU×V×C 表示输入,这是一个尺寸为UxV通道数为C的特征图, O∈RR×T×DO\in R^{R\times T\times D}O∈RR×T×D代表输出特征图。对于这个层的第j个卷积核,相应的输出特征映射通道是:


其中*是二维卷积算子。M:,:,kM_{:,:,k}M:,:,k​是M的第k个通道的尺寸为UxV的特征图,F:,:,k(i)F_{:,:,k}^{(i)}F:,:,k(i)​ 代表 F(j)F^{(j)}F(j) 的第k个通道的尺寸为HxW的特征图。在现代CNN体系结构中,批量归一化(BN)被广泛使用,以减少过度拟合,加快训练过程。通常情况下,批量归一化层之后通常会接一个线性变化,以增强表示能力。和公式1相比,输入变成:


其中,μj\mu_jμj​和σj\sigma_jσj​是批标准化的通道平均值和标准差,γj\gamma_jγj​和βj\beta_jβj​是缩放系数和偏移量。

3.2 利用卷积的可加性

我们试图以不对称卷积可以等效地融合到标准方形核层中的方式来使用,这样就不会引入额外的推理时间计算负担。我们注意到卷积的一个有用性质:如果几个大小兼容的二维核在相同的输入上以相同的步幅操作以产生相同分辨率的输出,并且它们的输出被求和,我们可以将这些核在相应的位置相加,从而得到一个产生相同输出的等效核。也就是说,二维卷积的可加性可以成立,即使核大小不同。


其中 III 是一个矩阵,K(1)K^{(1)}K(1) 和 K(2)K^{(2)}K(2) 是具有兼容尺寸的两个2D核,

是在对应位置的求和操作。注意 III 可能会被裁剪或者执行Padding操作。这里,“兼容”意味着我们可以把较小的内核“修补”到较大的内核上。在形式下,p层和q的下面这种转换是可行的:


例如,3x1和1x3是和3x3兼容的。通过研究滑动窗口形式的卷积计算,可以很容易地验证这一点,如图Figure2所示:


对于一个特定的卷积核F(j)F^{(j)}F(j),一个指定的点y,则输出 O:,:,jO_{:,:,j}O:,:,j​ 可以使用下式计算:


其中,X是输入M上相应的滑动窗口。显然,当我们将两个滤波器产生的输出通道相加时,如果一个通道上的每个y,其在另一个通道上的对应点共享相同的滑动窗口,则其相加性质(等式3)成立。

3.3 ACB不增加任何推理时间开销

在本文中,我们关注3x3卷积,这在现代CNN体系结构中大量使用。在给定的体系结构下,我们通过简单地将每个3x3卷积层替换为ACB来构建ACNet,该ACB模块包含三个并行层,内核大小分别为3x31x3,和3x1。和标准CNN的常规做法类似,在三层中的每一层之后都进行批量归一化,这被成为分子,并将三个分支的输出综合作为ACB的输出。请注意,我们可以使用与原始模型相同的配置来训练ACNet,而无需调整任何额外的超参数。如4.1和4.2节中所示,我们可以训练ACNet达到更高的精度。训练完成后,我们尝试将每个ACB转换为产生相同输出的标准卷积层这样,与经过常规训练的对等方相比,我们可以获得不需要任何额外计算的功能更强大的网络。该转换通过两个步骤完成,即BN融合和分支融合。

BN融合 卷积的同质性使得后续的BN和线性变换可以等价的融合到具有附加偏置的卷积层中。从公式2可以看出,对于每个分支,如果我们构造一个新的内核 γjσjF(j){{\gamma_j}\over{\sigma_j}}F^{(j)}σj​γj​​F(j)

然后加上偏置 −μjγjσj+βj-{{\mu_j\gamma_j}\over{\sigma_j}}+\beta_j−σj​μj​γj​​+βj​ ,我们可以产生相同的输出。

分支融合 我们通过在平方核的相应位置加入非对称核,将三个BN融合分支合并成标准卷积层。在实际应用中,这种转换是通过建立一个原始结构的网络并使用融合的权值进行初始化来实现的,这样我们就可以在与原始结构相同的计算预算下产生与ACNet相同的输出。更正式地,对于第j个卷积核, F′(j)F^{'(j)}F′(j) 表示融合后的卷积核, bjb_jbj​ 代表偏置, Fˉ(j)\bar F^{(j)}Fˉ(j) 和 F^(j)\hat F^{(j)}F^(j) 分别代表1x3和3x1卷积核的输出,融合后的结果可以表示为:


然后我们可以很容易地验证对于任意滤波器j,

其中, O:,:,j,Oˉ:,:,j,O^:,:,jO_{:,:,j},\bar O_{:,:,j},\hat O_{:,:,j}O:,:,j​,Oˉ:,:,j​,O^:,:,j​ 代表原始 3×3,1×3,3×13\times 3,1\times 3,3\times 13×3,1×3,3×1 三个分支的输出。Figure3展示了这个过程。


值得注意的是,尽管可以将ACB等价地转换为标准层,但是等效值仅在推理时才成立,因为训练动态是不同的,从而导致不同的性能。训练过程的不等价性是由于内核权重的随机初始化,以及由它们参与的不同计算流得出的梯度。

4. 实验

我们进行了大量的实验来验证ACNet在一系列数据集和架构上提高CNN性能的有效性。具体地说,我们选择一个现成的体系结构作为基线,构建一个ACNet的对等物,从头开始培训它,将它转换为与基线相同的结构,并测试它以收集准确性。对于可比性,所有的模型都经过训练直到完全收敛,并且每一对基线和ACNet使用相同的配置,例如,学习速率计划和批大小。

4.1节和4.2节,论文在CIFAR10和CIFAR100数据集,ImageNet数据集进行对比测试,结果如Table1,Table2,Table3所示。

4.3 节还展示了消融研究,也就是对AlexNet和ResNet在ImageNet图像上进行测试,采用控制变量法控制ACB的三个关键影响因素,同时对比了将图片旋转的测试效果,最终使用了ACB模块全部技巧的网络模型获得了几乎所有测试情况的新SOTA结果,证明了ACB模块能够增加对数据旋转的适应能力。

4.4 节用以说明ACB增强了方形卷积核的骨架信息。论文在训练过程中通过随机丢弃网络中3*3卷积核的骨架权重和边角权重,所谓骨架权重和边角权重的定义如Figure 4所示,骨架权重就是和中间位置直接相连的4个位置加上自身,剩下的就是边角部分了。

4.1 在CIFAR上的性能改进

为了对我们的方法在各种CNN架构上进行初步的评价,我们在CIFAR-10和CIFAR-100上对几个有代表性的基准模型Cifar-quick、VGG16、ResNet-56、WRN-16-8和DenseNet-40进行了实验。

对于Cifar-quick、VGG-16、ResNet-56和DenseNet-40,我们按照惯例使用0.1、0.01、0.001和0.0001的阶梯学习率训练模型。对于WRN-16-8,我们遵循原始论文[35]中报告的训练配置。我们使用了所采用的数据增强技术,即填充到40 40,随机裁剪和左右翻转。

从表1和表2中可以看出,所有模型的性能都有明显的提升,这表明ACBs的好处可以与各种架构相结合。

4.2 在ImageNet上的性能改进

然后,通过在ImageNet上的一系列实验,我们继续在真实世界的应用程序上验证我们的方法的有效性,这些实验包括来自1000个类的128万张用于训练的图像和50K用于验证的图像。我们分别用AlexNet、ResNet-18和DenseNet-121作为plain-style、residual和dense - connected架构的代表。每个模型以256个批处理规模进行150个epoch的训练,这比通常采用的基准(如90 epoch)要长,因此精度的提高不能简单归结为基础模型的不完全收敛。对于数据的增强,我们采用标准的管道,包括包围框扭曲,左右翻转和颜色移动,作为一个常见的实践。特别是我们使用的AlexNet的普通版本来自Tensorflow GitHub,它由五个堆叠的卷积层和三个完全连接的层组成,没有本地响应归一化(LRN),也没有跨gpu连接。值得注意的是,由于AlexNet的前两层分别使用了11 × 11和5 × 5核,因此可以扩展ACBs使其具有更大的非对称核。但是对于这两层我们仍然只使用1× 3和3 × 1的卷积,因为这样大规模的卷积在现代CNN中越来越不受欢迎,使得大型的ACBs不那么有用。

如表3所示,单作物Top-1精度AlexNet、ResNet-18和DenseNet-121提升1.52%,分别为0.78%和1.18%。在实践中,针对相同的精度目标,我们可以使用ACNet来增强一个更高效的模型,以更少的推理时间、能量消耗和存储空间来实现目标。另一方面,在计算预算或模型大小相同的限制下,我们可以使用ACNet以明显的优势提高精度,从而从终端用户的角度来看,所获得的性能可以被视为免费的利益。

4.3 消融研究

虽然我们有经验证明ACNet的有效性,但我们仍然希望找到一些解释。在本节中,我们试图通过一系列消融研究来研究ACNet。具体来说,我们关注以下三个设计决策:1)水平核,2)垂直核,3)每个分支中的批处理规范化。为了具有可比性,我们使用相同的训练配置,在ImageNet上用不同的消融来训练几个AlexNet和ResNet-18模型。值得注意的是,如果去掉分支中的批归一化,我们将对整个ACB的输出进行批归一化,即批归一化层的位置由预求和变为后求和。


从表4可以看出,去掉这三种设计中的任何一种都会降低模型的质量。然而,尽管水平和垂直的卷积都可以提高性能,由于在实践中水平方向和垂直方向的处理不平等,可能会存在一些差异,例如:我们通常执行随机的左右翻转,而不是上下翻转图像来增强训练数据。因此,如果在模型中输入一幅倒置的图像,原始的3 × 3层应该产生无意义的结果,这是自然的,但是水平核将在轴对称位置产生与原始图像相同的输出(图4),部分ACB仍能提取出正确的特征。考虑到这一点,我们假设ACBs可以增强模型对旋转畸变的鲁棒性,使模型能够更好地泛化未见数据。


然后,我们用整个验证集的旋转扭曲图像测试之前训练的模型,包括逆时针90◦旋转,180◦旋转,和上下翻转。当然,每个模型的精度都显著降低,但水平核模型在180度旋转和上下翻转图像上提供了明显更高的精度。例如,ResNet-18在水平方向上的精度略低于在垂直方向上的精度,但在180度方向上的精度要高0.75%。与基础模型相比,其在原/ 180度翻转图像上的精度分别提高了0.34% / 1.27%。可以预见,模型发挥类似的性能在180度旋转和上下翻转输入,因为180度旋转+左右翻转等价于上下翻转,由于数据增强方法,模型对左右翻转具有鲁棒性。

总之,我们已经证明,acb,特别是内部的水平核,可以增强模型的鲁棒性,以可观的边际旋转畸变。虽然这可能不是ACNet有效的主要原因,但我们认为它有希望激发对转动不变性问题的进一步研究。

4.4 ACB增强方形核的骨架

直观地看,当向平方内核添加水平和垂直内核时,可以将其视为显式增强骨架部分的方法,我们试图通过研究骨骼和角落重量之间的差异来解释ACNet的有效性。

受CNN剪枝的启发,我们首先在不同的空间位置删除一些权值,然后在CIFAR-10上使用ResNet56观察性能下降。具体地,我们在核中随机设置一些单独的权值为零,并对模型进行检验。如图5a所示,标注为转角的曲线,我们从每个角的四个角中随机选择权重
为获得给定的每个卷积层的全局稀疏度比,将它们设为0。注意,4/9 = 44.4%,44%的稀疏比意味着去掉四个角的大部分权值。对于骨架,我们只从每个核的骨架中随机选择权值。对于全局,内核中的每个权重都有平等的被选择的机会。实验采用不同的随机种子重复5次,并绘制了mean±std曲线。


然后,画出不同丢弃比例下的测试集准确率图,如Figure5所示:


通过对比图Figure5(a)和Figure5(b)发现,丢弃骨架部分的权重会降低准确率,而丢弃边角部分的权重却能获得更好的精度。然后,我们通过研究卷积核的数值来研究上叙述现象发生的原因。我们使用幅度(即绝对值)作为衡量参数重要性的指标,许多先前的CNN加速工作都采用了该指标。具体来说,我们将一个卷积层中所有融合的2D卷积核都加起来,通过最大值进行逐层归一化,最后获得所有层的归一化核的平均值。更正式地,我们让 F(i,j)F^{(i,j)}F(i,j) 表示第i个3x3卷积层的第j个核,L代表3x3卷积层的个数,maxabs代表逐像素的求最大值和取绝对值操作,所以平均核矩阵可以计算为:


其中,

我们在Figure 4(a)和Figure 4(b)上给出了经过正常训练的ResNet56和融合了ACNet的A值。某个网格的数值和颜色表示该参数在所有位置上平均重要性。从Figure5(a)看出正常训练的ResNet56参数分布是不平衡的,即中心点的A值最大,而四个角点的A值最小。Figure5(b)显示ACNet加剧了这种不平衡,因为四个角点的A值减小到了0.4以下,并且骨架中心点的A值为1.0,这意味着该位置在每个3*3层中始终占据主导地位。值得注意的是,方向,水平,垂直核的相应位置上的权重可能会在符号上相反,因此它们将它们相加可能会产生更大或者更小的幅度。但我们观察到一个一致的现象,即模型学会了在每一层增强骨骼部位的权重。我们继续研究如果将非对称核加到其他位置而不是中心骨架时模型的行为。具体来说,我们使用和以前相同的训练配置来训练Resnet56的ACNet对应网络,但是将水平卷积核向下平移一个像素,垂直卷积核向右平移一个像素。因此,在分支融合时,我们得到Figure 4©的结果。我们观察到, 这样的ACB网络还可以增强边界,但是强度不如常规ACB对骨骼的增强。该模型的准确度为94.67%,比常规的ACNet低0.42%(Table1)。此外我们对模型融合进行了类似的消融实验,可以看到丢弃边角部分的参数仍然获得了最高的精度,丢弃增强的右下角边界不会比丢弃左上角2*2方形的权重得到更好的结果。

总结一下

1)3*3卷积核的骨架部分比边角部分更加重要;
2)ACB可以增强卷积核的骨架部分,从而提高性能;
3)和常规的ACB相比,将水平和垂直核添加到边界会降低模型的性能;
4)这样做也可以增加边界的重要性,但是不能削弱其它部分的重要性。

因此,我们将ACNet的有效性部分归因于它进一步增强卷积核骨架的能力。

5. 结论

为了提高各种CNN架构的性能,我们提出了非对称卷积块(ACB),该算法将三个分别具有正方形,水平和垂直核的卷积分支的输出求和。我们通过使用ACB替换成熟体系结构中的方形核卷积层来构建非对称卷积网络(ACNet),并在训练后将其转换为原始网络结构。在CIFAR和ImageNet数据集上,通过在经典网络上使用ACNet评估我们的性能,取得了SOTA结果。我们已经表明,ACNet可以以可观察的幅度增强模型对旋转失真的鲁棒性,并显著增强方形卷积核的骨骼部分。并且ACNet也易于使用主流框架实现,方便研究者follow这项工作。

ACBlock

import torch.nn as nn
import torch.nn.init as init
from custom_layers.crop_layer import CropLayerclass ACBlock(nn.Module):def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1,padding_mode='zeros', deploy=False,use_affine=True, reduce_gamma=False, use_last_bn=False, gamma_init=None):super(ACBlock, self).__init__()self.deploy = deployif deploy:self.fused_conv = nn.Conv2d(in_channels=in_channels, out_channels=out_channels,kernel_size=(kernel_size, kernel_size), stride=stride,padding=padding, dilation=dilation, groups=groups, bias=True,padding_mode=padding_mode)else:self.square_conv = nn.Conv2d(in_channels=in_channels, out_channels=out_channels,kernel_size=(kernel_size, kernel_size), stride=stride,padding=padding, dilation=dilation, groups=groups, bias=False,padding_mode=padding_mode)self.square_bn = nn.BatchNorm2d(num_features=out_channels, affine=use_affine)center_offset_from_origin_border = padding - kernel_size // 2ver_pad_or_crop = (padding, center_offset_from_origin_border)hor_pad_or_crop = (center_offset_from_origin_border, padding)if center_offset_from_origin_border >= 0:self.ver_conv_crop_layer = nn.Identity()ver_conv_padding = ver_pad_or_cropself.hor_conv_crop_layer = nn.Identity()hor_conv_padding = hor_pad_or_cropelse:self.ver_conv_crop_layer = CropLayer(crop_set=ver_pad_or_crop)ver_conv_padding = (0, 0)self.hor_conv_crop_layer = CropLayer(crop_set=hor_pad_or_crop)hor_conv_padding = (0, 0)self.ver_conv = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=(kernel_size, 1),stride=stride,padding=ver_conv_padding, dilation=dilation, groups=groups, bias=False,padding_mode=padding_mode)self.hor_conv = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=(1, kernel_size),stride=stride,padding=hor_conv_padding, dilation=dilation, groups=groups, bias=False,padding_mode=padding_mode)self.ver_bn = nn.BatchNorm2d(num_features=out_channels, affine=use_affine)self.hor_bn = nn.BatchNorm2d(num_features=out_channels, affine=use_affine)if reduce_gamma:assert not use_last_bnself.init_gamma(1.0 / 3)if use_last_bn:assert not reduce_gammaself.last_bn = nn.BatchNorm2d(num_features=out_channels, affine=True)if gamma_init is not None:assert not reduce_gammaself.init_gamma(gamma_init)def init_gamma(self, gamma_value):init.constant_(self.square_bn.weight, gamma_value)init.constant_(self.ver_bn.weight, gamma_value)init.constant_(self.hor_bn.weight, gamma_value)def single_init(self):init.constant_(self.square_bn.weight, 1.0)init.constant_(self.ver_bn.weight, 0.0)init.constant_(self.hor_bn.weight, 0.0)def forward(self, input):if self.deploy:return self.fused_conv(input)else:square_outputs = self.square_conv(input)square_outputs = self.square_bn(square_outputs)vertical_outputs = self.ver_conv_crop_layer(input)vertical_outputs = self.ver_conv(vertical_outputs)vertical_outputs = self.ver_bn(vertical_outputs)horizontal_outputs = self.hor_conv_crop_layer(input)horizontal_outputs = self.hor_conv(horizontal_outputs)horizontal_outputs = self.hor_bn(horizontal_outputs)result = square_outputs + vertical_outputs + horizontal_outputsif hasattr(self, 'last_bn'):return self.last_bn(result)return resultclass CropLayer(nn.Module):#   E.g., (-1, 0) means this layer should crop the first and last rows of the feature map. And (0, -1) crops the first and last columnsdef __init__(self, crop_set):super(CropLayer, self).__init__()self.rows_to_crop = - crop_set[0]self.cols_to_crop = - crop_set[1]assert self.rows_to_crop >= 0assert self.cols_to_crop >= 0def forward(self, input):if self.rows_to_crop == 0 and self.cols_to_crop == 0:return inputelif self.rows_to_crop > 0 and self.cols_to_crop == 0:return input[:, :, self.rows_to_crop:-self.rows_to_crop, :]elif self.rows_to_crop == 0 and self.cols_to_crop > 0:return input[:, :, :, self.cols_to_crop:-self.cols_to_crop]else:return input[:, :, self.rows_to_crop:-self.rows_to_crop, self.cols_to_crop:-self.cols_to_crop]

Demo

这个Demo非常简单,在一张256*256的灰度图像上,分别做卷积核为(3,3)的运算,以及先进行卷积核为(1,3)的运算、然后进行卷积核为(3,1)的运算,比较二者的差异。

  • 项目结构
  • 主要代码
import cv2
import torch.nn as nn
from torch.utils.data import DataLoader
from torchvision import datasets, transformsdef image_show(title, image):cv2.imshow(title, image)cv2.waitKey(0)transform = transforms.Compose([transforms.ToTensor(),transforms.Resize(256),transforms.Grayscale()
])images_dataset = datasets.ImageFolder(root='./data/', transform=transform)
images_loader = DataLoader(dataset=images_dataset, batch_size=1, shuffle=False, num_workers=0)print(len(images_dataset))  # 3
print(images_dataset.class_to_idx)  # {'images': 0}class Model3x3(nn.Module):def __init__(self):super(Model3x3, self).__init__()self.conv3x3 = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=(3, 3))def forward(self, x):x = self.conv3x3(x)return xclass Model3x1and1x3(nn.Module):def __init__(self):super(Model3x1and1x3, self).__init__()self.conv3x1 = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=(1, 3))self.conv1x3 = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=(3, 1))def forward(self, x):x = self.conv3x1(x)x = self.conv1x3(x)return xmodel3x3 = Model3x3()
model3x1and1x3 = Model3x1and1x3()for data in images_loader:images, labels = dataprint(images.shape)  # torch.Size([1, 1, 256, 256])outputs3x3 = model3x3(images)print(outputs3x3.shape)  # torch.Size([1, 1, 254, 254])outputs3x3 = outputs3x3.detach().numpy()print(outputs3x3.shape)  # (1, 1, 254, 254)output3x3 = outputs3x3[0]print(output3x3.shape)  # (1, 254, 254)image_show('output3x3.jpg', output3x3[0])outputs3x1and1x3 = model3x1and1x3(images)print(outputs3x1and1x3.shape)  # torch.Size([1, 1, 254, 254])outputs3x1and1x3 = outputs3x1and1x3.detach().numpy()print(outputs3x1and1x3.shape)  # (1, 1, 254, 254)output3x1and1x3 = outputs3x3[0]print(output3x1and1x3.shape)  # (1, 254, 254)image_show('output3x1and1x3.jpg', output3x1and1x3[0])diff = outputs3x3[0] - outputs3x1and1x3[0]print(diff)
  • 实验结果

【ICCV-2019】ACNet:通过非对称卷积块增强CNN的核骨架 3*3卷积==>1*3卷积+3*1卷积=白给的精度提升相关推荐

  1. 3*3卷积+1*3卷积+3*1卷积=白给的精度提升

    2019-11-28 04:33:41 作者 | BBuf 编辑 | 唐里 ICCV2019: 通过非对称卷积块增强CNN的核骨架 下面要介绍的论文发于ICCV2019,题为「ACNet:Streng ...

  2. 基于Keras的卷积神经网络(CNN)可视化

    基于Keras的卷积神经网络(CNN)可视化 标签(空格分隔): 深度学习 卷积神经网络可视化 本文整理自Deep Learning with Python,书本上完整的代码在 这里的5.4节,并陪有 ...

  3. 非对称卷积增强CNN特征拟合

    作者:Tom Hardy Date:2020-01-14 来源:非对称卷积增强CNN特征拟合

  4. ICCV 2019 | 加一个任务路由让数百个任务同时跑起来,怎么做到?

    作者 | Gjorgji Strezoski, Nanne van Noord, Marcel Worring 译者 | 中国海洋大学李杰 出品 | AI科技大本营(ID:rgznai100) 摘要 ...

  5. ICCV 2019 | 可选择性与不变性:关注边界的显著性目标检测

    作者丨文永亮 学校丨哈尔滨工业大学(深圳)硕士生 研究方向丨目标检测.GAN 概要 上一次我们介绍了 CVPR 2019 的 BASNet,CVPR 2019 的那篇 BASNet 主要通过引入结构相 ...

  6. ICCV 2019 | Adobe 无需大量数据训练,内部学习机制实现更好的视频修补

    点击我爱计算机视觉标星,更快获取CVML新技术 今天跟大家分享一篇 ICCV 2019 的文章An Internal Learning Approach to Video Inpainting,该文在 ...

  7. 武汉大学提出ARGAN:注意力循环生成对抗模型用于检测、去除图像阴影 | ICCV 2019...

    作者 | 王红成 出品|AI科技大本营(ID:rgznai100) [导读]如何去除一张图像中的阴影部分?在ICCV 2019会上,武汉大学的一篇论文针对这一问题提出了一种用于阴影检测和去除的注意循环 ...

  8. 从一张风景照中就学会的SinGAN模型,究竟是什么神操作?| ICCV 2019最佳论文

    作者 | 王红成,中国海洋大学-信息科学与工程学院-计算机技术-计算机视觉方向研究生,研二在读,目前专注于生成对抗网络的研究 编辑 | Jane 出品 | AI科技大本营(ID:rgznai100) ...

  9. ICCV 2019 论文解读:用图神经网络改善视频的多标签分类

    作者 | 王磊 本文介绍了汽车之家团队在ICCV 2019一篇关于视频理解论文相关的工作.针对视频多标签分类的问题,论文提出了将视频多标签之间相关性特征加入到网络之中,结果证明该方法可以显著的提高视频 ...

最新文章

  1. kylin的安装和启动
  2. 1018 锤子剪刀布 (20分)
  3. C++ 空字符('\0')和空格符(' ')
  4. opencv-api getRotationMatrix2D
  5. keli调试变量出现负值
  6. 蜂窝移动电话定位技术与应用(转)
  7. Cocos2d-Html5--打怪升级之路
  8. 如何保持session一致性?
  9. 全向轮算法/万向轮算法/福来轮算法/全向轮漂移算法/万向轮漂移算法/福来轮漂移算法
  10. java解析蓝奏云直连(解析真正文件地址)
  11. mongodb关机重启
  12. python字符串与十六进制互相转换
  13. 基于CentOS7系统环境下的Snort3安装指南
  14. 【C++】—— STL简介(了解)
  15. Xcode 13 正式版发布,来看看有什么新特性
  16. 在Linux手机上编译和运行2048游戏学习C++
  17. 正则表达式的相关操作和验证
  18. 【游戏设计模式】之二 论撤消重做 回放系统的实现 命令模式
  19. linux安装红帽openshift,Redhat Openshift 单机版安装指南 CRC4.6
  20. markdown编辑工具-Haroopad下载安装

热门文章

  1. Python网络编程(OSI模型、网络协议、TCP)
  2. bootstrap3中模态框的数据编辑使用方法
  3. 20155231 实验三 敏捷开发与XP实践
  4. 区分:AndroidDriver, iOSDriver, AppiumDriver and Remote WebDriver
  5. 【转】让itunes下载加速的真正办法,转向至香港台湾澳门苹果服务器 -- 不错不错!!!...
  6. Windows Phone开发手记-WinRT下分组拼音的实现
  7. 第一个Android项目
  8. mysql dms_关于MySQL与DMsql探寻
  9. python无需修改是什么特性_用户编写的python程序无需修改就可以在不同的平台运行,是python的什么特征...
  10. 标记页面区分渠道php,PM必懂的前端知识