Skip to content

Commit c234e26

Browse files
committed
Added good CNN workload and external way to visualize receptive field.
attempted several CNN apporaches. Keras work best.
1 parent 00676b9 commit c234e26

File tree

4 files changed

+259
-6
lines changed

4 files changed

+259
-6
lines changed

CNN.py

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
validation_size = 0.333333
2323

2424
# Batch size
25-
batch_size = 16
25+
batch_size = 8
2626

2727
# Image related properties
2828
num_channels = 3 # color chanels?
@@ -75,16 +75,28 @@
7575
"""
7676

7777
# Layer Paramemters:
78-
L1_filter = 32
78+
L1_filter = 128
7979
L1_convSize = 3
8080

81-
L2_filter = 32
81+
L2_filter = 64
8282
L2_convSize = 3
8383

84-
L3_filter = 64
84+
L3_filter = 32
8585
L3_convSize = 3
8686

87-
FC1_size = 128
87+
L4_filter = 16
88+
L4_convSize = 3
89+
90+
L5_filter = 8
91+
L5_convSize = 3
92+
93+
L6_filter = 4
94+
L6_convSize = 3
95+
96+
L7_filter = 2
97+
L7_convSize = 3
98+
99+
FC1_size = 64
88100

89101

90102
"""
@@ -107,8 +119,29 @@
107119
conv_filter_size = L3_convSize,
108120
num_filters = L3_filter)
109121

122+
conv_stack4 = tfl.create_convolutional_stack(input = conv_stack3,
123+
num_input_channels = L3_filter,
124+
conv_filter_size = L4_convSize,
125+
num_filters = L4_filter)
126+
127+
conv_stack5 = tfl.create_convolutional_stack(input = conv_stack4,
128+
num_input_channels = L4_filter,
129+
conv_filter_size = L5_convSize,
130+
num_filters = L5_filter)
131+
132+
conv_stack6 = tfl.create_convolutional_stack(input = conv_stack5,
133+
num_input_channels = L5_filter,
134+
conv_filter_size = L6_convSize,
135+
num_filters = L6_filter)
136+
137+
conv_stack7 = tfl.create_convolutional_stack(input = conv_stack6,
138+
num_input_channels = L6_filter,
139+
conv_filter_size = L7_convSize,
140+
num_filters = L7_filter)
141+
142+
110143
# Building the Flat Layers
111-
layer_flat = tfl.create_flatten_layer(conv_stack3)
144+
layer_flat = tfl.create_flatten_layer(conv_stack7)
112145

113146
# Building the Fully Connected Layers
114147
fc_stack1 = tfl.create_fc_stack(input = layer_flat,

CNN2.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import keras
2+
from keras.models import Sequential
3+
from keras.layers import Dense, Dropout, Flatten
4+
from keras.layers import Conv2D, MaxPooling2D
5+
import numpy as np
6+
7+
batch size = 128
8+
num_classes = 2
9+
epochs = 12
10+
11+
# input image dimensions
12+
img_rows, img_cols = 500, 500
13+
channels = 3
14+
fashion_mnist = keras.datasets.fashion_mnist
15+
16+
# Data split:
17+
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
18+
19+
x_train = x_train.reshape(300, img_rows, img_cols, 1)
20+
x_test = x_test.rehapse(300,img_rows, img_cols,1 )
21+
22+
23+
# Binary class matrix: y = [0, 1] would be no-marker when the classes are [marker, no-marker]
24+
y_train = keras.utils.to_categorical(y_train, num_classes)
25+
y_test = keras.utils.to_categorical(y_test, num_classes)
26+
27+
model = Sequential()
28+
model.add(Conv2D(filters=32,
29+
kernel_size=(3,3),
30+
activation='relu',
31+
input_shape=(500,500,1)))
32+
model.add(MaxPooling2D(pool_size=(2,2),
33+
strides=2))
34+
model.add(Conv2D(filters=32,
35+
kernel_size=(3,3),
36+
activation='relu'))
37+
model.add(MaxPooling2D(pool_size=(2,2),
38+
strides=2))
39+
model.add(Dropout(0.25))
40+
model.add(Flatten())
41+
model.add(Dense(128, activation='relu'))
42+
model.add(Dropout(0.5))
43+
model.add(Dense(num_classes, activation='softmax'))
44+
45+
model.compile(loss=keras.losses.categorical_crossentropy,
46+
optimizer=keras.optimizers.adam,
47+
metric=['accuracy']
48+
)
49+
model.fit(x_train,y_train,
50+
batch_size=batch_size,
51+
epochs=epochs,
52+
verbose=1,
53+
validation_data=(x_test,y_test))
54+
score=model.evaluat(x_test,y_test,verbose=0)
55+
print('Test loss:', score[0])
56+
print('Test accurayc:', score[1])

CNN3.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
from keras.models import Sequential
2+
from keras.layers import Dense, Conv2D, MaxPooling2D, Dropout, Flatten, Activation
3+
from keras.preprocessing.image import ImageDataGenerator
4+
from keras.callbacks import TensorBoard
5+
import keras
6+
import os
7+
from PythonUtils.file import unique_name
8+
def load_data_and_run(model,input_shape, TBCallBack):
9+
train_data_loader = ImageDataGenerator()
10+
train_data = train_data_loader.flow_from_directory(r"E:\Gitlab\MarkerTrainer\data_train",
11+
target_size=(input_shape,input_shape),
12+
batch_size=128,
13+
class_mode='binary')
14+
validation_data_loader = ImageDataGenerator()
15+
validation_data = validation_data_loader.flow_from_directory(r"E:\Gitlab\MarkerTrainer\data_validate",
16+
target_size=(input_shape, input_shape),
17+
batch_size=128,
18+
class_mode='binary')
19+
model.fit_generator(
20+
train_data,
21+
steps_per_epoch=2500,
22+
epochs=50,
23+
validation_data=validation_data,
24+
validation_steps=1250,
25+
#callbacks=TBCallBack
26+
)
27+
model.save(os.path.join(r'E:\Gitlab\MarkerTrainer\models\\', unique_name()))
28+
29+
def createModel(input_shape, output_classes):
30+
model = Sequential()
31+
model.add(Conv2D(16, (3, 3), padding='same', activation='relu', input_shape=(input_shape, input_shape, 3)))
32+
model.add(Conv2D(16, (3, 3), activation='relu'))
33+
model.add(MaxPooling2D(pool_size=(2, 2)))
34+
model.add(Dropout(0.25))
35+
36+
model.add(Conv2D(32, (3, 3), padding='same', activation='relu'))
37+
model.add(Conv2D(32, (3, 3), activation='relu'))
38+
model.add(MaxPooling2D(pool_size=(2, 2)))
39+
model.add(Dropout(0.25))
40+
41+
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
42+
model.add(Conv2D(64, (3, 3), activation='relu'))
43+
model.add(MaxPooling2D(pool_size=(2, 2)))
44+
model.add(Dropout(0.25))
45+
46+
model.add(Conv2D(128, (3, 3), padding='same', activation='relu'))
47+
model.add(Conv2D(128, (3, 3), activation='relu'))
48+
model.add(MaxPooling2D(pool_size=(2, 2)))
49+
model.add(Dropout(0.25))
50+
51+
model.add(Conv2D(256, (3, 3), padding='same', activation='relu'))
52+
model.add(Conv2D(256, (3, 3), activation='relu'))
53+
model.add(MaxPooling2D(pool_size=(2, 2)))
54+
model.add(Dropout(0.25))
55+
56+
model.add(Flatten())
57+
model.add(Dense(512, activation='relu'))
58+
model.add(Dropout(0.5))
59+
model.add(Dense(output_classes))
60+
model.add(Activation('softmax'))
61+
62+
# Param: 276138
63+
64+
return model
65+
66+
if __name__ =="__main__":
67+
from time import time
68+
model1 = createModel(128, 2) # downsize to 128
69+
model1.compile(loss="sparse_categorical_crossentropy", optimizer="adam")
70+
TBCallBack = TensorBoard(log_dir=r'E:\Gitlab\MarkerTrainer\logs',
71+
histogram_freq=0,
72+
batch_size=32,
73+
write_graph=True,
74+
write_grads=True,
75+
write_images=True,
76+
embeddings_freq=0,
77+
embeddings_layer_names=None,
78+
embeddings_metadata=None,
79+
embeddings_data=None,
80+
update_freq='epoch')
81+
82+
load_data_and_run(model1, 128, TBCallBack)

ReceptiveFieldCalculator.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# [filter size, stride, padding]
2+
# Assume the two dimensions are the same
3+
# Each kernel requires the following parameters:
4+
# - k_i: kernel size
5+
# - s_i: stride
6+
# - p_i: padding (if padding is uneven, right padding will higher than left padding; "SAME" option in tensorflow)
7+
#
8+
# Each layer i requires the following parameters to be fully represented:
9+
# - n_i: number of feature (data layer has n_1 = imagesize )
10+
# - j_i: distance (projected to image pixel distance) between center of two adjacent features
11+
# - r_i: receptive field of a feature in layer i
12+
# - start_i: position of the first feature's receptive field in layer i (idx start from 0, negative means the center fall into padding)
13+
14+
# Source: https://medium.com/mlreview/a-guide-to-receptive-field-arithmetic-for-convolutional-neural-networks-e0f514068807
15+
16+
import math
17+
18+
convnet = [[10, 4, 0], # [filter size, stride, padding]
19+
[3, 2, 0],
20+
[5, 1, 2],
21+
[3, 2, 0],
22+
[3, 1, 1],
23+
[3, 1, 1],
24+
[3, 1, 1],
25+
[3, 2, 0],
26+
[6, 1, 0],
27+
[1, 1, 0]]
28+
layer_names = ['conv1', 'pool1', 'conv2', 'pool2', 'conv3', 'conv4', 'conv5', 'pool5', 'fc6-conv', 'fc7-conv']
29+
imsize = 500
30+
31+
32+
def outFromIn(conv, layerIn):
33+
n_in = layerIn[0]
34+
j_in = layerIn[1]
35+
r_in = layerIn[2]
36+
start_in = layerIn[3]
37+
k = conv[0]
38+
s = conv[1]
39+
p = conv[2]
40+
41+
n_out = math.floor((n_in - k + 2 * p) / s) + 1
42+
actualP = (n_out - 1) * s - n_in + k
43+
pR = math.ceil(actualP / 2)
44+
pL = math.floor(actualP / 2)
45+
46+
j_out = j_in * s
47+
r_out = r_in + (k - 1) * j_in
48+
start_out = start_in + ((k - 1) / 2 - pL) * j_in
49+
return n_out, j_out, r_out, start_out
50+
51+
52+
def printLayer(layer, layer_name):
53+
print(layer_name + ":")
54+
print("\t n features: %s \n \t jump: %s \n \t receptive size: %s \t start: %s " % (
55+
layer[0], layer[1], layer[2], layer[3]))
56+
57+
58+
layerInfos = []
59+
if __name__ == '__main__':
60+
# first layer is the data layer (image) with n_0 = image size; j_0 = 1; r_0 = 1; and start_0 = 0.5
61+
print("-------Net summary------")
62+
currentLayer = [imsize, 1, 1, 0.5]
63+
printLayer(currentLayer, "input image")
64+
for i in range(len(convnet)):
65+
currentLayer = outFromIn(convnet[i], currentLayer)
66+
layerInfos.append(currentLayer)
67+
printLayer(currentLayer, layer_names[i])
68+
print("------------------------")
69+
layer_name = "conv1"
70+
layer_idx = layer_names.index(layer_name)
71+
idx_x = 99 #int(raw_input("index of the feature in x dimension (from 0)"))
72+
idx_y = 98 #int(raw_input("index of the feature in y dimension (from 0)"))
73+
74+
n = layerInfos[layer_idx][0]
75+
j = layerInfos[layer_idx][1]
76+
r = layerInfos[layer_idx][2]
77+
start = layerInfos[layer_idx][3]
78+
assert (idx_x < n)
79+
assert (idx_y < n)
80+
81+
print("receptive field: (%s, %s)" % (r, r))
82+
print("center: (%s, %s)" % (start + idx_x * j, start + idx_y * j))

0 commit comments

Comments
 (0)