Skip to content

Commit 0d8965a

Browse files
committed
Implementing Inception-v4 with the Keras Functional API: Add three inception blocks & two reduction blocks.
1 parent bb4da55 commit 0d8965a

File tree

4 files changed

+185
-2
lines changed

4 files changed

+185
-2
lines changed

.idea/FromCodingToDeepLearning.iml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Learner: Nguyen Truong Thinh
2+
# Contact me: [email protected] || +84393280504
3+
#
4+
# Topic: Deep Learning with Keras framework (A deep learning library)
5+
# A collection of utilities functions
6+
7+
from keras import regularizers
8+
from keras.initializers import initializers_v1
9+
from keras import backend as be
10+
11+
from keras.models import Model
12+
from keras.layers.convolutional import MaxPooling2D, Conv2D, AveragePooling2D
13+
from keras.layers import Input, Dropout, Dense, Flatten, Activation
14+
from keras.layers.merging import concatenate
15+
from keras.layers.normalization.batch_normalization import BatchNormalization
16+
from keras.optimizers import Adam
17+
18+
# Hyperparameters we can adjust
19+
DROPOUT_PROBABILITY = 0.1
20+
INITIAL_LEARNING_RATE = 0.001
21+
L2_REGULARIZATION_AMOUNT = 0.00004
22+
23+
# Adjust these to match the dimensions of our input image.
24+
IMAGE_HEIGHT = 299
25+
IMAGE_WIDTH = 299
26+
IMAGE_CHANNELS = 3
27+
28+
# Reduce this if this model does not fit on our GPU.
29+
BATCH_SIZE = 24
30+
31+
32+
def build_reduction_b_block(input_tensor):
33+
"""
34+
A reduction block: Transform a 35x35 input into a 17x17 input in an efficient manner.
35+
:param input_tensor: The input image tensor
36+
:return: outputs of the three input branches
37+
"""
38+
# This is the first branch from the left
39+
branch_left = MaxPooling2D((3, 3), strides=(2, 2), padding='valid')(input_tensor)
40+
# This is the middle branch
41+
branch_middle = conv2d_batch_norm_relu(input_tensor, 192 , 1, 1)
42+
branch_middle = conv2d_batch_norm_relu(branch_middle, 192, 3, 3, strides=(2, 2), padding='valid')
43+
# This is the right branch
44+
branch_right = conv2d_batch_norm_relu(input_tensor, 256, 1, 1)
45+
branch_right = conv2d_batch_norm_relu(branch_right, 256, 1, 7)
46+
branch_right = conv2d_batch_norm_relu(branch_right, 320, 7, 1)
47+
branch_right = conv2d_batch_norm_relu(branch_right, 320, 3, 3, strides=(2, 2), padding='valid')
48+
# Concatenate all the results from the three branches
49+
outputs = concatenate([branch_left, branch_middle, branch_right], axis=-1)
50+
return outputs
51+
52+
53+
def build_reduction_a_block(input_tensor):
54+
"""
55+
A reduction block: Transform a 35x35 input into a 17x17 input in an efficient manner.
56+
:param input_tensor: The input image tensor
57+
:return: outputs of the three input branches
58+
"""
59+
# This is the first branch from the left
60+
branch_left = MaxPooling2D((3, 3), strides=(2, 2), padding='valid')(input_tensor)
61+
# This is the middle branch
62+
branch_middle = conv2d_batch_norm_relu(input_tensor, 384, 3, 3, strides=(2, 2), padding='valid')
63+
# This is the right branch
64+
branch_right = conv2d_batch_norm_relu(input_tensor, 192, 1, 1)
65+
branch_right = conv2d_batch_norm_relu(branch_right, 224, 3, 3)
66+
branch_right = conv2d_batch_norm_relu(branch_right, 256, 3, 3, strides=(2, 2), padding='valid')
67+
# Concatenate all the results from the three branches
68+
outputs = concatenate([branch_left, branch_middle, branch_right], axis=-1)
69+
return outputs
70+
71+
72+
def build_inception_c_block(input_tensor):
73+
"""
74+
Create the Inception C block - an Inception-v4 block
75+
:param input_tensor: The input image tensor
76+
:return: outputs of the four input branches
77+
"""
78+
# (384 1x1 convolutions) - This is the first branch for the left
79+
branch_a = conv2d_batch_norm_relu(input_tensor, 256, 1, 1)
80+
# This is the second branch for the left
81+
branch_b = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(input_tensor)
82+
branch_b = conv2d_batch_norm_relu(branch_b, 256, 1, 1)
83+
# This is the third branch from the left
84+
branch_c = conv2d_batch_norm_relu(input_tensor, 384, 1, 1)
85+
branch_c_left = conv2d_batch_norm_relu(branch_c, 256, 1, 3)
86+
branch_c_right = conv2d_batch_norm_relu(branch_c, 256, 3, 1)
87+
# This is the fourth (right-most) branch
88+
branch_d = conv2d_batch_norm_relu(input_tensor, 384, 1, 1)
89+
branch_d = conv2d_batch_norm_relu(branch_d, 448, 1, 3)
90+
branch_d = conv2d_batch_norm_relu(branch_d, 512, 3, 1)
91+
branch_d_left = conv2d_batch_norm_relu(branch_d, 256, 1, 3)
92+
branch_d_right = conv2d_batch_norm_relu(branch_d, 256, 3, 1)
93+
# Concatenate all the results from the four branches
94+
outputs = concatenate([branch_a, branch_b, branch_c_left, branch_c_right, branch_d_left, branch_d_right], axis=-1)
95+
return outputs
96+
97+
98+
def build_inception_b_block(input_tensor):
99+
"""
100+
Create the Inception B block - an Inception-v4 block
101+
:param input_tensor: The input image tensor
102+
:return: outputs of the four input branches
103+
"""
104+
# (384 1x1 convolutions) - This is the first branch for the left
105+
branch_a = conv2d_batch_norm_relu(input_tensor, 384, 1, 1)
106+
# This is the second branch for the left
107+
branch_b = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(input_tensor)
108+
branch_b = conv2d_batch_norm_relu(branch_b, 128, 1, 1)
109+
# This is the third branch from the left
110+
branch_c = conv2d_batch_norm_relu(input_tensor, 192, 1, 1)
111+
branch_c = conv2d_batch_norm_relu(branch_c, 224, 1, 7)
112+
branch_c = conv2d_batch_norm_relu(branch_c, 256, 7, 1)
113+
# This is the fourth (right-most) branch
114+
branch_d = conv2d_batch_norm_relu(input_tensor, 192, 1, 1)
115+
branch_d = conv2d_batch_norm_relu(branch_d, 192, 1, 7)
116+
branch_d = conv2d_batch_norm_relu(branch_d, 224, 7, 1)
117+
branch_d = conv2d_batch_norm_relu(branch_d, 224, 1, 7)
118+
branch_d = conv2d_batch_norm_relu(branch_d, 256, 7, 1)
119+
# Concatenate all the results from the four branches
120+
outputs = concatenate([branch_a, branch_b, branch_c, branch_d], axis=-1)
121+
return outputs
122+
123+
124+
def build_inception_a_block(input_tensor):
125+
"""
126+
Create the Inception A block - an Inception-v4 block
127+
:param input_tensor: The input image tensor
128+
:return: outputs of the four input branches
129+
"""
130+
# (96 1x1 convolutions) - This is the first branch for the left
131+
branch_a = conv2d_batch_norm_relu(input_tensor, 96, 1, 1)
132+
# This is the second branch for the left
133+
branch_b = conv2d_batch_norm_relu(input_tensor, 64, 1, 1)
134+
branch_b = conv2d_batch_norm_relu(branch_b, 96, 3, 3)
135+
# This is the third branch from the left
136+
branch_c = conv2d_batch_norm_relu(input_tensor, 64, 1, 1)
137+
branch_c = conv2d_batch_norm_relu(branch_c, 96, 3, 3)
138+
branch_c = conv2d_batch_norm_relu(branch_c, 96, 3, 3)
139+
# This is the fourth (right-most) branch
140+
branch_d = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(input_tensor)
141+
branch_d = conv2d_batch_norm_relu(branch_d, 96, 1, 1)
142+
# Concatenate all the results from the four branches
143+
outputs = concatenate([branch_a, branch_b, branch_c, branch_d], axis=-1)
144+
return outputs
145+
146+
147+
def conv2d_batch_norm_relu(input_tensor, num_kernels, kernel_rows, kernel_cols, padding='same', strides=(1, 1)):
148+
"""
149+
Create a 2D convolutional layer.
150+
Apply batch normalization to the output of the convolutional layer, and then apply a rectified linear unit
151+
activation function to the normalization output.
152+
:param input_tensor: The input image tensor
153+
:param num_kernels: Convolutional kernels
154+
:param kernel_rows: height dimension
155+
:param kernel_cols: width dimension
156+
:param padding: one of `"valid"` or `"same"` (case-insensitive). `"valid"` means no padding. `"same"`
157+
results in padding with zeros evenly to the left/right or up/down of the input. When `padding="same"` and
158+
`strides=1`, the output has the same size as the input.
159+
:param strides: An integer or tuple/list of 2 integers, specifying the strides of the convolution along the height
160+
and width.
161+
:return: The normalization output of the 2D convolutional layer
162+
"""
163+
x = Conv2D(num_kernels, (kernel_rows, kernel_cols), strides=strides, padding=padding, use_bias=False,
164+
kernel_regularizer=regularizers.l2(L2_REGULARIZATION_AMOUNT),
165+
kernel_initializer=initializers_v1._v1_glorot_normal_initializer(seed=42))(input_tensor)
166+
x = BatchNormalization()(x)
167+
168+
output = Activation('relu')(x)
169+
170+
return output
171+
172+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Learner: Nguyen Truong Thinh
2+
# Contact me: [email protected] || +84393280504
3+
#
4+
# Topic: Deep Learning with Keras framework (A deep learning library)
5+
# Implementing Inception-v4 with the Keras Functional API
6+
7+
from keras import backend as be
8+
9+
# Check the data ordering format (if we're using Theano as the backend => should be channels_first.).
10+
be.set_image_data_format('channels_last')
11+
print(be.image_data_format())

0 commit comments

Comments
 (0)