速查:卷积核参数计算公式

使用符号
输入尺寸(input): ii
卷积核大小(kernel size): kk
步幅(stride): ss
边界扩充(padding): pp
输出尺寸(output): oo

卷积公式

没有padding,且s=1

公式1:对于任意的i和k,如果s=1,p=0s=1,p=0,则
o=(ik)+1 o=(i-k)+1

有padding,且s=1

公式2:对于任意的i和k,p,如果s=1s=1,则
o=(ik)+2p+1 o=(i-k)+2p+1

Half (same) padding

公式3:如果我们希望输出的大小等于输入的大小,那么首先保证,k是奇数,于是对于任意的i,对于奇数的k=2n+1k=2n+1,s=1,p=k/2=ns=1,p=\lfloor k/2 \rfloor=n,于是
o=i+2k/2(k1)=i+2n2n=i \begin{aligned} o &=i+2\lfloor k / 2\rfloor-(k-1) \\ &=i+2 n-2 n \\ &=i \end{aligned}

这也是为什么,参数组合k=3,s=1,p=1以及k=5,s=1,p=2那么常见的原因,他们不会改变output的大小。

Full padding

这是一种让input size增加的padding设置方式:
公式4:对于任意的i,ki,k,并设p=k1,s=1p=k-1,s=1
o=i+2(k1)(k1)=i+(k1) \begin{array}{l} {o=i+2(k-1)-(k-1)} \\ {\quad=i+(k-1)} \end{array}

没有padding,s>1

上面都是讨论s=1的情况,现在讨论s>1的情况,首先没有padding的话公式是:
公式5:对于任意的i,k,si,k,s,若p=0p=0,则
o=iks+1 o=\lfloor \frac{i-k}{s}\rfloor+1

有padding,s>1

现在如果有padding:
公式6:对于任意的i,k,s,pi,k,s,p
o=i+2pks+1 o=\lfloor \frac{i+2p-k}{s}\rfloor+1

可以看到,s的增加会使得i成倍地减少,如果想要让o=i/2o=i/2,一个最常用的配置是设s=2,然后22pk1-2\le 2p-k \le -1,也就是s=2,p=1,k=4s=2,p=1,k=4,或者s=2,p=1,k=3s=2,p=1,k=3都可以

Pooling 公式

pooling其实只是一种特别的卷积核,所以他的计算公式跟卷积是一模一样的,而且由于pooling是没有padding的,所以他的计算公式就是:
公式7:对于任意的i,k,si,k,s
o=iks+1 o=\lfloor \frac{i-k}{s}\rfloor+1

反卷积公式

没有padding,且s=1

公式8如果正向卷积对于任意的kk,且s=1,p=0s=1,p=0,那么如果其反卷积的设置为k=k,s=s,p=k1k'=k,s'=s,p'=k-1,则反卷积的输出大小为:
o=i+(k1) o'=i'+(k-1)
显然,这个跟公式1是一一对应的,(根据公式1,可以推出i=o1+ki=o-1+k

有padding,且s=1

公式9:如果正向卷积对于任意的k,pk,p,且s=1s=1,那么如果其反卷积的设置为k=k,s=s,p=kp1k'=k,s'=s,p'=k-p-1,则反卷积的输出大小为:
o=i+(k1)2p o'=i'+(k-1)-2p
类似的,这个公式是跟公式2一一对应的。显然,当k=3,s=1,p=1k=3,s=1,p=1时,其反卷积的参数恰好也是k=3,s=1,p=311=1k'=3,s'=1,p'=3-1-1=1,是一模一样的,另外一个常用的配置是,k=5,s=1,p=3k=5,s=1,p=3,此时,反卷积的参数也是跟正向卷积一样的。

Half (same) padding

公式10: 如果正向卷积对于任意的k=2n+1k=2n+1为奇数,且s=1,p=k/2=ns=1,p=\lfloor k/2 \rfloor=n,那么如果其反卷积的设置为k=k,s=s,p=pk'=k,s'=s,p'=p,则反卷积的输出大小为:
o=i+(k1)2p=i+2n2n=i \begin{aligned} o^{\prime} &=i^{\prime}+(k-1)-2 p \\ &=i^{\prime}+2 n-2 n \\ &=i^{\prime} \end{aligned}

这个公式是跟公式3是一一对应的,反卷积同意也能得到相同大小的output与input。

Full padding

这是对应于公式4的反卷积,将input减少的
公式11: 如果正向卷积对于任意的kk,且s=1,p=k1s=1,p=k-1,那么如果其反卷积的设置为k=k,s=s,p=0k'=k,s'=s,p'=0,则反卷积的输出大小为:
o=i+(k1)2p=i(k1) \begin{aligned} o^{\prime} &=i^{\prime}+(k-1)-2 p \\ &=i^{\prime}-(k-1) \end{aligned}

没有padding,且s>1

在反卷积中,如果s>1,那么它在像素间插入空白的间隔,如下图所示:
在这里插入图片描述
经过扩大的图大小变成了
i^=i+(s1)(i1) \hat{i'}=i+(s-1)(i-1)
每一块输入之间都插入了(s-1)个空白点。经过插入后的大小记为i^\hat{i'}

公式12: 如果正向卷积对于任意的k,sk,s,且p=0p=0,以及iki-kss的整数倍,那么如果其反卷积,将想原始图像的输入拓展成i^=i+(s1)(i1)\hat{i'}=i+(s-1)(i-1),然后设置为k=k,s=1,p=k1k'=k,s'=1,p'=k-1,则反卷积的输出大小为:
o=s(i1)+k o'=s(i'-1)+k

有padding,且s>1

公式13: 如果正向卷积对于任意的k,s,pk,s,p,以及i+2pki+2p-kss的整数倍,那么如果其反卷积,将想原始图像的输入拓展成i^=i+(s1)(i1)\hat{i'}=i+(s-1)(i-1),然后设置为k=k,s=1,p=kp1k'=k,s'=1,p'=k-p-1,则反卷积的输出大小为:
o=s(i1)+k2p o'=s(i'-1)+k-2p

在上面为了方便计算,都是假设是整数倍,如果没有这个假设,那么:
公式14: 如果正向卷积对于任意的k,s,pk,s,p,,那么如果其反卷积,将想原始图像的输入拓展成i^=i+(s1)(i1)\hat{i'}=i+(s-1)(i-1),然后设置为k=k,s=1,p=k1k'=k,s'=1,p'=k-1,则反卷积的输出大小为:

o=s(i1)+a+k2p o'=s(i'-1)+a+k-2p

其中a=(i+2pk)mod  sa=(i+2p-k) \mod s.

暴力测试参数数量

说实话。。最方便的方法还是直接写代码测测维度大小:

import torch
import torch.nn as nn

def paras_cnn(k,s,p,i=64):
    x=torch.ones(1,1,i,i)
    conv = torch.nn.Conv2d(1, 1, kernel_size=k, stride=s, padding=p)
    convt= torch.nn.ConvTranspose2d(1, 1, kernel_size=k, stride=s, padding=p)
    h1=conv(x)
    h2=convt(x)
    y=convt(h1)
    print("conv(x):{} \t convT(x):{} \t convT(conv(x)):{}".format((h1.shape[2],h1.shape[3]),(h2.shape[2],h2.shape[3]),(y.shape[2],y.shape[3])))
    return h1.shape[2],h1.shape[3],h2.shape[2],h2.shape[3],y.shape[2],y.shape[3]

参考资料

https://arxiv.org/abs/1603.07285
https://zhuanlan.zhihu.com/p/57348649

发布了70 篇原创文章 · 获赞 239 · 访问量 45万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章