Я пытаюсь реализовать 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()
У меня есть две идеи решения этой проблемы:
- Используйте 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()
. - Однако я предпочитаю реализовать SVM с разными ядрами в качестве последнего уровня FlowerModel. Вот некоторые проблемы, связанные с topi c: https://github.com/keras-team/keras/issues/2588, Преобразование классификатора sklearn.svm SV C в реализацию Keras . К сожалению, ни один из них не объясняет мне, как сделать такую реализацию для разных ядер.
Я новичок в машинном обучении, поэтому, вероятно, есть несколько простых решений, которые мне не хватает.