[Python]Utility function of calculate convolution output shape

Posted by John on 2019-12-09
Words 477 and Reading Time 2 Minutes
Viewed Times

心情不好就來發發廢文技術文,然後完蛋了要過年了距離我的目標100篇還差5篇。

在使用pytorch時比較麻煩的一點是,convolution的shape要計算好,才不會給錯conv的參數,所以這時候使用者就要對於Convolution到底怎麼運作的(kernel size/padding/stride/dilation)有很清楚的瞭解才行,不然連shape都推不出來是要怎麼給模型參數?

pytorch的doc內對於各種Conv(Conv1d, Conv2d)都給了一個公式讓大家可以很方便的推出input shape 和 output shape之間的對應關係,可是我又很懶不想每次都慢慢去看公式來算,所以參考網路上的資源就寫了兩個function,分別來計算給定input shape和你想要的Conv設定(kernel size/ padding…這些)時,output shape會長怎樣,順便拿這個來發廢文,廢話不多說,直接發代碼啦。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import math

def conv_2d_output_shape(h_w, kernel_size=1, stride=1, pad=0, dilation=1):
"""
Utility function for computing output shape of 2d-convolutions
input:
(h,w)(tuple): (height, width) of input
kernel_size: kernel size of kernel
stride: stride of convolution
pad: padding of convolution
dilation: dilation of convolution

output:
(h,w)(tuple): (height, width) of output
"""
if type(kernel_size) is not tuple:
kernel_size = (kernel_size, kernel_size)
h = math.floor( ((h_w[0] + (2 * pad) - ( dilation * (kernel_size[0] - 1) ) - 1 )/ stride) + 1)
w = math.floor( ((h_w[1] + (2 * pad) - ( dilation * (kernel_size[1] - 1) ) - 1 )/ stride) + 1)
return h, w

def conv_1d_output_shape(l, kernel_size=1, stride=1, pad=0, dilation=1):
"""
Utility function for computing output shape of 1d-convolutions
input:
l: length of input
kernel_size: kernel size of kernel
stride: stride of convolution
pad: padding of convolution
dilation: dilation of convolution

output:
l: lenght of output
"""
if type(kernel_size) is not tuple:
kernel_size = (kernel_size, kernel_size)
l = math.floor( ((l + (2 * pad) - ( dilation * (kernel_size[0] - 1) ) - 1 )/ stride) + 1)
return l

對了,如果還是想了解這個公式在算什麼的,很久以前有寫了一篇[ML]Calculate Parameter Numbers of MLP & CNN,裡面主要是在手把手的介紹2d的Conv參數怎麼算,是用keras,不過shape的介紹那部分或許也可以參考看看。


>