(base, num_classes)
return model, pass2_lr, preprocessor, BATCH_SIZE, FREEZE
NB: Do not use "max" pooling in any model. It has an op (REDUCE_MAX) than cannot be quantized.

    dropout ref: # http://jmlr.org/papers/volume15/srivastava14a/srivastava14a.pdf
NB: Do not use "max" pooling in any model. It has an op (REDUCE_MAX) than cannot be quantized.
NB : Do not use max pooling in any model . It has an op ( REDUCE_MAX ) than cannot be quantized .
def create_model(base, num_classes):
    """
    NB: Do not use "max" pooling in any model. It has an op (REDUCE_MAX) than cannot be quantized.

    dropout ref: # http://jmlr.org/papers/volume15/srivastava14a/srivastava14a.pdf
    """
    logger.info('Creating model with cnn base: {}'.format(base))
    if base == 'InceptionResNetV2': 
        # Setup hyperparamters.
        BATCH_SIZE = 32
        DENSE_UNITS = 128
        DROPOUT = 0.2
        LEARNING_RATE = 1e-4
        L2_PENALTY = 1e-4
        FREEZE = 200 # Freeze all layers less than this (InceptionResNetV2 has 780 layers).

        logger.info('batch size: {}, dense units {}, dropout: {}'
            .format(BATCH_SIZE, DENSE_UNITS, DROPOUT))
        logger.info('learning rate: {}, l2 penalty: {}, freeze {}'
            .format(LEARNING_RATE, L2_PENALTY, FREEZE))

        base_model = tf.keras.applications.inception_resnet_v2.InceptionResNetV2(weights='imagenet',
            include_top=False,
            pooling='avg',
            input_shape=(299,299,3))

        # Uncomment below to modify base model kernel regularizers for fine-tuning.
        # This may improve accuracy in some cases at expense of training time. 
        #add_regularization(base_model, tf.keras.regularizers.l2(L2_PENALTY))

        base_model.trainable = False

        model = tf.keras.models.Sequential()
        model.add(base_model)
        model.add(tf.keras.layers.Dense(DENSE_UNITS, activation='relu',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))
        model.add(tf.keras.layers.Dropout(rate=DROPOUT))
        model.add(tf.keras.layers.Dense(num_classes, activation='softmax',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))

        model.compile(loss=tf.keras.losses.CategoricalCrossentropy(label_smoothing=0.1),
            optimizer=tf.keras.optimizers.Adam(lr=LEARNING_RATE),
            metrics=['accuracy', tf.keras.metrics.Precision(),
                tf.keras.metrics.Recall()])

        pass2_lr = LEARNING_RATE/10
        preprocessor = tf.keras.applications.inception_resnet_v2.preprocess_input
    elif base == 'NASNetLarge': 
        # Setup hyperparamters.
        BATCH_SIZE = 16 # use caution increasing as this will cause OOM
        DENSE_UNITS = 128
        DROPOUT = 0.2
        LEARNING_RATE = 1e-4
        L2_PENALTY = 1e-4
        FREEZE = 266 # Freeze all layers less than this (NASNetLarge has 1039 layers).

        logger.info('batch size: {}, dense units {}, dropout: {}'
            .format(BATCH_SIZE, DENSE_UNITS, DROPOUT))
        logger.info('learning rate: {}, l2 penalty: {}, freeze {}'
            .format(LEARNING_RATE, L2_PENALTY, FREEZE))

        base_model = tf.keras.applications.nasnet.NASNetLarge(weights='imagenet',
            include_top=False,
            pooling='max', # won't complie on the edge tpu anyhow...
            input_shape=(331,331,3))

        base_model.trainable = False

        model = tf.keras.models.Sequential()
        model.add(base_model)
        model.add(tf.keras.layers.Dense(DENSE_UNITS, activation='relu',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))
        model.add(tf.keras.layers.Dropout(rate=DROPOUT))
        model.add(tf.keras.layers.Dense(num_classes, activation='softmax',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))

        model.compile(loss=tf.keras.losses.CategoricalCrossentropy(label_smoothing=0.1),
            optimizer=tf.keras.optimizers.Adam(lr=LEARNING_RATE),
            metrics=['accuracy', tf.keras.metrics.Precision(),
                tf.keras.metrics.Recall()])

        pass2_lr = LEARNING_RATE/10
        preprocessor = tf.keras.applications.nasnet.preprocess_input
    elif base == 'NASNetMobile': 
        # Setup hyperparamters.
        BATCH_SIZE = 32
        DENSE_UNITS = 128
        DROPOUT = 0.2
        LEARNING_RATE = 1e-4
        L2_PENALTY = 1e-4
        FREEZE = 200 # Freeze all layers less than this (NASNetMobile has 769 layers).

        logger.info('batch size: {}, dense units {}, dropout: {}'
            .format(BATCH_SIZE, DENSE_UNITS, DROPOUT))
        logger.info('learning rate: {}, l2 penalty: {}, freeze {}'
            .format(LEARNING_RATE, L2_PENALTY, FREEZE))

        base_model = tf.keras.applications.nasnet.NASNetMobile(weights='imagenet',
            include_top=False,
            pooling='avg',
            input_shape=(224,224,3))

        base_model.trainable = False

        model = tf.keras.models.Sequential()
        model.add(base_model)
        model.add(tf.keras.layers.Dense(DENSE_UNITS, activation='relu',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))
        model.add(tf.keras.layers.Dropout(rate=DROPOUT))
        model.add(tf.keras.layers.Dense(num_classes, activation='softmax',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))

        model.compile(loss=tf.keras.losses.CategoricalCrossentropy(label_smoothing=0.1),
            optimizer=tf.keras.optimizers.Adam(lr=LEARNING_RATE),
            metrics=['accuracy', tf.keras.metrics.Precision(),
                tf.keras.metrics.Recall()])

        pass2_lr = LEARNING_RATE/10
        preprocessor = tf.keras.applications.nasnet.preprocess_input
    elif base == 'MobileNetV2': 
        # Setup hyperparamters.
        BATCH_SIZE = 32
        DENSE_UNITS = 128
        DROPOUT = 0.2
        LEARNING_RATE = 5e-4
        L2_PENALTY = 1e-4
        FREEZE = 75 # Freeze all layers less than this (MobileNetV2 has 155 layers).

        logger.info('batch size: {}, dense units {}, dropout: {}'
            .format(BATCH_SIZE, DENSE_UNITS, DROPOUT))
        logger.info('learning rate: {}, l2 penalty: {}, freeze {}'
            .format(LEARNING_RATE, L2_PENALTY, FREEZE))

        base_model = tf.keras.applications.mobilenet_v2.MobileNetV2(weights='imagenet',
            include_top=False,
            pooling='avg',
            input_shape=(224,224,3))

        # Uncomment below to modify base model kernel regularizers for fine-tuning.
        # This may improve accuracy in some cases at expense of training time. 
        #add_regularization(base_model, tf.keras.regularizers.l2(L2_PENALTY))

        base_model.trainable = False

        model = tf.keras.models.Sequential()
        model.add(base_model)
        model.add(tf.keras.layers.Dense(DENSE_UNITS, activation='relu',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))
        model.add(tf.keras.layers.Dropout(rate=DROPOUT))
        model.add(tf.keras.layers.Dense(num_classes, activation='softmax',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))

        model.compile(loss=tf.keras.losses.CategoricalCrossentropy(label_smoothing=0.1),
            optimizer=tf.keras.optimizers.Adam(lr=LEARNING_RATE),
            metrics=['accuracy', tf.keras.metrics.Precision(),
                tf.keras.metrics.Recall()])

        pass2_lr = LEARNING_RATE/10
        preprocessor = tf.keras.applications.mobilenet_v2.preprocess_input
    elif base == 'ResNet50': 
        # Setup hyperparamters.
        BATCH_SIZE = 32
        DENSE_UNITS = 128
        DROPOUT = 0.2
        LEARNING_RATE = 1e-4
        L2_PENALTY = 1e-4
        FREEZE = 40 # Freeze all layers less than this (ResNet50 has 175 layers).

        logger.info('batch size: {}, dense units {}, dropout: {}'
            .format(BATCH_SIZE, DENSE_UNITS, DROPOUT))
        logger.info('learning rate: {}, l2 penalty: {}, freeze {}'
            .format(LEARNING_RATE, L2_PENALTY, FREEZE))

        base_model = tf.keras.applications.resnet50.ResNet50(weights='imagenet',
            include_top=False,
            pooling='avg',
            input_shape=(224,224,3))

        # Uncomment below to modify base model kernel regularizers for fine-tuning.
        # This may improve accuracy in some cases at expense of training time. 
        #add_regularization(base_model, tf.keras.regularizers.l2(L2_PENALTY))

        base_model.trainable = False

        model = tf.keras.models.Sequential()
        model.add(base_model)
        model.add(tf.keras.layers.Dense(DENSE_UNITS, activation='relu',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))
        model.add(tf.keras.layers.Dropout(rate=DROPOUT))
        model.add(tf.keras.layers.Dense(num_classes, activation='softmax',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))

        model.compile(loss=tf.keras.losses.CategoricalCrossentropy(label_smoothing=0.1),
            optimizer=tf.keras.optimizers.Adam(lr=LEARNING_RATE),
            metrics=['accuracy', tf.keras.metrics.Precision(),
                tf.keras.metrics.Recall()])

        pass2_lr = LEARNING_RATE/10
        preprocessor = tf.keras.applications.resnet50.preprocess_input
    else: #'VGG16'
        # Setup hyperparamters.
        BATCH_SIZE = 32
        DENSE_UNITS = 128
        DROPOUT = 0.2
        LEARNING_RATE = 1e-4
        L2_PENALTY = 1e-4
        FREEZE = 10 # Freeze all layers less than this (VGG16 has 19 layers).

        logger.info('batch size: {}, dense units {}, dropout: {}'
            .format(BATCH_SIZE, DENSE_UNITS, DROPOUT))
        logger.info('learning rate: {}, l2 penalty: {}, freeze {}'
            .format(LEARNING_RATE, L2_PENALTY, FREEZE))

        base_model = tf.keras.applications.vgg16.VGG16(weights='imagenet',
            include_top=False,
            pooling='avg',
            input_shape=(224,224,3))

        # Uncomment below to modify base model kernel regularizers for fine-tuning.
        # This may improve accuracy in some cases at expense of training time. 
        #add_regularization(base_model, tf.keras.regularizers.l2(L2_PENALTY))

        base_model.trainable = False

        model = tf.keras.models.Sequential()
        model.add(base_model)
        model.add(tf.keras.layers.Dense(DENSE_UNITS, activation='relu',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))
        model.add(tf.keras.layers.Dropout(rate=DROPOUT))
        model.add(tf.keras.layers.Dense(num_classes, activation='softmax',
            kernel_regularizer=tf.keras.regularizers.l2(L2_PENALTY)))

        model.compile(loss=tf.keras.losses.CategoricalCrossentropy(label_smoothing=0.1),
            optimizer=tf.keras.optimizers.Adam(lr=LEARNING_RATE),
            metrics=['accuracy', tf.keras.metrics.Precision(),
                tf.keras.metrics.Recall()])

        pass2_lr = LEARNING_RATE/10
        preprocessor = tf.keras.applications.vgg16.preprocess_input

    return model, pass2_lr, preprocessor, BATCH_SIZE, FREEZE
def create_model ( base , num_classes ) : logger . info ( 'Creating model with cnn base: {}' . format ( base ) ) if base == 'InceptionResNetV2' : # Setup hyperparamters. BATCH_SIZE = 32 DENSE_UNITS = 128 DROPOUT = 0.2 LEARNING_RATE = 1e-4 L2_PENALTY = 1e-4 FREEZE = 200 # Freeze all layers less than this (InceptionResNetV2 has 780 layers). logger . info ( 'batch size: {}, dense units {}, dropout: {}' . format ( BATCH_SIZE , DENSE_UNITS , DROPOUT ) ) logger . info ( 'learning rate: {}, l2 penalty: {}, freeze {}' . format ( LEARNING_RATE , L2_PENALTY , FREEZE ) ) base_model = tf . keras . applications . inception_resnet_v2 . InceptionResNetV2 ( weights = 'imagenet' , include_top = False , pooling = 'avg' , input_shape = ( 299 , 299 , 3 ) ) # Uncomment below to modify base model kernel regularizers for fine-tuning. # This may improve accuracy in some cases at expense of training time.  #add_regularization(base_model, tf.keras.regularizers.l2(L2_PENALTY)) base_model . trainable = False model = tf . keras . models . Sequential ( ) model . add ( base_model ) model . add ( tf . keras . layers . Dense ( DENSE_UNITS , activation = 'relu' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . add ( tf . keras . layers . Dropout ( rate = DROPOUT ) ) model . add ( tf . keras . layers . Dense ( num_classes , activation = 'softmax' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . compile ( loss = tf . keras . losses . CategoricalCrossentropy ( label_smoothing = 0.1 ) , optimizer = tf . keras . optimizers . Adam ( lr = LEARNING_RATE ) , metrics = [ 'accuracy' , tf . keras . metrics . Precision ( ) , tf . keras . metrics . Recall ( ) ] ) pass2_lr = LEARNING_RATE / 10 preprocessor = tf . keras . applications . inception_resnet_v2 . preprocess_input elif base == 'NASNetLarge' : # Setup hyperparamters. BATCH_SIZE = 16 # use caution increasing as this will cause OOM DENSE_UNITS = 128 DROPOUT = 0.2 LEARNING_RATE = 1e-4 L2_PENALTY = 1e-4 FREEZE = 266 # Freeze all layers less than this (NASNetLarge has 1039 layers). logger . info ( 'batch size: {}, dense units {}, dropout: {}' . format ( BATCH_SIZE , DENSE_UNITS , DROPOUT ) ) logger . info ( 'learning rate: {}, l2 penalty: {}, freeze {}' . format ( LEARNING_RATE , L2_PENALTY , FREEZE ) ) base_model = tf . keras . applications . nasnet . NASNetLarge ( weights = 'imagenet' , include_top = False , pooling = 'max' , # won't complie on the edge tpu anyhow... input_shape = ( 331 , 331 , 3 ) ) base_model . trainable = False model = tf . keras . models . Sequential ( ) model . add ( base_model ) model . add ( tf . keras . layers . Dense ( DENSE_UNITS , activation = 'relu' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . add ( tf . keras . layers . Dropout ( rate = DROPOUT ) ) model . add ( tf . keras . layers . Dense ( num_classes , activation = 'softmax' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . compile ( loss = tf . keras . losses . CategoricalCrossentropy ( label_smoothing = 0.1 ) , optimizer = tf . keras . optimizers . Adam ( lr = LEARNING_RATE ) , metrics = [ 'accuracy' , tf . keras . metrics . Precision ( ) , tf . keras . metrics . Recall ( ) ] ) pass2_lr = LEARNING_RATE / 10 preprocessor = tf . keras . applications . nasnet . preprocess_input elif base == 'NASNetMobile' : # Setup hyperparamters. BATCH_SIZE = 32 DENSE_UNITS = 128 DROPOUT = 0.2 LEARNING_RATE = 1e-4 L2_PENALTY = 1e-4 FREEZE = 200 # Freeze all layers less than this (NASNetMobile has 769 layers). logger . info ( 'batch size: {}, dense units {}, dropout: {}' . format ( BATCH_SIZE , DENSE_UNITS , DROPOUT ) ) logger . info ( 'learning rate: {}, l2 penalty: {}, freeze {}' . format ( LEARNING_RATE , L2_PENALTY , FREEZE ) ) base_model = tf . keras . applications . nasnet . NASNetMobile ( weights = 'imagenet' , include_top = False , pooling = 'avg' , input_shape = ( 224 , 224 , 3 ) ) base_model . trainable = False model = tf . keras . models . Sequential ( ) model . add ( base_model ) model . add ( tf . keras . layers . Dense ( DENSE_UNITS , activation = 'relu' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . add ( tf . keras . layers . Dropout ( rate = DROPOUT ) ) model . add ( tf . keras . layers . Dense ( num_classes , activation = 'softmax' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . compile ( loss = tf . keras . losses . CategoricalCrossentropy ( label_smoothing = 0.1 ) , optimizer = tf . keras . optimizers . Adam ( lr = LEARNING_RATE ) , metrics = [ 'accuracy' , tf . keras . metrics . Precision ( ) , tf . keras . metrics . Recall ( ) ] ) pass2_lr = LEARNING_RATE / 10 preprocessor = tf . keras . applications . nasnet . preprocess_input elif base == 'MobileNetV2' : # Setup hyperparamters. BATCH_SIZE = 32 DENSE_UNITS = 128 DROPOUT = 0.2 LEARNING_RATE = 5e-4 L2_PENALTY = 1e-4 FREEZE = 75 # Freeze all layers less than this (MobileNetV2 has 155 layers). logger . info ( 'batch size: {}, dense units {}, dropout: {}' . format ( BATCH_SIZE , DENSE_UNITS , DROPOUT ) ) logger . info ( 'learning rate: {}, l2 penalty: {}, freeze {}' . format ( LEARNING_RATE , L2_PENALTY , FREEZE ) ) base_model = tf . keras . applications . mobilenet_v2 . MobileNetV2 ( weights = 'imagenet' , include_top = False , pooling = 'avg' , input_shape = ( 224 , 224 , 3 ) ) # Uncomment below to modify base model kernel regularizers for fine-tuning. # This may improve accuracy in some cases at expense of training time.  #add_regularization(base_model, tf.keras.regularizers.l2(L2_PENALTY)) base_model . trainable = False model = tf . keras . models . Sequential ( ) model . add ( base_model ) model . add ( tf . keras . layers . Dense ( DENSE_UNITS , activation = 'relu' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . add ( tf . keras . layers . Dropout ( rate = DROPOUT ) ) model . add ( tf . keras . layers . Dense ( num_classes , activation = 'softmax' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . compile ( loss = tf . keras . losses . CategoricalCrossentropy ( label_smoothing = 0.1 ) , optimizer = tf . keras . optimizers . Adam ( lr = LEARNING_RATE ) , metrics = [ 'accuracy' , tf . keras . metrics . Precision ( ) , tf . keras . metrics . Recall ( ) ] ) pass2_lr = LEARNING_RATE / 10 preprocessor = tf . keras . applications . mobilenet_v2 . preprocess_input elif base == 'ResNet50' : # Setup hyperparamters. BATCH_SIZE = 32 DENSE_UNITS = 128 DROPOUT = 0.2 LEARNING_RATE = 1e-4 L2_PENALTY = 1e-4 FREEZE = 40 # Freeze all layers less than this (ResNet50 has 175 layers). logger . info ( 'batch size: {}, dense units {}, dropout: {}' . format ( BATCH_SIZE , DENSE_UNITS , DROPOUT ) ) logger . info ( 'learning rate: {}, l2 penalty: {}, freeze {}' . format ( LEARNING_RATE , L2_PENALTY , FREEZE ) ) base_model = tf . keras . applications . resnet50 . ResNet50 ( weights = 'imagenet' , include_top = False , pooling = 'avg' , input_shape = ( 224 , 224 , 3 ) ) # Uncomment below to modify base model kernel regularizers for fine-tuning. # This may improve accuracy in some cases at expense of training time.  #add_regularization(base_model, tf.keras.regularizers.l2(L2_PENALTY)) base_model . trainable = False model = tf . keras . models . Sequential ( ) model . add ( base_model ) model . add ( tf . keras . layers . Dense ( DENSE_UNITS , activation = 'relu' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . add ( tf . keras . layers . Dropout ( rate = DROPOUT ) ) model . add ( tf . keras . layers . Dense ( num_classes , activation = 'softmax' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . compile ( loss = tf . keras . losses . CategoricalCrossentropy ( label_smoothing = 0.1 ) , optimizer = tf . keras . optimizers . Adam ( lr = LEARNING_RATE ) , metrics = [ 'accuracy' , tf . keras . metrics . Precision ( ) , tf . keras . metrics . Recall ( ) ] ) pass2_lr = LEARNING_RATE / 10 preprocessor = tf . keras . applications . resnet50 . preprocess_input else : #'VGG16' # Setup hyperparamters. BATCH_SIZE = 32 DENSE_UNITS = 128 DROPOUT = 0.2 LEARNING_RATE = 1e-4 L2_PENALTY = 1e-4 FREEZE = 10 # Freeze all layers less than this (VGG16 has 19 layers). logger . info ( 'batch size: {}, dense units {}, dropout: {}' . format ( BATCH_SIZE , DENSE_UNITS , DROPOUT ) ) logger . info ( 'learning rate: {}, l2 penalty: {}, freeze {}' . format ( LEARNING_RATE , L2_PENALTY , FREEZE ) ) base_model = tf . keras . applications . vgg16 . VGG16 ( weights = 'imagenet' , include_top = False , pooling = 'avg' , input_shape = ( 224 , 224 , 3 ) ) # Uncomment below to modify base model kernel regularizers for fine-tuning. # This may improve accuracy in some cases at expense of training time.  #add_regularization(base_model, tf.keras.regularizers.l2(L2_PENALTY)) base_model . trainable = False model = tf . keras . models . Sequential ( ) model . add ( base_model ) model . add ( tf . keras . layers . Dense ( DENSE_UNITS , activation = 'relu' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . add ( tf . keras . layers . Dropout ( rate = DROPOUT ) ) model . add ( tf . keras . layers . Dense ( num_classes , activation = 'softmax' , kernel_regularizer = tf . keras . regularizers . l2 ( L2_PENALTY ) ) ) model . compile ( loss = tf . keras . losses . CategoricalCrossentropy ( label_smoothing = 0.1 ) , optimizer = tf . keras . optimizers . Adam ( lr = LEARNING_RATE ) , metrics = [ 'accuracy' , tf . keras . metrics . Precision ( ) , tf . keras . metrics . Recall ( ) ] ) pass2_lr = LEARNING_RATE / 10 preprocessor = tf . keras . applications . vgg16 . preprocess_input return model , pass2_lr , preprocessor , BATCH_SIZE , FREEZE