from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Activation, Flatten, BatchNormalization
from tensorflow.keras.layers import Conv2D, DepthwiseConv2D, AveragePooling2D
from tensorflow.keras.regularizers import l2
#define model
[docs]def MobileNetV1(
input_shape:tuple=(96,96,3), # resized to 96x96 per EEMBC requirement
num_classes=2, # person and non-person
num_filters=8 # normally 32, but running with alpha=.25 per EEMBC requirement
) -> Model:
"""MobileNet v1
.. seealso::
* https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet_v1.md
* https://github.com/SiliconLabs/platform_ml_models/blob/master/eembc/Person_detection/mobilenet_v1_eembc.py
"""
inputs = Input(shape=input_shape)
x = inputs # Keras model uses ZeroPadding2D()
# 1st layer, pure conv
# Keras 2.2 model has padding='valid' and disables bias
x = Conv2D(num_filters,
kernel_size=3,
strides=2,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x) # Keras uses ReLU6 instead of pure ReLU
# 2nd layer, depthwise separable conv
# Filter size is always doubled before the pointwise conv
# Keras uses ZeroPadding2D() and padding='valid'
x = DepthwiseConv2D(kernel_size=3,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
num_filters = 2*num_filters
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 3rd layer, depthwise separable conv
x = DepthwiseConv2D(kernel_size=3,
strides=2,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
num_filters = 2*num_filters
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 4th layer, depthwise separable conv
x = DepthwiseConv2D(kernel_size=3,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 5th layer, depthwise separable conv
x = DepthwiseConv2D(kernel_size=3,
strides=2,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
num_filters = 2*num_filters
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 6th layer, depthwise separable conv
x = DepthwiseConv2D(kernel_size=3,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 7th layer, depthwise separable conv
x = DepthwiseConv2D(kernel_size=3,
strides=2,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
num_filters = 2*num_filters
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 8th-12th layers, identical depthwise separable convs
# 8th
x = DepthwiseConv2D(kernel_size=3,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 9th
x = DepthwiseConv2D(kernel_size=3,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 10th
x = DepthwiseConv2D(kernel_size=3,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 11th
x = DepthwiseConv2D(kernel_size=3,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 12th
x = DepthwiseConv2D(kernel_size=3,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 13th layer, depthwise separable conv
x = DepthwiseConv2D(kernel_size=3,
strides=2,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
num_filters = 2*num_filters
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# 14th layer, depthwise separable conv
x = DepthwiseConv2D(kernel_size=3,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(num_filters,
kernel_size=1,
strides=1,
padding='same',
kernel_initializer='he_normal',
kernel_regularizer=l2(1e-4))(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
# Average pooling, max polling may be used also
# Keras employs GlobalAveragePooling2D
x = AveragePooling2D(pool_size=x.shape[1:3])(x)
#x = MaxPooling2D(pool_size=x.shape[1:3])(x)
# Keras inserts Dropout() and a pointwise Conv2D() here
# We are staying with the paper base structure
# Flatten, FC layer and classify
x = Flatten()(x)
outputs = Dense(num_classes, activation='softmax')(x)
# Instantiate model.
model = Model(inputs=inputs, outputs=outputs)
return model