Skip to content

Commit 47bb12d

Browse files
committed
Receptive Field Calculator
1 parent f9c44e7 commit 47bb12d

File tree

15 files changed

+757
-1
lines changed

15 files changed

+757
-1
lines changed

README.md

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,124 @@
1-
# RF_calculator
1+
## This Project can help you calculating Receptive Field in every layer for CNN model ##
2+
3+
# How to use ?
4+
```python
5+
!pip install rf-calc
6+
7+
8+
from rf_calc import receptive_field
9+
model = models.GoogLeNet().to(device)
10+
image_input_size = 224
11+
RF = receptive_field(model,image_input_size)
12+
```
13+
14+
# Output
15+
```python
16+
Kernel_size : Size of the convolving kernel.
17+
Padding : Zero-padding added to both sides of the input image.
18+
Stride : Stride of the convolution. Default: 1
19+
Input_Img_size : Shape of image as input to the layer.
20+
Output_Img_size : Shape of image as Output from the layer.
21+
Receptive_field : Shape pf Receptive field in the layer.
22+
23+
=======================================Reciptive Field Calculator========================================
24+
| | Kernel_size | Padding | Stride | Input_Img_size | Output_Img_size | Receptive_field |
25+
|---:|:--------------|:----------|---------:|:-----------------|:------------------|:------------------|
26+
| 0 | 7*7 | 3 | 2 | 224*224 | 112*112 | 7*7 |
27+
| 1 | 3*3 | NO | 2 | 112*112 | 55*55 | 11*11 |
28+
| 2 | 1*1 | NO | 1 | 55*55 | 55*55 | 11*11 |
29+
| 3 | 3*3 | 1 | 1 | 55*55 | 55*55 | 19*19 |
30+
| 4 | 3*3 | NO | 2 | 55*55 | 27*27 | 27*27 |
31+
| 5 | 1*1 | NO | 1 | 27*27 | 27*27 | 27*27 |
32+
| 6 | 1*1 | NO | 1 | 27*27 | 27*27 | 27*27 |
33+
| 7 | 3*3 | 1 | 1 | 27*27 | 27*27 | 43*43 |
34+
| 8 | 1*1 | NO | 1 | 27*27 | 27*27 | 43*43 |
35+
| 9 | 3*3 | 1 | 1 | 27*27 | 27*27 | 59*59 |
36+
| 10 | 3*3 | 1 | 1 | 27*27 | 27*27 | 75*75 |
37+
| 11 | 1*1 | NO | 1 | 27*27 | 27*27 | 75*75 |
38+
| 12 | 1*1 | NO | 1 | 27*27 | 27*27 | 75*75 |
39+
| 13 | 1*1 | NO | 1 | 27*27 | 27*27 | 75*75 |
40+
| 14 | 3*3 | 1 | 1 | 27*27 | 27*27 | 91*91 |
41+
| 15 | 1*1 | NO | 1 | 27*27 | 27*27 | 91*91 |
42+
| 16 | 3*3 | 1 | 1 | 27*27 | 27*27 | 107*107 |
43+
| 17 | 3*3 | 1 | 1 | 27*27 | 27*27 | 123*123 |
44+
| 18 | 1*1 | NO | 1 | 27*27 | 27*27 | 123*123 |
45+
| 19 | 3*3 | NO | 2 | 27*27 | 13*13 | 139*139 |
46+
| 20 | 1*1 | NO | 1 | 13*13 | 13*13 | 139*139 |
47+
| 21 | 1*1 | NO | 1 | 13*13 | 13*13 | 139*139 |
48+
| 22 | 3*3 | 1 | 1 | 13*13 | 13*13 | 171*171 |
49+
| 23 | 1*1 | NO | 1 | 13*13 | 13*13 | 171*171 |
50+
| 24 | 3*3 | 1 | 1 | 13*13 | 13*13 | 203*203 |
51+
| 25 | 3*3 | 1 | 1 | 13*13 | 13*13 | 235*235 |
52+
| 26 | 1*1 | NO | 1 | 13*13 | 13*13 | 235*235 |
53+
| 27 | 1*1 | NO | 1 | 13*13 | 13*13 | 235*235 |
54+
| 28 | 1*1 | NO | 1 | 13*13 | 13*13 | 235*235 |
55+
| 29 | 3*3 | 1 | 1 | 13*13 | 13*13 | 267*267 |
56+
| 30 | 1*1 | NO | 1 | 13*13 | 13*13 | 267*267 |
57+
| 31 | 3*3 | 1 | 1 | 13*13 | 13*13 | 299*299 |
58+
| 32 | 3*3 | 1 | 1 | 13*13 | 13*13 | 331*331 |
59+
| 33 | 1*1 | NO | 1 | 13*13 | 13*13 | 331*331 |
60+
| 34 | 1*1 | NO | 1 | 13*13 | 13*13 | 331*331 |
61+
| 35 | 1*1 | NO | 1 | 13*13 | 13*13 | 331*331 |
62+
| 36 | 3*3 | 1 | 1 | 13*13 | 13*13 | 363*363 |
63+
| 37 | 1*1 | NO | 1 | 13*13 | 13*13 | 363*363 |
64+
| 38 | 3*3 | 1 | 1 | 13*13 | 13*13 | 395*395 |
65+
| 39 | 3*3 | 1 | 1 | 13*13 | 13*13 | 427*427 |
66+
| 40 | 1*1 | NO | 1 | 13*13 | 13*13 | 427*427 |
67+
| 41 | 1*1 | NO | 1 | 13*13 | 13*13 | 427*427 |
68+
| 42 | 1*1 | NO | 1 | 13*13 | 13*13 | 427*427 |
69+
| 43 | 3*3 | 1 | 1 | 13*13 | 13*13 | 459*459 |
70+
| 44 | 1*1 | NO | 1 | 13*13 | 13*13 | 459*459 |
71+
| 45 | 3*3 | 1 | 1 | 13*13 | 13*13 | 491*491 |
72+
| 46 | 3*3 | 1 | 1 | 13*13 | 13*13 | 523*523 |
73+
| 47 | 1*1 | NO | 1 | 13*13 | 13*13 | 523*523 |
74+
| 48 | 1*1 | NO | 1 | 13*13 | 13*13 | 523*523 |
75+
| 49 | 1*1 | NO | 1 | 13*13 | 13*13 | 523*523 |
76+
| 50 | 3*3 | 1 | 1 | 13*13 | 13*13 | 555*555 |
77+
| 51 | 1*1 | NO | 1 | 13*13 | 13*13 | 555*555 |
78+
| 52 | 3*3 | 1 | 1 | 13*13 | 13*13 | 587*587 |
79+
| 53 | 3*3 | 1 | 1 | 13*13 | 13*13 | 619*619 |
80+
| 54 | 1*1 | NO | 1 | 13*13 | 13*13 | 619*619 |
81+
| 55 | 2*2 | NO | 2 | 13*13 | 6*6 | 635*635 |
82+
| 56 | 1*1 | NO | 1 | 6*6 | 6*6 | 635*635 |
83+
| 57 | 1*1 | NO | 1 | 6*6 | 6*6 | 635*635 |
84+
| 58 | 3*3 | 1 | 1 | 6*6 | 6*6 | 699*699 |
85+
| 59 | 1*1 | NO | 1 | 6*6 | 6*6 | 699*699 |
86+
| 60 | 3*3 | 1 | 1 | 6*6 | 6*6 | 763*763 |
87+
| 61 | 3*3 | 1 | 1 | 6*6 | 6*6 | 827*827 |
88+
| 62 | 1*1 | NO | 1 | 6*6 | 6*6 | 827*827 |
89+
| 63 | 1*1 | NO | 1 | 6*6 | 6*6 | 827*827 |
90+
| 64 | 1*1 | NO | 1 | 6*6 | 6*6 | 827*827 |
91+
| 65 | 3*3 | 1 | 1 | 6*6 | 6*6 | 891*891 |
92+
| 66 | 1*1 | NO | 1 | 6*6 | 6*6 | 891*891 |
93+
| 67 | 3*3 | 1 | 1 | 6*6 | 6*6 | 955*955 |
94+
| 68 | 3*3 | 1 | 1 | 6*6 | 6*6 | 1019*1019 |
95+
| 69 | 1*1 | NO | 1 | 6*6 | 6*6 | 1019*1019 |
96+
| 70 | 1*1 | NO | 1 | 6*6 | 6*6 | 1019*1019 |
97+
| 71 | 1*1 | NO | 1 | 6*6 | 6*6 | 1019*1019 |
98+
=========================================================================================================
99+
```
100+
101+
# About Receptive Field
102+
103+
What is Receptive Field ?
104+
105+
1> Local Receptive field
106+
Local receptive field is present in every layer. Local receptive will be the size of kernel used in the layer .For example if we have an image of size 19x19 and we are applying a 3x3 metric then local receptive field will be 3x3 in first layer.
107+
108+
2> Global Receptive field
109+
At every layer the part of image our kernel can see is global receptive field .For a 3x3 kernel convolution global receptive field will increase by 2 units ( there is a mathematical formula that we can cover in later chapters ). It means if you see the below code in every convolution step our model will be able to see 2 pixel more in each side of image .
110+
111+
112+
Input image => kernel shape => Output Image -> local Receptive field -> Global Receptive field
113+
19x19 => 3x3 => 17x17 -> 3x3 ->3x3
114+
17x17 => 3x3 => 15x15 ->3x3 ->5x5
115+
15x15 => 3x3 => 13x13 ->3x3 ->7x7
116+
13x13 => 3x3 => 11x11 ->3x3 ->9x9
117+
11x11 => 3x3 => 9x9 ->3x3 ->11x11
118+
9x9 => 3x3 => 7x7 ->3x3 ->13x13
119+
7x7 => 3x3 => 5x5 ->3x3 ->15x15
120+
5x5 => 3x3 => 3x3 ->3x3 ->17x17
121+
3x3 => 3x3 => 1x1 ->3x3 ->19x19
122+
123+
Read the article for better understanding.
124+
https://medium.com/@data.pruthiraj/building-blocks-of-computer-vision-and-cnn-f5acdbf3c0b7

__pycache__/rf_calc.cpython-38.pyc

2.73 KB
Binary file not shown.

build/lib/rf_calc.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import pandas as pd
2+
import tabulate
3+
4+
#OutPut Image shape calculator
5+
6+
def ch_out(ch_in,pad,kern,strid):
7+
CH_out =((ch_in+2*pad - kern)/strid)+1
8+
return int(CH_out)
9+
10+
#Jump calculator
11+
def jp_out(jp_in,strid):
12+
JP_out = jp_in*strid
13+
return int(JP_out)
14+
15+
#Receptive field out calculator
16+
def Rf_out(rf_in,kern,jump_in):
17+
RF_out = rf_in+(kern-1)*jump_in
18+
return int(RF_out)
19+
20+
21+
# Returns the Kernel Size,Stride Size, Padding Size
22+
def get_values(lar):
23+
st=[]
24+
pd = []
25+
lar = str(lar)
26+
for part in lar.split(' '):
27+
28+
if "kernel_size" in part[0:12]:
29+
ker= part[-2]
30+
if "MaxPool2d" in part:
31+
ker = part[-2]
32+
33+
if 'AdaptiveAvgPool2d' in part:
34+
ker = [i[-2] for i in part.split(' ') if 'output_size' in i][0]
35+
s = 1
36+
37+
if 'stride' in part[0:7]:
38+
s = part[-2]
39+
40+
if 'padding' in part:
41+
pd.append(int(part[-2]))
42+
else:
43+
pd.append(0)
44+
45+
p = max(pd)
46+
return int(ker),int(s),int(p)
47+
48+
def model_df(model_object):
49+
# xml = dict2xml(model_object._dir_)
50+
model_layers = str(model_object.__dir__)
51+
search_keywords = {' MaxPoo',' Conv2d'}
52+
model_layers = str(model_object)
53+
req_layers = []
54+
for part in model_layers.split(':'):
55+
if part[0:7] in search_keywords:
56+
req_layers.append(str(part))
57+
if part[0:18] == ' AdaptiveAvgPool2d':
58+
req_layers.append(str(part))
59+
60+
df = pd.DataFrame(req_layers,columns = ['layers'])
61+
return df
62+
63+
64+
65+
def receptive_field(model_obj,input_image,jump_in = 1,rf_in =1 ,):
66+
67+
channel_in = input_image
68+
c = channel_in
69+
r = 1
70+
j = 1
71+
72+
L = []
73+
K= []
74+
P = []
75+
S = []
76+
c_in = []
77+
C_out = []
78+
R_out = []
79+
80+
model_data = model_df(model_obj)
81+
82+
for i in model_data.layers:
83+
kernel,stride,padding = get_values(i)
84+
# print (kernel,padding,stride)
85+
86+
channel_out = ch_out(channel_in,padding,kernel,stride)
87+
jump_out =jp_out(jump_in,stride)
88+
rf_out= Rf_out(rf_in,kernel,jump_in)
89+
90+
# L.append('Layer_'+str(i))
91+
# L.append(name)
92+
K.append(str(kernel)+'*'+str(kernel))
93+
P.append(['NO' if padding == 0 else padding][0])
94+
S.append(stride)
95+
c_in.append(str(c)+ '*' + str(c))
96+
C_out.append(str(abs(channel_out))+ '*'+ str(abs(channel_out)))
97+
R_out.append(str(rf_out)+ '*'+ str(rf_out))
98+
99+
100+
rf_in =r = rf_out
101+
jump_in=j = jump_out
102+
channel_in=c = channel_out
103+
104+
RF_graph = {'Kernel_size':K,'Padding':P,'Stride':S,'Input_Img_size':c_in,'Output_Img_size':C_out,'Receptive_field':R_out}
105+
RF = pd.DataFrame(RF_graph)
106+
107+
print ("=======================================Reciptive Field Calculator========================================")
108+
print(RF.to_markdown())
109+
print ("=========================================================================================================")
110+
return RF
111+
112+
# error = receptive_field(model,input_image = 28)
113+
114+
# print (['No Error' if error == 0 else 'Somethign went wrong'][0])

dist/rf_calc-0.0.7-py3-none-any.whl

3.99 KB
Binary file not shown.

dist/rf_calc-0.0.7.tar.gz

4.99 KB
Binary file not shown.

requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
numpy==1.19.4
2+
pandas==1.1.5
3+
tabulate==0.8.9

rf_calc.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import pandas as pd
2+
import tabulate
3+
4+
#OutPut Image shape calculator
5+
6+
def ch_out(ch_in,pad,kern,strid):
7+
CH_out =((ch_in+2*pad - kern)/strid)+1
8+
return int(CH_out)
9+
10+
#Jump calculator
11+
def jp_out(jp_in,strid):
12+
JP_out = jp_in*strid
13+
return int(JP_out)
14+
15+
#Receptive field out calculator
16+
def Rf_out(rf_in,kern,jump_in):
17+
RF_out = rf_in+(kern-1)*jump_in
18+
return int(RF_out)
19+
20+
21+
# Returns the Kernel Size,Stride Size, Padding Size
22+
def get_values(lar):
23+
st=[]
24+
pd = []
25+
lar = str(lar)
26+
for part in lar.split(' '):
27+
28+
if "kernel_size" in part[0:12]:
29+
ker= part[-2]
30+
if "MaxPool2d" in part:
31+
ker = part[-2]
32+
33+
if 'AdaptiveAvgPool2d' in part:
34+
ker = [i[-2] for i in part.split(' ') if 'output_size' in i][0]
35+
s = 1
36+
37+
if 'stride' in part[0:7]:
38+
s = part[-2]
39+
40+
if 'padding' in part:
41+
pd.append(int(part[-2]))
42+
else:
43+
pd.append(0)
44+
45+
p = max(pd)
46+
return int(ker),int(s),int(p)
47+
48+
def model_df(model_object):
49+
# xml = dict2xml(model_object._dir_)
50+
model_layers = str(model_object.__dir__)
51+
search_keywords = {' MaxPoo',' Conv2d'}
52+
model_layers = str(model_object)
53+
req_layers = []
54+
for part in model_layers.split(':'):
55+
if part[0:7] in search_keywords:
56+
req_layers.append(str(part))
57+
if part[0:18] == ' AdaptiveAvgPool2d':
58+
req_layers.append(str(part))
59+
60+
df = pd.DataFrame(req_layers,columns = ['layers'])
61+
return df
62+
63+
64+
65+
def receptive_field(model_obj,input_image,jump_in = 1,rf_in =1 ,):
66+
67+
channel_in = input_image
68+
c = channel_in
69+
r = 1
70+
j = 1
71+
72+
L = []
73+
K= []
74+
P = []
75+
S = []
76+
c_in = []
77+
C_out = []
78+
R_out = []
79+
80+
model_data = model_df(model_obj)
81+
82+
for i in model_data.layers:
83+
kernel,stride,padding = get_values(i)
84+
# print (kernel,padding,stride)
85+
86+
channel_out = ch_out(channel_in,padding,kernel,stride)
87+
jump_out =jp_out(jump_in,stride)
88+
rf_out= Rf_out(rf_in,kernel,jump_in)
89+
90+
# L.append('Layer_'+str(i))
91+
# L.append(name)
92+
K.append(str(kernel)+'*'+str(kernel))
93+
P.append(['NO' if padding == 0 else padding][0])
94+
S.append(stride)
95+
c_in.append(str(c)+ '*' + str(c))
96+
C_out.append(str(abs(channel_out))+ '*'+ str(abs(channel_out)))
97+
R_out.append(str(rf_out)+ '*'+ str(rf_out))
98+
99+
100+
rf_in =r = rf_out
101+
jump_in=j = jump_out
102+
channel_in=c = channel_out
103+
104+
RF_graph = {'Kernel_size':K,'Padding':P,'Stride':S,'Input_Img_size':c_in,'Output_Img_size':C_out,'Receptive_field':R_out}
105+
RF = pd.DataFrame(RF_graph)
106+
107+
print ("=======================================Reciptive Field Calculator========================================")
108+
print(RF.to_markdown())
109+
print ("=========================================================================================================")
110+
return RF
111+
112+
# error = receptive_field(model,input_image = 28)
113+
114+
# print (['No Error' if error == 0 else 'Somethign went wrong'][0])

setup.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import os
2+
from os import path
3+
from setuptools import setup
4+
5+
# read the contents of your README file
6+
this_directory = path.abspath(path.dirname(__file__))
7+
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
8+
long_description = f.read()
9+
10+
setup(
11+
name = 'rf_calc',
12+
author='Pruthiraj Jayasingh',
13+
author_email='pruthirajjayasingh.4u@gmail.com',
14+
version = '0.0.7',
15+
install_requires =['numpy>=1.19.4','pandas>=1.1.5','tabulate>=0.8.9'] ,
16+
description = 'Often we spend lots of time calculating the Receptive field of a CNN model.This Module can calculate the receptive field, Output image size from a model object',
17+
long_description=long_description,
18+
long_description_content_type='text/markdown',
19+
py_modules = ["rf_calc"],
20+
package_dir = {'':'src'},
21+
classifiers= [
22+
"Programming Language :: Python :: 3",
23+
"Programming Language :: Python :: 3.6",
24+
"Programming Language :: Python :: 3.7",
25+
"Programming Language :: Python :: 3.8",
26+
"License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",
27+
"Operating System :: OS Independent",],
28+
)

0 commit comments

Comments
 (0)