zoukankan      html  css  js  c++  java
  • 卷积和反卷积详细说明

    转载:https://zhuanlan.zhihu.com/p/124626648

    转载:https://www.cnblogs.com/wanghui-garcia/p/10791328.html

    1. 卷积 Convolution

    1.1 卷积输出尺寸

    输出图像尺寸可以根据以下公式获得

    [公式]

    • [公式] :输入图像尺寸
    • [公式] : padding 大小
    • [公式] : 卷积核大小
    • [公式] : 步长

    卷积:蓝色的输入图片(4 x4),深蓝色代表卷积核(3 x 3),绿色为输出图像(2 x 2)

    假如现在有一个4 x 4的图片, 使用一个3 x 3的kernel 进行卷积

    图片: [公式] 卷积核: [公式]

    strides = 1 , padding = 0, 卷积后,输出图像的尺寸为 [公式]

    如果卷积核很大,那么可以使用傅里叶变换, 提升卷积的性能。

    2. 反卷积 Transposed Convolution

    由于卷积核一般比原始图像小,所以卷积之后的图像尺寸往往会变小。有时候我们需要将卷积后的图像还原成原始图像的尺寸,即实现图像从小分辨率到大分辨率的映射,这种操作就叫做上采样(Upsampling)。而反卷积正是一种上采样方法。

    反卷积,又称为转置卷积(Transposed Convolution,),它是一种特殊的卷积,先padding来扩大图像尺寸,紧接着跟正向卷积一样,旋转卷积核180度,再进行卷积计算。看上去就像,已知正向卷积的输出图像,卷积核,得到正向卷积中的原始图像(并非真的得到原始图像,像素点是不一样的,但是尺寸是一致的)。

    它看上去像是正向卷积的逆运算,但其实并不是。因为反卷积只能还原原始图像的尺寸,但是并不能真的恢复原始图像内容,即每个元素值其实是不一样的。

    卷积过程中:

    [公式] 表示输出, [公式] 表示输入, [公式] :表示kernel的大小, [公式]:表示padding, [公式] : 表达strides

    反卷积过程中:

    [公式] 表示输出, [公式] 表示输入, [公式] :表示kernel的大小, [公式]:表示padding, [公式] : 表达strides

    卷积后的 [公式] 则反卷积的 [公式] , 一般卷积核是不会变的, [公式] ,需要注意的是,卷积与反卷积的padding很可能是不一样。

    2.1 Striding

    反卷积的Striding跟卷积有点不一样,它在输入的每个元素之间插入 [公式] 个值为0的元素

    Transposed convolution : Striding

    如果我们将反卷积看成是一种特殊的卷积,它其实是根据反卷积中指定的步长strides, 修改了输入 [公式], 根据strding 进行补0操作,得到 [公式] , 其大小变为 [公式] , 然后对 [公式] 进行s=1的卷积。例如,对应上面的三个子图, [公式] 对应的 [公式] , [公式] 对应的 [公式] , [公式] 对应的 [公式] 。

    反卷积:蓝色是输入(3 x 3), 灰色是卷积核(3 x 3), 绿色是输出(5 x 5),padding=1,strides = 2

    反卷积:蓝色是输入(5 x 5), 灰色是卷积核(3 x 3), 绿色是输出(5 x 5),padding=1,strides =1

    3 反卷积的输出尺寸

    可见这里没考虑output_padding

    output_padding的作用:可见nn.ConvTranspose2d的参数output_padding的作用.

    论文 A guide to convolution arithmetic for deep learning 涉及了14种有关反卷积的尺寸大小公式的关系,但是归纳起来就只有两种情况。

    3.1 [公式]

    反卷积的输出尺寸为 [公式] 或者 [公式]

    对应上面提到的卷积的例子,分别用上面两条公式进行验算,验算结果都成立。

    卷积时, [公式] ,[公式] , [公式] , [公式] , 所以计算的结果 [公式]

    反卷积, [公式] , [公式] , [公式] , [公式] ,

    代入第一个式子 [公式]

    代入第二个式子 [公式]

    反卷积,蓝色是输入(2 x 2), 灰色是卷积核(3 x 3), 绿色是输出(4 x 4),padding=2

    4.下面举例说明

    https://github.com/vdumoulin/conv_arithmetic#convolution-arithmetic

    1)当stride=1时,就不会进行插值操作,只会进行padding,举例说明:

    卷积操作为:

    蓝色为输入特征图Hin*Hin=4*4,绿色为输出特征图Hout*Hout=2*2,卷积核kernel_size=3, stride=1

    根据式子Hout =  floor( Hin + 2*padding - kernel_size / stride) + 1

    可得padding=0

    其对应的逆卷积操作为:

    蓝色为输入特征图Hout*Hout=2*2,绿色为输出特征图Hin*Hin=4*4,卷积核kernel_size=3, stride=1

    卷积时的padding=0

    将这些值代入上面的式子Hin = (Hout - 1) * stride - 2*padding + kernel_size

    果然输入Hout*Hout=2*2能得到输出Hin*Hin=4*4

    变形过程为:

    paddingnew = kernel_size - padding -1 = 3 -0 -1 = 2

    所以可见下方的蓝色最后的大小为7*7 = Hout + 2*paddingnew = 2 + 2*2 = 6

    ⚠️这里可见是有padding的,为什么定义是为no padding呢?

    这是因为它对应的卷积操作的padding=0

     1)当stride=2时,进行插值和padding操作,举例说明:

    卷积操作为:

    蓝色为输入特征图Hin*Hin=5*5,绿色为输出特征图Hout*Hout=3*3,卷积核kernel_size=3, stride=2

    根据式子Hout =  floor( Hin + 2*padding - kernel_size / stride) + 1

    可得padding=1

    其对应的逆卷积操作为:

    蓝色为输入特征图Hout*Hout=3*3,绿色为输出特征图Hin*Hin=5*5,卷积核kernel_size=3,stride=2

    卷积时的padding=1

    将这些值代入上面的式子Hin = (Hout - 1) * stride - 2*padding + kernel_size

    果然输入Hout*Hout=3*3能得到输出Hin*Hin=5*5

    变形操作为:

    Hout_new = Hout + (stride-1) * (Hout-1) = 3 + (2-1)*(3-1) = 5

    paddingnew = kernel_size - padding -1 = 3 -1 -1 = 1

    所以可见下方的蓝色最后的大小为7*7 = Hout_new + 2*paddingnew = 5 + 2*1 = 7

     

    ⚠️因为这里的逆卷积对应的卷积操作的padding= 1,所以这里不是no padding,而是padding

  • 相关阅读:
    bzoj1014: [JSOI2008]火星人prefix
    bzoj1934: [Shoi2007]Vote 善意的投票&&bzoj2768:[JLOI2010]冠军调查
    bzoj2705: [SDOI2012]Longge的问题
    bzoj4653: [Noi2016]区间
    bzoj2456: mode
    bzoj5018: [Snoi2017]英雄联盟
    关于树论【左偏树】
    caioj1522: [NOIP提高组2005]过河
    caioj1421&&hdu2167: [视频]【状态压缩】选数
    Linux下全局安装composer方法
  • 原文地址:https://www.cnblogs.com/hansjorn/p/14767592.html
Copyright © 2011-2022 走看看