Как реализовать SVM с разными типами ядер поверх предварительно обученной модели? - PullRequest
0 голосов
/ 26 мая 2020

Я пытаюсь реализовать SVM поверх модели Mobi lNet v2 (https://github.com/keras-team/keras-applications/blob/master/keras_applications/mobilenet_v2.py) в тензорном потоке 2.0 с помощью keras. Цель состоит в том, чтобы использовать его для классификации цветов из набора данных https://www.kaggle.com/alxmamaev/flowers-recognition. Я хочу протестировать поведение SVM с ядрами Linear , Quadrati c и Exponential ядром в качестве последнего уровня модели Mobi lNet, однако я новичок в машинном обучении, поэтому не знаю, как это сделать.

Это текущая модель, в которой для целей классификации используется плотный слой.

class FlowerModel(tf.keras.Model):
    def __init__(self, name, image_shape, classes):
        super(FlowerModel, self).__init__(name=name)
        self.core = tf.keras.applications.MobileNetV2(
            include_top=False, weights="imagenet"
        )
        self.global_average_layer = tf.keras.layers.GlobalAveragePooling2D()
        self.predictions = tf.keras.layers.Dense(
            classes, activation=tf.keras.activations.softmax
        )

    def freeze_core(self):
        self.core.trainable = False

    def freeze_core_layers(self):
        layers = [layer for layer in self.core.layers]
        for layer in layers:
            layer.trainable = False

    def unfreeze_block(self, block):
        layers = [layer for layer in self.core.layers]
        block_name = "block_%d_" % block
        fl = filter(lambda x: x.name.startswith(block_name), layers)
        for layer in fl:
            layer.trainable = True

    def call(self, inputs):
        x = self.core(inputs)
        x = self.global_average_layer(x)
        x = self.predictions(x)
        return x

Как обучается модель:

import seed 
import datetime
import os

import tensorflow as tf
import numpy as np
from data.augmentation import expand_dataset
from data.dataset import DataProcessor
from visualization import visualize

def load_dataset():
    # Load dataset
    dp = DataProcessor(DATA_DIR, IMG_WIDTH, IMG_HEIGHT, SEED)
    ds_train, ds_validation, ds_test = dp.load(
        TRAIN_RATIO, VALIDATION_RATIO, TEST_RATIO
    )

    # Data preprocessing
    ds_train = expand_dataset(ds_train, 4)
    ds_train = dp.prepare(ds_train, BATCH_SIZE, True, True)
    ds_validation = dp.prepare(ds_validation, BATCH_SIZE)
    ds_test = dp.prepare(ds_test, BATCH_SIZE)

    return ds_train, ds_validation, ds_test

def train(
        model: tf.keras.Model,
        ds_train: tf.data.Dataset,
        ds_validation: tf.data.Dataset
):
    # Callbacks
    log_dir = os.path.join(
        MODEL_LOGS_DIR, model.name, datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
    )
    tensorboard_callback = tf.keras.callbacks.TensorBoard(
        log_dir=log_dir, histogram_freq=1
    )

    # Model training
    train_history = model.fit(
        ds_train,
        epochs=TRAINING_EPOCHS,
        batch_size=BATCH_SIZE,
        validation_data=ds_validation,
        steps_per_epoch=STEPS_PER_EPOCH,
        callbacks=[tensorboard_callback],
    )
    visualize.show_history(train_history, model.metrics_names)


def evaluate(model: tf.keras.Model, ds_test: tf.data.Dataset):
    # Model evaluation
    model.evaluate(ds_test, batch_size=BATCH_SIZE)



model = FlowerModel("flower classifier", IMG_SHAPE, CLASSES)
model.freeze_core()

model.build(INPUT_SHAPE)
model.compile(optimizer="adam", metrics=["accuracy", "top_k_categorical_accuracy"], loss=tf.keras.losses.hinge)

ds_train, ds_validation, ds_test = load_dataset()

model.freeze_core_layers()
train(model=model, ds_train=ds_train, ds_validation=ds_validation)
evaluate(model=model, ds_test=ds_test)
model.summary()

У меня есть две идеи решения этой проблемы:

  1. Используйте sckit-learn swm.SVC() модель (https://scikit-learn.org/stable/modules/svm.html). Используйте вывод theMobi lNet v2 (self.core.output) как часть метода вызова. Однако я не знаю, как преобразовать тензор вывода Mobi lNet v2 в массив numpy, и я не нашел никаких источников, объясняющих, как интегрировать вывод модели keras в качестве входных данных для sklearn swm.SVC().
  2. Однако я предпочитаю реализовать SVM с разными ядрами в качестве последнего уровня FlowerModel. Вот некоторые проблемы, связанные с topi c: https://github.com/keras-team/keras/issues/2588, Преобразование классификатора sklearn.svm SV C в реализацию Keras . К сожалению, ни один из них не объясняет мне, как сделать такую ​​реализацию для разных ядер.

Я новичок в машинном обучении, поэтому, вероятно, есть несколько простых решений, которые мне не хватает.

...