i
n
in
in为输入
d
i
l
a
t
i
o
n
dilation
dilation为空洞
k
e
r
n
e
l
kernel
kernel为卷积核
s
t
r
i
d
e
stride
stride为步长
o
u
t
out
out为输出
卷积形状
padding为数字
o
u
t
[
0
]
=
⌊
i
n
[
0
]
+
2
×
p
a
d
d
i
n
g
[
0
]
−
d
i
l
a
t
i
o
n
[
0
]
×
(
k
e
r
n
e
l
[
0
]
−
1
)
−
1
s
t
r
i
d
e
[
0
]
+
1
⌋
out[0]= \lfloor \frac{in[0]+2\times padding[0]-dilation[0]\times \left ( kernel[0]-1 \right )-1}{stride[0]} +1 \rfloor
out[0]=⌊stride[0]in[0]+2×padding[0]−dilation[0]×(kernel[0]−1)−1+1⌋
o
u
t
[
1
]
=
⌊
i
n
[
1
]
+
2
×
p
a
d
d
i
n
g
[
1
]
−
d
i
l
a
t
i
o
n
[
1
]
×
(
k
e
r
n
e
l
[
1
]
−
1
)
−
1
s
t
r
i
d
e
[
1
]
+
1
⌋
out[1]= \lfloor \frac{in[1]+2\times padding[1]-dilation[1]\times \left ( kernel[1]-1 \right )-1 }{stride[1]} +1 \rfloor
out[1]=⌊stride[1]in[1]+2×padding[1]−dilation[1]×(kernel[1]−1)−1+1⌋
padding为SAME或者VALID
SAME
o
u
t
[
0
]
=
⌊
i
n
[
0
]
s
t
r
i
d
e
[
0
]
⌋
out[0]= \lfloor \frac{in[0]}{stride[0]} \rfloor
out[0]=⌊stride[0]in[0]⌋
o
u
t
[
1
]
=
⌊
i
n
[
1
]
s
t
r
i
d
e
[
1
]
⌋
out[1]= \lfloor \frac{in[1]}{stride[1]} \rfloor
out[1]=⌊stride[1]in[1]⌋
VALID
o
u
t
[
0
]
=
⌊
i
n
[
0
]
−
d
i
l
a
t
i
o
n
[
0
]
×
(
k
e
r
n
e
l
[
0
]
−
1
)
s
t
r
i
d
e
[
0
]
⌋
out[0]= \lfloor \frac{in[0]-dilation[0]\times \left ( kernel[0]-1 \right )}{stride[0]} \rfloor
out[0]=⌊stride[0]in[0]−dilation[0]×(kernel[0]−1)⌋
o
u
t
[
1
]
=
⌊
i
n
[
1
]
−
d
i
l
a
t
i
o
n
[
1
]
×
(
k
e
r
n
e
l
[
1
]
−
1
)
s
t
r
i
d
e
[
1
]
⌋
out[1]= \lfloor \frac{in[1]-dilation[1]\times \left ( kernel[1]-1 \right )}{stride[1]} \rfloor
out[1]=⌊stride[1]in[1]−dilation[1]×(kernel[1]−1)⌋
卷积padding计算
SAME
p
a
d
d
i
n
g
_
h
e
i
g
h
t
=
max
(
(
o
u
t
[
0
]
−
1
)
×
s
t
r
i
d
e
[
0
]
+
1
+
d
i
l
a
t
i
o
n
[
0
]
×
(
k
e
r
n
e
l
[
0
]
−
1
)
−
i
n
[
0
]
,
0
)
p
a
d
d
i
n
g
_
t
o
p
=
p
a
d
d
i
n
g
_
h
e
i
g
h
t
/
/
2
p
a
d
d
i
n
g
_
b
o
t
t
o
m
=
p
a
d
d
i
n
g
_
h
e
i
g
h
t
−
p
a
d
d
i
n
g
_
t
o
p
p
a
d
d
i
n
g
[
0
]
=
⌈
p
a
d
d
i
n
g
_
h
e
i
g
h
t
2
⌉
\\padding\_height= \max \left ( \left ( out[0]-1 \right )\times stride[0]+1+dilation[0]\times \left(kernel[0]-1 \right )-in[0],0 \right ) \\padding\_top=padding\_height //2 \\padding\_bottom=padding\_height -padding\_top \\padding[0]=\lceil \frac{padding\_height}{2} \rceil
padding_height=max((out[0]−1)×stride[0]+1+dilation[0]×(kernel[0]−1)−in[0],0)padding_top=padding_height//2padding_bottom=padding_height−padding_toppadding[0]=⌈2padding_height⌉
p
a
d
d
i
n
g
_
w
i
d
t
h
=
max
(
(
o
u
t
[
1
]
−
1
)
×
s
t
r
i
d
e
[
1
]
+
1
+
d
i
l
a
t
i
o
n
[
1
]
×
(
k
e
r
n
e
l
[
1
]
−
1
)
−
i
n
[
1
]
,
0
)
p
a
d
d
i
n
g
_
l
e
f
t
=
p
a
d
d
i
n
g
_
w
i
d
t
h
/
/
2
p
a
d
d
i
n
g
_
r
i
g
h
t
=
p
a
d
d
i
n
g
_
w
i
d
t
h
−
p
a
d
d
i
n
g
_
t
o
p
p
a
d
d
i
n
g
[
1
]
=
⌈
p
a
d
d
i
n
g
_
w
i
d
t
h
2
⌉
\\padding\_width= \max \left ( \left ( out[1]-1 \right )\times stride[1]+1+dilation[1]\times \left(kernel[1]-1 \right )-in[1],0 \right ) \\padding\_left=padding\_width //2 \\padding\_right=padding\_width -padding\_top \\padding[1]=\lceil \frac{padding\_width}{2} \rceil
padding_width=max((out[1]−1)×stride[1]+1+dilation[1]×(kernel[1]−1)−in[1],0)padding_left=padding_width//2padding_right=padding_width−padding_toppadding[1]=⌈2padding_width⌉
反卷积
padding为数字
o
u
t
[
0
]
=
(
i
n
[
0
]
−
1
)
×
s
t
r
i
d
e
[
0
]
−
2
×
p
a
d
d
i
n
g
[
0
]
+
d
i
l
a
t
i
o
n
[
0
]
×
(
k
e
r
n
e
l
[
0
]
−
1
)
+
1
out[0]=\\ \left ( in[0]-1 \right )\times stride[0]- 2\times padding[0]+ dilation[0] \times \left(kernel[0]- 1 \right )+ 1
out[0]=(in[0]−1)×stride[0]−2×padding[0]+dilation[0]×(kernel[0]−1)+1
o
u
t
[
1
]
=
(
i
n
[
1
]
−
1
)
×
s
t
r
i
d
e
[
1
]
−
2
×
p
a
d
d
i
n
g
[
1
]
+
d
i
l
a
t
i
o
n
[
1
]
×
(
k
e
r
n
e
l
[
1
]
−
1
)
+
1
out[1]=\\ \left ( in[1]-1 \right )\times stride[1]- 2\times padding[1]+ dilation[1] \times \left(kernel[1]- 1 \right )+ 1
out[1]=(in[1]−1)×stride[1]−2×padding[1]+dilation[1]×(kernel[1]−1)+1
padding为SAME或者VALID
SAME
o
u
t
[
0
]
=
i
n
[
0
]
×
s
t
r
i
d
e
[
0
]
out[0]= in[0] \times stride[0]
out[0]=in[0]×stride[0]
o
u
t
[
1
]
=
i
n
[
1
]
×
s
t
r
i
d
e
[
1
]
out[1]= in[1] \times stride[1]
out[1]=in[1]×stride[1]
VALID
o
u
t
[
0
]
=
(
i
n
[
0
]
−
1
)
×
s
t
r
i
d
e
[
0
]
+
d
i
l
a
t
i
o
n
[
0
]
×
(
k
e
r
n
e
l
[
0
]
−
1
)
+
1
out[0]=\left ( in[0]-1 \right )\times stride[0]+ dilation[0] \times \left(kernel[0]- 1 \right )+ 1
out[0]=(in[0]−1)×stride[0]+dilation[0]×(kernel[0]−1)+1
o
u
t
[
1
]
=
(
i
n
[
1
]
−
1
)
×
s
t
r
i
d
e
[
1
]
+
d
i
l
a
t
i
o
n
[
1
]
×
(
k
e
r
n
e
l
[
1
]
−
1
)
+
1
out[1]=\left ( in[1]-1 \right )\times stride[1]+ dilation[1] \times \left(kernel[1]- 1 \right )+ 1
out[1]=(in[1]−1)×stride[1]+dilation[1]×(kernel[1]−1)+1
padding计算
p
a
d
d
i
n
g
_
h
e
i
g
h
t
=
max
(
(
i
n
[
0
]
−
1
)
×
s
t
r
i
d
e
[
0
]
+
d
i
l
a
t
i
o
n
[
0
]
×
(
k
e
r
n
e
l
[
0
]
−
1
)
+
1
−
o
u
t
[
0
]
,
0
)
p
a
d
d
i
n
g
_
t
o
p
=
p
a
d
d
i
n
g
_
h
e
i
g
h
t
/
/
2
p
a
d
d
i
n
g
_
b
o
t
t
o
m
=
p
a
d
d
i
n
g
_
h
e
i
g
h
t
−
p
a
d
d
i
n
g
_
t
o
p
p
a
d
d
i
n
g
[
0
]
=
⌈
p
a
d
d
i
n
g
_
h
e
i
g
h
t
2
⌉
\\padding\_height=\max \left(\left(in[0]- 1 \right )\times stride[0]+ dilation[0]\times \left(kernel[0]-1 \right )+ 1- out[0],0 \right ) \\padding\_top= padding\_height //2 \\padding\_bottom=padding\_height - padding\_top \\padding[0]=\lceil \frac{padding\_height}{2} \rceil
padding_height=max((in[0]−1)×stride[0]+dilation[0]×(kernel[0]−1)+1−out[0],0)padding_top=padding_height//2padding_bottom=padding_height−padding_toppadding[0]=⌈2padding_height⌉
p
a
d
d
i
n
g
_
w
i
d
t
h
=
max
(
(
i
n
[
1
]
−
1
)
×
s
t
r
i
d
e
[
1
]
+
d
i
l
a
t
i
o
n
[
1
]
×
(
k
e
r
n
e
l
[
1
]
−
1
)
+
1
−
o
u
t
[
1
]
,
0
)
p
a
d
d
i
n
g
_
l
e
f
t
=
p
a
d
d
i
n
g
_
w
i
d
t
h
/
/
2
p
a
d
d
i
n
g
_
r
i
g
h
t
=
p
a
d
d
i
n
g
_
w
i
d
t
h
−
p
a
d
d
i
n
g
_
l
e
f
t
p
a
d
d
i
n
g
[
0
]
=
⌈
p
a
d
d
i
n
g
_
w
i
d
t
h
2
⌉
\\padding\_width=\max \left(\left(in[1]- 1 \right )\times stride[1]+ dilation[1]\times \left(kernel[1]-1 \right )+ 1- out[1],0 \right ) \\padding\_left= padding\_width //2 \\padding\_right=padding\_width - padding\_left\\padding[0]=\lceil \frac{padding\_width}{2} \rceil
padding_width=max((in[1]−1)×stride[1]+dilation[1]×(kernel[1]−1)+1−out[1],0)padding_left=padding_width//2padding_right=padding_width−padding_leftpadding[0]=⌈2padding_width⌉
import math
def calc_conv_size(in_size, stride, padding, dilation, kernel_size):
h_out = math.floor((in_size[0] + 2 * padding[0] - dilation[0] * (kernel_size[0] - 1) - 1) / (stride[0]) + 1)
w_out = math.floor((in_size[1] + 2 * padding[1] - dilation[1] * (kernel_size[1] - 1) - 1) / (stride[1]) + 1)
return h_out, w_out
def calc_deconv_size(in_size, stride, padding, dilation, kernel_size):
h_out = (in_size[0] - 1) * stride[0] - 2 * padding[0] + dilation[0] * (kernel_size[0] - 1) + 1
w_out = (in_size[1] - 1) * stride[1] - 2 * padding[1] + dilation[1] * (kernel_size[1] - 1) + 1
return h_out, w_out
def calc_conv_padding_size(in_size, stride, dilation, kernel_size, out_size):
padding_height = max((out_size[0] - 1) * stride[0] + 1 + dilation[0] * (kernel_size[0] - 1) - in_size[0], 0)
padding_width = max((out_size[1] - 1) * stride[1] + 1 + dilation[1] * (kernel_size[1] - 1) - in_size[1], 0)
return math.ceil(padding_height / 2), math.ceil(padding_width / 2)
def calc_deconv_padding_size(in_size, stride, dilation, kernel_size, out_size):
padding_height = max((in_size[0] - 1) * stride[0] + 1 + dilation[0] * (kernel_size[0] - 1) - out_size[0], 0)
padding_width = max((in_size[1] - 1) * stride[1] + 1 + dilation[1] * (kernel_size[1] - 1) - out_size[1], 0)
return math.ceil(padding_height / 2), math.ceil(padding_width / 2)