Exemplo n.º 1
0
    def MobileNet(self):
        model = models.Sequential()
        from keras.applications import MobileNet
        alpha = 0.75
        conv_base = MobileNet(include_top=False,
                              weights='imagenet',
                              input_shape=self.input_shape,
                              pooling='max',
                              alpha=alpha)
        print('MobileNet:\n')
        conv_base.summary()
        '''
        alpha: 控制网络的宽度:
                  如果alpha<1,则同比例的减少每层的滤波器个数
                  如果alpha>1,则同比例增加每层的滤波器个数
                  如果alpha=1,使用默认的滤波器个数
        '''
        model.add(conv_base)
        model.add(layers.Reshape((1, 1, int(1024 * alpha))))
        model.add(layers.Dropout(0.5))  # 以前是1e-3,但是我觉得这个概率太小了,不利于泛化
        model.add(
            layers.Conv2D(len(self.labels), (1, 1),
                          padding='same',
                          name='conv_preds'))
        model.add(layers.Activation('softmax', name='act_softmax'))
        model.add(layers.Reshape((len(self.labels), ), name='reshape_2'))

        model.compile(loss='categorical_crossentropy',
                      optimizer=optimizers.adam(lr=2e-3),
                      metrics=['acc'])
        return model
Exemplo n.º 2
0
def make_model():
    model = MobileNet(input_shape=(224, 224, 3),
                      alpha=1.,
                      weights=None,
                      classes=2)
    model.compile(optimizer=Adam(lr=0.002),
                  loss='categorical_crossentropy',
                  metrics=[categorical_crossentropy, categorical_accuracy])
    print(model.summary())
    return model
Exemplo n.º 3
0
def tfl_model(base_model):
    if base_model == 1:  # MobileNet (87 layers)
        model_name = 'MobileNet'
        bmodel = MobileNet(weights='imagenet', include_top=False)
    elif base_model == 2:  # InceptionV3 (311 layers)
        model_name = 'InceptionV3'
        bmodel = InceptionV3(weights='imagenet', include_top=False)
    elif base_model == 3:  # VGG16 (16 layers)
        model_name = 'VGG16'
        bmodel = VGG16(weights='imagenet', include_top=False)
    elif base_model == 4:  # VGG119 (22 layers)
        model_name = 'VGG19'
        bmodel = VGG19(weights='imagenet', include_top=False)
    elif base_model == 5:  # ResNet50 (175 layers)
        model_name = 'ResNet50'
        bmodel = ResNet50(weights='imagenet', include_top=False)
    elif base_model == 6:  # Xception (132 layers)
        model_name = 'Xception'
        bmodel = Xception(weights='imagenet', include_top=False)
    elif base_model == 7:  # MobileNetV2 (155 layers)
        model_name = 'MobileNetV2'
        bmodel = MobileNetV2(weights='imagenet', include_top=False)
    #elif base_model == 8: # DenseNet121 (427 layers)
    #    model_name = 'DenseNet121'
    #    bmodel     = DenseNet121(weights='imagenet',include_top=False)
    #elif base_model == 9: # NASNetMobile (769 layers)
    #    model_name = 'NASNetMobile'
    #    bmodel     = NASNetMobile(weights='imagenet',include_top=False)
    #elif base_model == 10: # NASNetLarge (1039 layers)
    #    model_name = 'NASNetLarge'
    #    bmodel     = NASNetLarge(weights='imagenet',include_top=False)
    else:
        print('error: base model ' + str(base_model) + ' not defined.')
    bmodel.summary()
    print('\nBase model ' + model_name + ' loaded with ' +
          str(len(bmodel.layers)) + ' layers.')
    return bmodel
Exemplo n.º 4
0
    def create_model(self):
        from helper import precision, recall, f1_score
        input = Input(shape=(dim[0], dim[1], 3), name='input')

        model = MobileNet(input_shape=dim,
                          alpha=1,
                          depth_multiplier=1,
                          dropout=self.dropout_global,
                          include_top=False,
                          weights=self.w,
                          input_tensor=None)
        if self.trainable:
            for i in model.layers[:len(model.layers) - self.trainable]:
                i.trainable = False
            x = model.output
            input = model.input
            optimizer = SGD(learning_rate=self.eta)
        else:
            optimizer = Adam(lr=self.eta, amsgrad=self.amsgrad)
            x = model(input)

        x = GlobalAveragePooling2D()(x)
        nodes = 2048
        x = Dense(nodes,
                  activation='relu',
                  kernel_regularizer=l2(self.regulizer))(x)
        x = Dropout(self.dropout)(x)
        for i in range(self.layer_params):
            nodes = int(nodes / 2)
            x = Dense(nodes,
                      activation='relu',
                      kernel_regularizer=l2(self.regulizer))(x)
            x = Dropout(self.dropout)(x)
        z = Dense(units=self.classes, activation='softmax')(x)
        model = Model(inputs=input, outputs=z)
        if not self.train_mode:
            model.compile(optimizer=optimizer,
                          loss='categorical_crossentropy',
                          metrics=['accuracy', precision, recall, f1_score])

        else:
            model.compile(optimizer=optimizer,
                          loss='categorical_crossentropy',
                          metrics=['accuracy'])

        print(model.summary())

        return model, optimizer
Exemplo n.º 5
0
def build_small_mobnet(width=28, height=28, alpha=0.25, verbose=True):

    dim = (height, width, 3)
    input = Input(shape=dim, name='input')
    model = MobileNet(input_shape=dim,
                      alpha=alpha,
                      depth_multiplier=1,
                      include_top=False,
                      weights='imagenet',
                      input_tensor=None)
    x = model(input)
    x = GlobalAveragePooling2D()(x)

    x = Dense(units=512, activation='relu', kernel_regularizer=l2(0.01))(x)
    x = Dropout(0.2)(x)
    z = Dense(6)(x)
    z = Activation('softmax')(z)
    model = Model(inputs=input, outputs=z)
    model.compile(loss='categorical_crossentropy',
                  optimizer='adadelta',
                  metrics=['accuracy'])

    if verbose == True: print(model.summary())
    return model
Exemplo n.º 6
0
                                               class_mode='binary')

test_datagen = ImageDataGenerator(rescale=1. / 255)
data_test = test_datagen.flow_from_directory("DATOS/test",
                                             target_size=(128, 128),
                                             class_mode='binary')

model = MobileNet(input_shape=(128, 128, 3), include_top=False, pooling='avg')
x = model.output
x = Dense(512, activation="relu")(x)
predict = Dense(1, activation="sigmoid")(x)
model = Model(inputs=model.input, outputs=predict)

adam = Adam(lr=0.0001)
model.compile(optimizer=adam, loss="binary_crossentropy", metrics=["accuracy"])
model.summary()

history = model.fit(data_train,
                    epochs=10,
                    validation_data=data_test,
                    verbose=1)

model.save("/Clasificador.h5")


def visualizar_img_test(path, modelo):
    img = cv2.imread(path)
    img_1 = cv2.resize(img, (128, 128))
    img = (img_1 / 255)
    img = np.expand_dims(img, axis=0)
    predict = modelo.predict(img)
Exemplo n.º 7
0
(x_train, y_train), (x_test, y_test) = cifar10.load_data()

print(f"x_train.shape : {x_train.shape}")
print(f"x_test.shape : {x_test.shape}")
print(f"y_train.shape : {y_train.shape}")
print(f"y_test.shape : {y_test.shape}")

x_train = x_train.reshape(50000, 32, 32, 3).astype('float32') / 255.0
x_test = x_test.reshape(10000, 32, 32, 3).astype('float32') / 255.0

# 2. model
# vgg16 = ResNet152V2(weights='imagenet' , include_top=False, input_shape=(32,32,3))
vgg16 = MobileNet(weights='imagenet',
                  include_top=False,
                  input_shape=(32, 32, 3))
vgg16.summary()

model = Sequential()
model.add(vgg16)

model.add(Flatten())

model.add(Dense(128))
model.add(BatchNormalization())
# model.add(Dropout(0.1))
model.add(Activation('relu'))

model.add(Dense(10, activation='softmax'))

model.summary()
Exemplo n.º 8
0
def Mobile_Net(trainable=None, net="MobileNet"):

    # Preprocessing the dataset into keras feedable format

    train_datagen = ImageDataGenerator(rotation_range=rotation,
                                       width_shift_range=width_shift,
                                       height_shift_range=height_shift,
                                       rescale=scale,
                                       shear_range=shear,
                                       zoom_range=zoom,
                                       horizontal_flip=horizontal,
                                       fill_mode=fill,
                                       validation_split=validation)
    test_datagen = ImageDataGenerator(rescale=scale, )

    train_generator = train_datagen.flow_from_directory(
        path,
        target_size=target,
        batch_size=batch,
        class_mode='categorical',
        subset='training',
    )
    validation_generator = train_datagen.flow_from_directory(
        path,
        target_size=target,
        batch_size=batch,
        class_mode='categorical',
        subset='validation')

    models_list = ['MobileNet', 'MobileNetV2']

    # Loading the MobileNet Model

    if net == "MobileNet":
        mobilenet = MobileNet(include_top=False,
                              alpha=alpha_n,
                              depth_multiplier=depth_multiplier_n,
                              dropout=dropout_num_n,
                              weights='imagenet',
                              input_shape=input_sh,
                              pooling=pooling_model)
    if net == "MobileNetV2":
        mobilenet = MobileNetV2(include_top=False,
                                alpha=alpha_n,
                                weights='imagenet',
                                input_shape=input_sh,
                                pooling=pooling_model)
    if net not in models_list:
        raise ValueError('Please provide the raise model ')
    output = mobilenet.layers[-1].output
    if pooling_model is None:
        output = keras.layers.Flatten()(output)
    mobilenet = Model(mobilenet.input, output=output)
    print(mobilenet.summary())
    print('\n\n\n')
    # If you chose not for fine tuning
    if trainable is None:
        model = Sequential()
        model.add(mobilenet)
        model.add(Dense(hidden, activation='relu', input_dim=input_sh))
        model.add(Dropout(dropout_num))
        model.add(Dense(hidden, activation='relu'))
        model.add(Dropout(dropout_num))
        if classes == 1:
            model.add(Dense(classes, activation='sigmoid', name='Output'))
        else:
            model.add(Dense(classes, activation='softmax', name='Output'))

        for layer in mobilenet.layers:
            layer.trainable = False
        print("The model summary of Mobilenet  -->\n\n\n"
              )  # In this the Mobilenet layers are not trainable

        for i, layer in enumerate(mobilenet.layers):
            print(i, layer.name, layer.trainable)
        model.compile(
            loss=loss_param,  # Change according to data
            optimizer=optimizers.RMSprop(),
            metrics=['accuracy'])
        print("The summary of final Model \n\n\n")
        print(model.summary())
        print('\n\n\n')

        fit_history = model.fit_generator(
            train_generator,
            steps_per_epoch=len(train_generator.filenames) // batch,
            epochs=epoch,
            shuffle=True,
            validation_data=validation_generator,
            validation_steps=len(train_generator.filenames) // batch,
            class_weight=n,
            callbacks=[
                EarlyStopping(patience=patience_param,
                              restore_best_weights=True),
                ReduceLROnPlateau(patience=patience_param)
            ])
        os.chdir(output_path)
        model.save("model.h5")
        print(fit_history.history.keys())
        plt.figure(1, figsize=(15, 8))

        plt.subplot(221)
        plt.plot(fit_history.history['accuracy'])
        plt.plot(fit_history.history['val_accuracy'])
        plt.title('model accuracy')
        plt.ylabel('accuracy')
        plt.xlabel('epoch')
        plt.legend(['train', 'valid'])

        plt.subplot(222)
        plt.plot(fit_history.history['loss'])
        plt.plot(fit_history.history['val_loss'])
        plt.title('model loss')
        plt.ylabel('loss')
        plt.xlabel('epoch')
        plt.legend(['train', 'valid'])

        plt.show()

    if trainable is not None:
        # Make last block of the conv_base trainable:

        for layer in mobilenet.layers[:trainable]:
            layer.trainable = False
        for layer in mobilenet.layers[trainable:]:
            layer.trainable = True

        print('Last block of the conv_base is now trainable')

        for i, layer in enumerate(mobilenet.layers):
            print(i, layer.name, layer.trainable)

        model = Sequential()
        model.add(mobilenet)
        model.add(Dense(hidden, activation='relu', input_dim=input_sh))
        model.add(Dropout(dropout_num))
        model.add(Dense(hidden, activation='relu'))
        model.add(Dropout(dropout_num))
        model.add(Dense(hidden, activation='relu'))
        model.add(Dropout(dropout_num))
        if classes == 1:
            model.add(Dense(classes, activation='sigmoid', name='Output'))
        else:
            model.add(Dense(classes, activation='softmax', name='Output'))

        for layer in mobilenet.layers:
            layer.trainable = False
        print("The model summary of Mobilenet -->\n\n\n"
              )  # In this the Mobilenet layers are not trainable
        model.compile(
            loss=loss_param,  # Change according to data
            optimizer=optimizers.RMSprop(),
            metrics=['accuracy'])
        print("The summary of final Model \n\n\n")
        print(model.summary())
        print('\n\n\n')

        fit_history = model.fit_generator(
            train_generator,
            steps_per_epoch=len(train_generator.filenames) // batch,
            epochs=epoch,
            shuffle=True,
            validation_data=validation_generator,
            validation_steps=len(train_generator.filenames) // batch,
            class_weight=n,
            callbacks=[
                EarlyStopping(patience=patience_param,
                              restore_best_weights=True),
                ReduceLROnPlateau(patience=patience_param)
            ])
        os.chdir(output_path)
        model.save("model.h5")
        print(fit_history.history.keys())
        plt.figure(1, figsize=(15, 8))

        plt.subplot(221)
        plt.plot(fit_history.history['accuracy'])
        plt.plot(fit_history.history['val_accuracy'])
        plt.title('model accuracy')
        plt.ylabel('accuracy')
        plt.xlabel('epoch')
        plt.legend(['train', 'valid'])

        plt.subplot(222)
        plt.plot(fit_history.history['loss'])
        plt.plot(fit_history.history['val_loss'])
        plt.title('model loss')
        plt.ylabel('loss')
        plt.xlabel('epoch')
        plt.legend(['train', 'valid'])

        plt.show()
Exemplo n.º 9
0
def task2():
    # Create a MobileNet model
    mobile = MobileNet(weights='imagenet')

    # See a summary of the layers in the model
    mobile.summary()

    # Modify the model
    # Exclude the last 5 layers of the model
    x = mobile.layers[-6].output
    # Add a dropout and dense layer for predictions
    x = Dropout(0.25)(x)
    predictions = Dense(7, activation='softmax')(x)

    # Create a new model with the new outputs
    model = Model(inputs=mobile.input, outputs=predictions)

    # See a summary of the new layers in the model
    model.summary()

    # Freeze the weights of the layers that we aren't training (training the last 23)
    for layer in model.layers[:-23]:
        layer.trainable = False


    # Compile the model
    model.compile(loss='categorical_crossentropy',
                  optimizer='adam',
                  metrics=['accuracy'])

    # Useful variables
    data_folder = '../res/Task 2/Training'
    test_folder = '../res/Task 2/Test'
    total_train = 8012
    total_test = 2003
    labels = ["AK", "BCC", "BK", "D", "MN", "M", "VL"]
    batch_size = 100 
    epochs = 10

    # this is the augmentation configuration we will use for training
    train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

    # this is the augmentation configuration we will use for testing:
    # only rescaling
    test_datagen = ImageDataGenerator(rescale=1./255)

    train_generator = train_datagen.flow_from_directory(
        data_folder, class_mode='categorical', batch_size=batch_size, target_size=(224, 224),)
    test_generator = test_datagen.flow_from_directory(
        test_folder, class_mode='categorical', batch_size=batch_size, target_size=(224, 224))
    
    # Try to deal with class imbalance: calculate class_weights so that the minority classes have a larger weight
    # than the majority classes.
    class_weights = class_weight.compute_class_weight(
               'balanced',
                np.unique(train_generator.classes), 
                train_generator.classes)
    class_weights = dict(enumerate(class_weights))

    # Train the model
    model.fit_generator(
        train_generator,
        steps_per_epoch=total_train // batch_size,
        epochs=epochs,
        class_weight=class_weights
        )

    # Evaluate the model accuracy with the testing dataset
    scores = model.evaluate_generator(test_generator, total_test // batch_size)
    print("Test accuracy = ", scores[1])

    # Generate predictions with the test dataset
    # softmax returns a value for each class
    # the predicted class for a given sample will be the one that has the maximum value
    predictions = model.predict_generator(test_generator, total_test // batch_size + 1)
    y_pred = np.argmax(predictions, axis=1)

    # Save the predictions in a csv file
    with open('results2.csv', mode="w") as results_file:
        writer = csv.writer(results_file, delimiter=',',
                        quotechar='"', quoting=csv.QUOTE_MINIMAL)

        for x in predictions:
            writer.writerow(x)

    # Generate confusion matrix and classification report
    # Helps to evaluate metrics such as accuracy, precision, recall
    print('Confusion Matrix')
    cm = confusion_matrix(test_generator.classes, y_pred)
    print(cm)
    plot_cm(cm, labels, "second.png")

    print('Classification Report')
    print(classification_report(test_generator.classes, y_pred, target_names=labels))
Exemplo n.º 10
0
EPOCHS = 30
size = 128
batchsize = 340

base_model = MobileNet(input_shape=(size, size, 3),
                       alpha=1.,
                       weights="imagenet",
                       include_top=False)
inp = base_model.input
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(NCATS, activation='softmax')(x)
model = Model(inp, x)

base_model = Sequential(model.layers[:-2])
base_model.summary()

from keras.models import Sequential
from keras.layers import BatchNormalization, Conv1D, LSTM, Dense, Dropout, Bidirectional
from keras.layers import CuDNNLSTM as LSTM  # this one is about 3x faster on GPU instances

inp = Input(shape=(70, 3))

x = BatchNormalization()(inp)

# # filter count and length are taken from the script https://github.com/tensorflow/models/blob/master/tutorials/rnn/quickdraw/train_model.py
x = Conv1D(256, (5, ), activation="relu")(x)
x = Dropout(0.2)(x)
x = Conv1D(256, (5, ), activation='relu')(x)
x = Dropout(0.2)(x)
x = Conv1D(256, (3, ), activation='relu')(x)
Exemplo n.º 11
0
    filepath='weights_keras/{epoch:02d}-{val_loss:.2f}.hdf5',
    monitor='val_acc',
    save_best_only=True)
tb = TensorBoard(log_dir='./logs_keras', histogram_freq=1, batch_size=128)

from keras.applications import MobileNetV2
from keras.applications import MobileNet

k_model = MobileNet(input_shape=(224, 224, 3),
                    alpha=1.0,
                    depth_multiplier=1,
                    dropout=1e-3,
                    include_top=True,
                    weights=None,
                    input_tensor=None,
                    pooling=None,
                    classes=200)

k_model.compile(optimizer='adam',
                metrics=['accuracy'],
                loss='categorical_crossentropy')

k_model.summary()

k_model.fit_generator(train_generator,
                      validation_data=val_generator,
                      epochs=35,
                      callbacks=[ckpt],
                      workers=6,
                      use_multiprocessing=True)
Exemplo n.º 12
0
from keras import Model
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator
from keras.applications import MobileNet
from keras.layers import Dense, GlobalAveragePooling2D
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer

pickle_in = open("/content/drive/My Drive/labelfile_4.pickle", "rb")
example_dict = pickle.load(pickle_in)
y_new = example_dict
pickle_in = open('/content/drive/My Drive/trainfile_4.pickle', "rb")
X_new = pickle.load(pickle_in)

vggmodel = MobileNet(weights='imagenet', include_top=False)
vggmodel.summary()
vggmodel.trainable = False

x = vggmodel.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
x = Dense(1024, activation='relu')(x)
x = Dense(512, activation='relu')(x)
preds = Dense(3, activation='softmax')(x)

model_final = Model(input=vggmodel.input, output=preds)

from keras.optimizers import Adam
opt = Adam(lr=0.0001)

model_final.compile(loss=keras.losses.categorical_crossentropy,
Exemplo n.º 13
0
# Re-loads the MobileNet model without the top or FC layers
MobileNet = MobileNet(weights='imagenet',
                      include_top=False,
                      input_shape=(img_rows, img_cols, 3))

# Here we freeze the last 4 layers
# Layers are set to trainable as True by default
for layer in MobileNet.layers:
    layer.trainable = False

# Let's print our layers
for (i, layer) in enumerate(MobileNet.layers):
    print(str(i) + " " + layer.__class__.__name__, layer.trainable)

print(MobileNet.summary())


def lw(bottom_model, num_classes):
    """creates the top or head of the model that will be 
    placed ontop of the bottom layers"""

    top_model = bottom_model.output

    #     top_model = GlobalAveragePooling2D()(top_model)
    #     top_model = Dense(1024,activation='relu')(top_model)
    #     top_model = Dense(128, activation='relu')(top_model)
    #     top_model = Dense(num_classes,activation='softmax')(top_model)
    top_model = Conv2D(32,
                       kernel_size=(3, 3),
                       activation='relu',
Exemplo n.º 14
0
                           name='conv_pw_%d_bn' % block_id)(x)
    return Activation(relu6, name='conv_pw_%d_relu' % block_id)(x)


if __name__ == '__main__':
    print('Loading VGG16 Weights ...')
    VGG16_notop = MobileNet(input_shape=None,
                            alpha=1.0,
                            depth_multiplier=1,
                            dropout=1e-3,
                            include_top=False,
                            weights='imagenet',
                            input_tensor=None,
                            pooling=None,
                            classes=1000)
    VGG16_notop.summary()

    print('Adding Average Pooling Layer and Softmax Output Layer ...')
    output = VGG16_notop.get_layer(index=-1).output  # Shape: (6, 6, 2048)
    output = AveragePooling2D((8, 8), strides=(8, 8), name='avg_pool')(output)
    output = Flatten(name='flatten')(output)
    output = Dense(n_classes, activation='softmax', name='predictions')(output)

    VGG16_model = Model(VGG16_notop.input, output)
    VGG16_model.summary()

    optimizer = SGD(lr=learning_rate, momentum=0.9, decay=0.001, nesterov=True)
    VGG16_model.compile(loss='categorical_crossentropy',
                        optimizer=optimizer,
                        metrics=['accuracy'])
Exemplo n.º 15
0
from keras.callbacks import TensorBoard, ModelCheckpoint

from dataset import SmokeGifSequence

if __name__ == '__main__':
    input_shape = (299, 299, 3)
    # hdf = "m1.h5"
    hdf = "temporal_vg_smoke_v1.h5"

    m = MobileNet(input_shape=(299, 299, 20), weights=None, classes=2)
    # load_model(hdf)
    m.load_weights(hdf)
    m.compile("adam", categorical_crossentropy, metrics=["accuracy"])
    # plot_model(m, show_shapes=True)

    m.summary()

    # data_dir = "/blender/storage/datasets/smoking/gifs/"
    data_dir = "/blender/storage/datasets/vg_smoke"

    train_seq = SmokeGifSequence(data_dir, neg_txt='negatives.txt', pos_txt='positives.txt',
                                 input_shape_hwc=input_shape,
                                 only_temporal=True)
    # val_seq = SmokeGifSequence(data_dir, neg_txt='validate_neg.txt', pos_txt='validate_pos.txt',
    #                            input_shape_hwc=input_shape,
    #                            only_temporal=True)

    log_dir = os.path.join("./logs", os.path.basename(hdf))
    m.fit_generator(train_seq, len(train_seq), epochs=20,
                    use_multiprocessing=True, workers=5,
                    # validation_data=val_seq, validation_steps=len(val_seq),
plt.tight_layout()
fig.savefig('gs.png', dpi=300)
plt.show();


MODEL_WEIGHTS_FILE = inDir + '/Prav_Model13.h5'

callbacks = [
    ReduceLROnPlateau(monitor='val_categorical_accuracy', factor=0.5, patience=5, mode='max', cooldown=3, verbose=1),
    ModelCheckpoint(MODEL_WEIGHTS_FILE, monitor='val_categorical_accuracy', save_best_only=True, verbose=1),
]

model = MobileNet(input_shape=(size, size, 1), alpha=1., weights=None, classes=NCATS)
model.compile(optimizer=Adam(lr=learning_rate), loss='categorical_crossentropy',
              metrics=[categorical_crossentropy, categorical_accuracy, top_3_accuracy])
print(model.summary())

model.fit_generator(
                        train_datagen, 
                        steps_per_epoch=STEPS, 
#                        initial_epoch = initial_epoch,
                        epochs=EPOCHS,
                        verbose=1,
                        validation_data=(x_valid, y_valid),
                        callbacks = callbacks
)


model.load_weights(MODEL_WEIGHTS_FILE)

valid_predictions = model.predict(x_valid, batch_size=128, verbose=1)
history = model.fit_generator(train_generator,
                              epochs=100,
                              validation_data=validation_generator,
                              callbacks=model_callbacks)

test_loss, test_acc = model.evaluate_generator(test_generator)
print('test acc:', test_acc)
print('test loss:', test_loss)

#Method 3 - Fine tuning
#Builds on Method 2

#Freezing all layers up to a specific one
conv_base.trainable = True

conv_base.summary()

set_trainable = False

for layer in conv_base.layers:
    if layer.name == 'conv_pw_13':
        set_trainable = True
    if set_trainable:
        layer.trainable = True
    else:
        layer.trainable = False

#Fine-tuning the model - low learning rate to limit magnitude of modifications
model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-5),
              metrics=['acc'])
def convertMobileNetWeights(out_path, input_size=224, alpha=0.25, include_top=True):
    if not os.path.isdir(out_path):
        os.mkdir(out_path)

    model_k = MobileNet(input_shape=(input_size, input_size, 3), alpha=alpha, weights='imagenet', include_top=include_top, pooling='avg')
    print(model_k.summary())
    model_t = MobileNet_v1(1000, alpha=alpha, input_size=input_size, include_top=include_top)

    res_t = dict()
    st = model_t.state_dict()
    for i, el in enumerate(st):
        arr = el.split('.')
        print(arr)
        if 'model' in el:
            key = (int(arr[1]), int(arr[2]))
            if key not in res_t:
                res_t[key] = []
            res_t[key].append((el, st[el].numpy().shape))
        elif 'fc.':
            key = (100, )
            if key not in res_t:
                res_t[key] = []
            res_t[key].append((el, st[el].numpy().shape))

    res_torch = dict()
    for i, el in enumerate(sorted(list(res_t.keys()))):
        print(i, el, res_t[el])
        res_torch[i] = res_t[el]
        print(res_torch[i])

    total = 0
    res_k = dict()
    for level_id in range(len(model_k.layers)):
        layer = model_k.layers[level_id]
        layer_type = layer.__class__.__name__
        if layer_type in ['Conv2D', 'BatchNormalization', 'DepthwiseConv2D', 'Dense']:
            w = layer.get_weights()
            print('{} {} {} {}'.format(total, level_id, layer_type, w[0].shape))
            res_k[total] = [level_id, layer_type, w[0].shape]

            # Modify state_dict
            if layer_type == 'Conv2D':
                weigths_t = w[0].transpose((3, 2, 1, 0))
                torch_name = res_torch[total][0][0]
                torch_shape = res_torch[total][0][1]
                print('Modify: {}'.format(torch_name))
                # Check shape
                if weigths_t.shape != torch_shape:
                    print('Shape mismatch: {} != {}'.format(weigths_t.shape, torch_shape))
                st[torch_name] = torch.from_numpy(weigths_t)
                if len(res_torch[total]) == 2:
                    print('Store bias...')
                    weigths_t = w[1]
                    torch_name = res_torch[total][1][0]
                    torch_shape = res_torch[total][1][1]
                    print('Modify: {}'.format(torch_name))
                    # Check shape
                    if weigths_t.shape != torch_shape:
                        print('Shape mismatch: {} != {}'.format(weigths_t.shape, torch_shape))
                    st[torch_name] = torch.from_numpy(weigths_t)

            elif layer_type == 'DepthwiseConv2D':
                weigths_t = w[0].transpose((2, 3, 1, 0))
                torch_name = res_torch[total][0][0]
                torch_shape = res_torch[total][0][1]
                print('Modify: {}'.format(torch_name))
                # Check shape
                if weigths_t.shape != torch_shape:
                    print('Shape mismatch: {} != {}'.format(weigths_t.shape, torch_shape))
                st[torch_name] = torch.from_numpy(weigths_t)
            elif layer_type == 'BatchNormalization':
                for i in range(4):
                    weigths_t = w[i]
                    torch_name = res_torch[total][i][0]
                    torch_shape = res_torch[total][i][1]
                    print('Modify: {}'.format(torch_name))
                    # Check shape
                    if weigths_t.shape != torch_shape:
                        print('Shape mismatch: {} != {}'.format(weigths_t.shape, torch_shape))
                    st[torch_name] = torch.from_numpy(weigths_t)

            total += 1

    model_t.load_state_dict(st)

    data_k = np.random.uniform(-1, 1, (100, input_size, input_size, 3)).astype(np.float32)
    data_t = data_k.transpose((0, 3, 2, 1))
    print(data_k.shape, data_t.shape)

    pred_k = model_k.predict(data_k)
    data_t = torch.from_numpy(data_t)
    model_t.eval()
    with torch.no_grad():
        pred_t = model_t(data_t)
    if include_top:
        pred_t = pred_t.numpy()
    else:
        pred_t = pred_t.permute(0, 3, 2, 1).squeeze().numpy()

    print(pred_k.shape, pred_t.shape)
    diff = (pred_t - pred_k)
    print(diff.min(), diff.max(), diff.mean())

    if np.abs(diff).max() > 0.001:
        print('Large error!')
        exit()

    top = '_no_top'
    if include_top:
        top = '_top'
    torch.save(model_t.state_dict(), out_path + "mobilenet_v1_size_{}_alpha_{}{}.pth".format(input_size, alpha, top))