在跑一份代码时,效果一直提升不上去,偶然将3 * 3的卷积核换成了4 * 4的卷积核,效果奇佳,于是搜索了一下卷积核的大小对网络性能的影响,总结如下:

1.大卷积核和小卷积核

显然,大卷积核的感受野更大,自然提取特征的性能更好,一个5 * 5的卷积核可以由两个3 * 3的卷积核替换,但是带来的代价是:大卷积核的计算速度更慢,参数量更多。因此,通常使用小卷积核,小卷积核所需要的参数量更少,且产生了更多的特征

2.奇数卷积核和偶数卷积核

“Convolution with even-sized kernels and symmetric padding” 这篇论文,解释了偶数卷积核对网络的影响,这里不对论文中的公式做解读,只对文章中提出的对普通卷积方式和padding方式提出的改进做以分析

在普通的分类任务中用偶数卷积核,偶数卷积之所以结果更差,是因为偶数卷积会使得feature map偏移,即**“the shift problem”**,这将导致学习到的feature不具备更强的表征能力,如下图所示,激活后(ReLU)值逐渐移到空间位置的左上角。文章提出信息侵蚀假设,认为奇数卷积中心对称,而偶数卷积在实现时没有对称点,这将导致在实现时卷积利用的信息不能是各个方向的,只能是左上或其他方向(取决于具体实现),因此整体将会导致feature map往一个方向偏移。当堆叠多层偶数大小的卷积时,位置偏移会累积,最终会挤压并将要素扭曲到空间位置的某个角。(如图,第一行是没使用论文方法padding的conv2x2的结果,第二行是论文方法的结果)
在这里插入图片描述
并且,在GAN中,将网络深度加倍会阻碍训练,并将卷积核大小增加到7或5会导致性能下降或只有微小的改进。 这些表明GAN需要增加信息,并且对信息侵蚀更敏感。

为了解决feature map偏移带来的影响,本文提出了一种padding方式,称为symmetric padding,具体的操作如图:
在这里插入图片描述
即先将feature map分成四个group,每个group在不同方向上按如图所示的方式进行padding,最后将4个group用concat拼接起来再conv2x2即可。
这样做的好处就是使得网络的某些channel能利用到特定方向的信息,从宏观上看网络利用到了各个方向的信息,一定程度上缓解了shift带来的问题。
一个symmetric padding的简单例子

import torch
import torch.nn as nn
import torch.nn.functional as F
class SpConv2d(nn.Module):
    def __init__(self,in_channels,out_channels,kernel_size,stride,padding,*args,**kwargs):
        super(SpConv2d,self).__init__()
        self.conv = nn.Conv2d(in_channels,out_channels,kernel_size,stride,padding)
    def forward(self,x):
        n,c,h,w = x.size()
        assert c % 4 == 0
        x1 = x[:,:c//4,:,:]
        x2 = x[:,c//4:c//2,:,:]
        x3 = x[:,c//2:c//4*3,:,:]
        x4 = x[:,c//4*3:c,:,:]
        x1 = nn.functional.pad(x1,(1,0,1,0),mode = "constant",value = 0) # left top
        x2 = nn.functional.pad(x2,(0,1,1,0),mode = "constant",value = 0) # right top
        x3 = nn.functional.pad(x3,(1,0,0,1),mode = "constant",value = 0) # left bottom
        x4 = nn.functional.pad(x4,(0,1,0,1),mode = "constant",value = 0) # right bottom
        x = torch.cat([x1,x2,x3,x4],dim = 1)
        return self.conv(x)
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.conv = SpConv2d(4,16,2,1,0)
    def forward(self,x):
        return self.conv(x)
if __name__ == "__main__":
    x = torch.randn(2,4,14,14)
    net = Net()
print(net(x))

然而在我的实验中,直接用4*4的卷积核,得到的正确率就能到达94.2222%,将卷积换成上面代码中的SpConv2d,正确率就能提高至97.4444%,且用SpConv2d的网络收敛更快,正常的Conv2d用3000左右个epoch能收敛,SpConv2d用1000个左右的epoch就能收敛,该现象的具体原因还有待探究

参考:https://www.cnblogs.com/aoru45/p/12253838.html

在跑一份代码时,效果一直提升不上去,偶然将3 * 3的卷积核换成了4 * 4的卷积核,效果奇佳,于是搜索了一下卷积核的大小对网络性能的影响,总结如下:1.大卷积核和小卷积核显然,大卷积核的感受野更大,自然提取特征的性能更好,一个5 * 5的卷积核可以由两个3 * 3的卷积核替换,但是带来的代价是:大卷积核的计算速度更慢,参数量更多。因此,通常使用小卷积核,小卷积核所需要的参数量更少,且产... FFT卷积 脚本提供了一些示例,用于计算2D实信号的各种卷积积(Full,Valid,Same,Circular)。 还有一些脚本用于测试实现(针对八度和Matlab),而其他脚本则用于对卷积进行基准测试。 比较的不同实现是 八度转换和fftconv fftconv2 我使用FFT的技巧之一是在可能的情况下计算要卷积的最佳信号大小。 由于FFTW和GSL的FFT依赖于质数因子分解,因此计算具有可分解大小的信号的FFT比大质数大小的FFT更快。 对于某些卷积,可以填充任意数量(下界)的零。 诀窍是仅添加更多0来获得可以分解的大小。 文件中给出了带FFT的卷积积的描述。 编译/使用 每个脚本的开头都有一行,给出了编译行。 您还具有一个主makefile: 运行基准测试:制定基准测试 针对octave和matlab运行实现的测试:进行测试 绘制比较(下图):绘制图 对2D卷积执行基准测试,其源和内核的大小最大为100 通过在各种条件下生成50个随机源和内核(具有奇数/偶数源和内核的1D卷积,以及2D卷积)并比较容差为1e-12的八度音阶的卷
卷积神经网络(ConvolutionalNeuralNetwork,CNN)是一种前馈神经网络,在计算机视觉等领域被广泛应用.本文将简单介绍其原理并分析Tensorflow官方提供的示例.关于神经网络与误差反向传播的原理可以参考作者的另一篇博文BP神经网络与Python实现.卷积是图像处理中一种基本方法.卷积核是一个f*f的矩阵.通常n取奇数,使得卷积核有中心点.对图像中每个点取以其为中心的f阶方阵,将该方阵中各值与卷积核中对应位置的值相乘,并用它们的和作为结果矩阵中对应点的值.1*1+1*0+1*1+0*0+1*1+1*0+0*1+0*0+1*1=4卷积核每次向右移动1列,遇行末向下移动1列
卷积核相当于是一个滑动窗口,一般像我们看到的3x3的卷积核就是指覆盖3x3像素的一个滑动窗口,对于单个kernal size中的卷积核,滑动窗口3x3中的9个参数都是公用的,来处理一个通道的输入数据,比如: 一般图片都是RGB三层,像素大小为224x224,那个一个输入图片的大小为224x224x3,然后通过64个3x3的卷积层来提取特征,最后输出的特征向量的大小是由步长stride和padding决定的,一般都为1(而maxpooling池化层stride为2或者其他,从而降低输出特征矩阵的大小),这样的
为什么CNN中的卷积核一般都是奇奇数*奇数,没有偶数*偶数的? 咱们经常见到的多为 3 * 3、5*5;怎么从来没有见过 4*4,6*6 之类的卷积核?无论奇数 or 偶数,都是能够做卷积的呀 之前学习的时候真的没有想过这些问题,再复习时,觉得全是 Why?说明之前还是没有搞明白 从AlexNet模型的11*11、5*5、3*3,还有V...
今天看到一篇比较有意思的文章,也解开了我一直一个疑问:为什么现在卷积神经网络中卷积核都是奇数的。比如3×3,5×5,7×7. 3×3的卷积核也是在VGG证明了用两个可以代替一个7*7效果更好,且参数还更少。那么为什么没有人用两个2×2的卷积核代替3×3的卷积核,或者就是直接用2×2的卷积代替3×3呢? 今天看到的文章,Convolution with even-sized kernels an...
为什么卷积核size通常都是奇数 本博客用于自我学习,如有错误,烦请指教! 在卷积神经网络模型中卷积核大小一般都是偶数,很少有奇数或者没有奇数卷积核,这是为什么呢? LeNet()卷积核大小55,AlexNet模型(2012)中用到1111,55,33,VGG(2014)系列用得都是33大小卷积核,ResNet(2015)使用33大小卷积核等等,都是使用奇数卷积核。 原因有2: 1. 保证锚点在中间 锚点也就是卷积核滑动时得中心点,一个参考点,奇数大小的卷积核刚好是中心位置,避免位置信息发生偏移,在CN
深度学习中有关卷积算术的技术报告。 本教程的代码和图像可根据许可证的规定免费使用,并具有适当的归属: [1] Vincent Dumoulin,Francesco Visin-( ) 注意:蓝色图是输入,青色图是输出。 没有填充,没有大步前进 任意填充,没有大幅度提高 半填充,没有大步前进 完全填充,没有大步前进 没有填充,大步前进 填充,大步前进 填充,跨度(奇数) 转置卷积动画 注意:蓝色图是输入,青色图是输出。 无填充,无跨步,换位 任意填充,无跨步,转置 半填充,无跨步,换位 全填充,无跨步,换位 无填充,跨步,移调 填充,大步,换位 填充,跨步,移调(奇数) 膨胀的卷积动画 注意:蓝色图是输入,青色图是输出。 无填充,无步幅,膨胀 生成Makefile 从存储库的根目录: $ ./bin/generate_makefile fft代码FFT卷积 脚本提供了一些示例,用于计算2D实信号的各种卷积积(Full,Valid,Same,Circular)。 还有一些脚本用于测试实现(针对八度和Matlab),而其他脚本则用于对卷积进行基准测试。 比较的不同实现是 八度转换和fftconv fftconv2 我使用FFT的技巧之一是在可能的情况下计算要卷积的最佳信号大小。 由于FFTW和GSL的FFT依赖于质数因子分解,因此与大质数大小相比,计算具有可分解大小的信号的FFT更快。 对于某些卷积,可以填充任意数量(下界)的零。 诀窍是仅添加更多0以获得可分解的大小。 文件中给出了带FFT的卷积积的描述。 编译/使用 每个脚本的开头都有一行,给出了编译行。 您还具有一个主makefile: 运行基准测试:制定基准测试 针对octave和matlab运行实现的测试:进行测试 绘制比较(下图):绘制图 对2D卷积执行基准测试,其源和内核的大小最大为100 通过在各种条件下生成50个随机源和内核(带有奇数/偶数源和内核的一维卷积,以及2D卷积)并比较容差为1e-12的八度音阶的卷积结 为什么CNN中的卷积核一般都是奇数*奇数? 熟悉CNN应该都知道常见的卷积核都是3*3或者5*5等,也就是奇数*奇数,似乎都没看过偶数的,这是为什么呢? 作者/编辑汤兴旺 在CNN中,卷积核的大小是3*3或者5*5是最常见的。也就是说我们见到的卷积核几乎都是奇数*奇数的。在LeNet5中两个卷积层的卷积核都是5*5。 而在AlexNet...
你好!感谢您的提问。要使用cv2.filter2d()函数进行卷积操作,需要指定卷积核的大小,在函数的第三个参数中传入一个二维的NumPy数组作为卷积核。数组的大小必须为奇数,以确保卷积核有一个中心元素。例如,如果需要使用一个3x3的卷积核,可以使用以下代码: kernel = np.ones((3,3), np.float32)/9 dst = cv2.filter2D(src, -1, kernel) 其中,src是输入图像,dst是输出图像。第二个参数是目标图像的深度,通常设置为-1表示与原图像一致。第三个参数就是卷积核了,这里使用np.ones()生成一个3x3的全1矩阵,再除以9得到平均卷积核