看了吴恩达老师的深度学习课程,里面有提到卷积网络的大小计算方式,就记录一下,顺便以pytorch代码实现验证一下。
记图像尺寸为 n ∗ n n*n n∗n,卷即核尺寸为 f ∗ f f*f f∗f,步长为 s s s,padding大小为 p p p,输出的尺寸大小为 ( n + 2 p − f s + 1 ) ∗ ( n + 2 p − f s + 1 ) {({{n+2p-f} \over s}+1 )}*{({{n+2p-f} \over s}+1 )} (sn+2p−f+1)∗(sn+2p−f+1)
令 n = 224 , f = 3 , s = 1 , p = 1 n=224,f=3,s=1,p=1 n=224,f=3,s=1,p=1
带入上式计算得输出尺寸 s i z e = 224 size=224 size=224
代码验证如下
import torch
import torch.nn as nn
class conv(nn.Module):
def __init__(self, ch_in=3, ch_out=3):
super(conv, self).__init__()
self.conv1 = nn.Conv2d(ch_in, ch_out, kernel_size=3, stride=1, padding=1, bias=True)
def forward(self, x):
x = self.conv1(x)
return x
t = conv()
a=torch.randn(32,3,224,224)
print(t(a).shape)
>>>torch.Size([32, 3, 224, 224])
令 n = 224 , f = 3 , s = 2 , p = 2 n=224,f=3,s=2,p=2 n=224,f=3,s=2,p=2
带入上式计算得输出尺寸 s i z e = 113.5 size=113.5 size=113.5
代码验证如下
import torch
import torch.nn as nn
class conv(nn.Module):
def __init__(self, ch_in=3, ch_out=3):
super(conv, self).__init__()
self.conv1 = nn.Conv2d(ch_in, ch_out, kernel_size=3, stride=2, padding=2, bias=True)
def forward(self, x):
x = self.conv1(x)
return x
t = conv()
a=torch.randn(32,3,224,224)
print(t(a).shape)
>>>torch.Size([32, 3, 113, 113])
这里需要注意的是像素是没有小数点的,所以在设计卷积层时要注意参数的设置
膨胀卷积是对卷积核进行0填充,参数dilation_rate(默认为1),会改变卷积核的大小,其他计算和普通卷积相同,卷积核的计算公式如下 k e r n e l _ s i z e = d i l a t i o n _ r a t e ∗ ( k e r n e l _ s i z e − 1 ) + 1 kernel\_size=dilation\_rate*(kernel\_size - 1)+1 kernel_size=dilation_rate∗(kernel_size−1)+1
令 n = 224 , f = 3 , s = 1 , p = 1 , d i l a t i o n _ r a t e = 2 n=224,f=3,s=1,p=1,dilation\_rate=2 n=224,f=3,s=1,p=1,dilation_rate=2
代入公式计算 k e r n e l _ s i z e = 5 kernel\_size=5 kernel_size=5, s i z e = 222 size=222 size=222
代码验证如下
import torch
import torch.nn as nn
class conv(nn.Module):
def __init__(self, ch_in=3, ch_out=3):
super(conv, self).__init__()
self.conv1 = nn.Conv2d(ch_in, ch_out, kernel_size=3, stride=1, padding=1,dilation=2, bias=True)
def forward(self, x):
x = self.conv1(x)
return x
t = conv()
a=torch.randn(32,3,224,224)
print(t(a).shape)
>>>torch.Size([32, 3, 222, 222])
可以理解为把常规卷积的输入与输出交换下位置
计算公式为 s ∗ ( n − 1 ) + f − 2 p s*(n-1)+f-2p s∗(n−1)+f−2p
令 n = 5 , f = 3 , s = 2 , p = 0 n=5,f=3,s=2,p=0 n=5,f=3,s=2,p=0
代入计算的 s i z e = 11 size=11 size=11
代码验证
import torch
import torch.nn as nn
class conv(nn.Module):
def __init__(self, ch_in=3, ch_out=3):
super(conv, self).__init__()
self.conv1 = nn.ConvTranspose2d(in_channels= ch_in,out_channels=ch_out,kernel_size=3,stride=2,padding=0)
def forward(self, x):
x = self.conv1(x)
return x
t = conv()
a=torch.randn(32,3,5,5)
print(t(a).shape)
>>>torch.Size([32, 3, 11, 11])