"loss": class_consistency_loss,
        "metrics": [classification_accuracy(ascending=False), class_consistency_loss, BinaryCrossentropy()],
    },
]
projectors = [
    {"name": "", "projector": []},
    {"name": "_l2_normalize", "projector": [Lambda(lambda x: tf.math.l2_normalize(x, axis=1))]},
    {"name": "_dense_10", "projector": [Dense(10)]},
    {"name": "_dense_128", "projector": [Dense(128)]},
]
for experiment, projector in itertools.product(experiments, projectors):
    pprint(experiment)
    pprint(projector)
    for i in range(10):
        encoder.load_weights(str(output_dir / "initial_encoder.h5"))
        model = Sequential([encoder, *projector["projector"], GramMatrix(kernel=experiment["kernel"])])
        model.compile(
            optimizer="adam", loss=experiment["loss"], metrics=experiment["metrics"],
        )
        model.fit(
            train_dataset.map(lambda x, y: (tf.image.convert_image_dtype(x, tf.float32), get_dummies(y)[0])).repeat(),
            epochs=100,
            steps_per_epoch=train_steps,
            validation_data=val_dataset.map(
                lambda x, y: (tf.image.convert_image_dtype(x, tf.float32), get_dummies(y)[0])
            ).repeat(),
            validation_steps=val_steps,
            callbacks=[TensorBoard(str(output_dir / f"{experiment['name']}{projector['name']}_{i}"))],
        )
        results += [
            {
#%% Train
experiments = [
    {
        "name": "binary_crossentropy",
        "loss": ClippedBinaryCrossentropy(upper=0.75)
    },
    {
        "name": "class_consistency",
        "loss": ClassConsistencyLoss()
    },
]
for experiment in experiments:
    pprint(experiment)
    encoder.load_weights(str(output_dir / "initial_encoder.h5"))
    model = Sequential([encoder, GramMatrix(kernel="LearntNorms")])
    model.compile(
        optimizer="adam",
        loss=experiment["loss"],
        metrics=[classification_accuracy(ascending=False)],
    )
    model.fit(
        train_dataset.repeat(),
        epochs=10,
        steps_per_epoch=train_steps,
        validation_data=val_dataset.repeat(),
        validation_steps=val_steps,
        callbacks=[
            TensorBoard(str(output_dir / experiment["name"])),
            EarlyStopping(patience=10)
        ],
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 preprocessing(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 = {
        split: all_annotations.loc[lambda df: df.split == split].pipe(
            ToKShotDataset(k_shot=k_shot,
                           preprocessing=data_augmentation,
                           cache=str(cache / split),
                           reset_cache=False))
        for split in set(all_annotations.split)
    }

    batch_size = 64
    encoder.trainable = False
    optimizer = Adam(lr=1e-4)
    model.compile(
        optimizer=optimizer,
        loss=class_consistency_loss,
        metrics=[
            accuracy(margin),
            ClippedBinaryCrossentropy(),
            MaxBinaryCrossentropy(),
            StdBinaryCrossentropy(),
            same_image_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),
            ClippedBinaryCrossentropy(),
            MaxBinaryCrossentropy(),
            StdBinaryCrossentropy(),
            same_image_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})
config = projector.ProjectorConfig()
embedding = config.embeddings.add()
embedding.tensor_name = key_to_use

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(
           kernel_size=2,
           padding="same",
           activation="relu",
           input_shape=(28, 28, 1)),
    MaxPooling2D(pool_size=2),
    Dropout(0.3),
    Conv2D(filters=32, kernel_size=2, padding="same", activation="relu"),
    MaxPooling2D(pool_size=2),
    Dropout(0.3),
    Flatten(),
    Dense(256, activation=None),  # No activation on final dense layer
    Lambda(
        lambda x: tf.math.l2_normalize(x, axis=1)),  # L2 normalize embeddings
])
encoder.save_weights("initial_encoder.h5")
support_layer = GramMatrix(kernel=Lambda(lambda inputs: tf.math.reduce_sum(
    tf.square(inputs[0] - inputs[1]), axis=1)))
model = Sequential([encoder, support_layer])


#%% Build datasets
def preprocessing(input_tensor):
    return tf.cast(input_tensor, tf.float32) / 255


train_dataset, test_dataset = tfds.load(name="mnist",
                                        split=["train", "test"],
                                        as_supervised=True)
train_dataset = train_dataset.shuffle(1024).batch(32)
test_dataset = test_dataset.batch(32)

#%% Save test labels for later visualization in projector https://projector.tensorflow.org/
Beispiel #6
0
cv = StratifiedKFold(5)

for train, test in cv.split(X, Y):
    x_train, y_train = X.iloc[train], Y.iloc[train]
    x_test, y_test = X.iloc[test], Y.iloc[test]
    x_support, x_query, y_support, y_query = train_test_split(x_train,
                                                              y_train,
                                                              test_size=0.15,
                                                              stratify=y_train)

    # create the model
    input_shape = x_support.shape[1]  # first shape is batch_size

    # %% Training
    encoder = Dense(73)
    support_layer = GramMatrix("DenseSigmoid")
    model = Sequential([encoder, support_layer])
    model.compile(optimizer="Adam",
                  loss=BinaryCrossentropy(),
                  metrics=[classification_accuracy(), min_eigenvalue])
    model.fit(x=x_support,
              y=y_support,
              validation_data=([x_query], [y_query]),
              epochs=5)

    # model = XGBClassifier(class_weights=[1,5])
    # model.fit(x_train, y_train)ddd

    y_pred = model.predict_proba(x_test)[:, 1]
    print_results(y_test, y_pred)