projector.visualize_embeddings(output_dir, config)

#%% Evaluate model
scores = model.evaluate(X_test, y_test, verbose=1)
print(f"Accuracy: {scores[1]:.2%}")

#%% Train with binary crossentropy and gram matrix
accuracies = []
for i in range(1, 21):
    kernel = Lambda(
        lambda inputs: tf.reduce_sum(inputs[0] * inputs[1], axis=1))
    model = Sequential([BasicCNN((32, 32, 3), i), GramMatrix(kernel)])
    model.summary()
    model.compile(
        optimizer="adam",
        loss=binary_crossentropy(),
        metrics=[mean_score_classification_loss, min_eigenvalue],
    )
    model.fit(X_train, y_train, validation_split=0.2, epochs=20, batch_size=32)

    embeddings = model.layers[0].predict(X_train)
    classifier = Sequential([model.layers[0], Classification(kernel)])
    classifier.layers[1].set_support_set(embeddings, y_train)
    classifier.compile(loss="binary_crossentropy", optimizer="adam")
    classifier.evaluate(X_test, y_test, verbose=1)
    y_pred = classifier.predict(X_test, verbose=1)
    confusion_matrix = pd.crosstab(
        index=pd.Categorical(np.argmax(y_pred, axis=1),
                             categories=list(range(10))),
        columns=pd.Categorical(np.argmax(y_test, axis=1),
                               categories=list(range(10))),
Esempio n. 2
0
    preprocessings=preprocessing,
    batch_size=batch_size,
    labels_in_input=False,
    labels_in_output=True,
    to_categorical=True,
    k_shot=batch_size // 8,
    n_way=8,
)

#%% Train model with loss on kernel
siamese_nets.get_layer('branch_model').trainable = False
optimizer = Adam(lr=1e-4)
margin = 0.05
model.compile(
    optimizer=optimizer,
    loss=binary_crossentropy(margin),
    metrics=[
        binary_crossentropy(0.0),
        accuracy(margin), mean_score_classification_loss, min_eigenvalue
    ],
)
model.fit_generator(
    train_sequence,
    validation_data=val_sequence,
    callbacks=callbacks,
    initial_epoch=0,
    epochs=10,
    use_multiprocessing=False,
    workers=0,
)
Esempio n. 3
0
def train(base_dir):
    #%% Init model
    encoder = keras_applications.MobileNet(input_shape=(224, 224, 3), include_top=False, pooling="avg")
    support_layer = GramMatrix(
        kernel={
            "name": "MixedNorms",
            "init": {
                "norms": [
                    lambda x: 1 - tf.nn.l2_normalize(x[0]) * tf.nn.l2_normalize(x[1]),
                    lambda x: tf.math.abs(x[0] - x[1]),
                    lambda x: tf.nn.softmax(tf.math.abs(x[0] - x[1])),
                    lambda x: tf.square(x[0] - x[1]),
                ],
                "use_bias": True,
            },
        },
    )
    model = Sequential([encoder, support_layer])

    #%% Init training
    callbacks = [
        TensorBoard(base_dir, write_images=True, histogram_freq=1),
        ModelCheckpoint(str(base_dir / "best_loss.h5"), save_best_only=True),
        ReduceLROnPlateau(),
    ]

    #%% Init data
    @tf.function(input_signature=(tf.TensorSpec(shape=[None, None, 3], dtype=tf.uint8)))
    def preprocessing(input_tensor):
        output_tensor = tf.cast(input_tensor, dtype=tf.float32)
        output_tensor = tf.image.resize_with_pad(output_tensor, target_height=224, target_width=224)
        output_tensor = keras_applications.mobilenet.preprocess_input(output_tensor, data_format="channels_last")
        return output_tensor

    @tf.function(input_signature=(tf.TensorSpec(shape=[None, None, 3], dtype=tf.float32)))
    def data_augmentation(input_tensor):
        output_tensor = tf.image.random_flip_left_right(input_tensor)
        output_tensor = tf.image.random_flip_up_down(output_tensor)
        output_tensor = tf.image.random_brightness(output_tensor, max_delta=0.25)
        return output_tensor

    all_annotations = pd.read_csv(base_dir / "annotations" / "all_annotations.csv")
    class_count = all_annotations.groupby("split").apply(lambda group: group.label.value_counts())

    #%% Train model
    margin = 0.05
    k_shot = 4
    cache = base_dir / "cache"
    datasets = all_annotations.groupby("split").apply(
        lambda group: (
            group.pipe(
                ToKShotDataset(
                    k_shot=k_shot,
                    preprocessing=compose(preprocessing, data_augmentation),
                    cache=str(cache / group.name),
                    reset_cache=False,
                    dataset_mode="with_cache",
                    # max_shuffle_buffer_size=max(class_count),  # can slow down a lot if classes are big
                )
            )
        )
    )

    batch_size = 64
    encoder.trainable = False
    optimizer = Adam(lr=1e-4)
    model.compile(
        optimizer=optimizer,
        loss=class_consistency_loss,
        metrics=[
            accuracy(margin),
            binary_crossentropy(),
            max_crossentropy,
            std_crossentropy,
            same_image_score,
            top_score_classification_accuracy,
        ],
    )
    model.fit(
        datasets["train"].batch(batch_size).repeat(),
        steps_per_epoch=len(class_count["train"]) * k_shot // batch_size * 150,
        validation_data=datasets["val"].batch(batch_size).repeat(),
        validation_steps=max(len(class_count["val"]) * k_shot // batch_size, 100),
        initial_epoch=0,
        epochs=3,
        callbacks=callbacks,
    )

    encoder.trainable = True
    optimizer = Adam(lr=1e-5)
    model.compile(
        optimizer=optimizer,
        loss=class_consistency_loss,
        metrics=[
            accuracy(margin),
            binary_crossentropy(),
            max_crossentropy,
            std_crossentropy,
            same_image_score,
            top_score_classification_accuracy,
        ],
    )
    model.fit(
        datasets["train"].batch(batch_size).repeat(),
        steps_per_epoch=len(class_count["train"]) * k_shot // batch_size * 150,
        validation_data=datasets["val"].batch(batch_size).repeat(),
        validation_steps=max(len(class_count["val"]) * k_shot // batch_size, 100),
        initial_epoch=3,
        epochs=30,
        callbacks=callbacks,
    )

    #%% Evaluate on test set. Each batch is a k_shot, n_way=batch_size / k_shot task
    model.load_weights(str(base_dir / "best_loss.h5"))
    model.evaluate(
        datasets["test"].batch(batch_size).repeat(), steps=max(len(class_count["test"]) * k_shot // batch_size, 100)
    )

    #%% Export artifacts
    classifier = Sequential([encoder, Classification(support_layer.kernel)])
    tf.saved_model.save(classifier, "siamese_nets_classifier/1", signatures={"preprocessing": preprocessing})