From d279468ef3f939b9f2083d6bc6799fd45c4d819b Mon Sep 17 00:00:00 2001 From: RoundRonin Date: Sun, 31 Mar 2024 19:22:32 +0300 Subject: [PATCH] Model supports settings, CLI cleanup --- image_recognition/cli.py | 31 +++++++++------------- image_recognition/modules/model.py | 25 ++++++++--------- image_recognition/modules/visualization.py | 4 +-- 3 files changed, 25 insertions(+), 35 deletions(-) diff --git a/image_recognition/cli.py b/image_recognition/cli.py index 7a5065c..4588673 100644 --- a/image_recognition/cli.py +++ b/image_recognition/cli.py @@ -23,91 +23,84 @@ def main(): # pragma: no cover height = 140 width = 90 image_size = (height, width) - # Больше -- быстрее, меньше -- точнее. В теории. batch_size = 32 - # Вышеописанная директория data_directory = "Data50" - # Разделение на тренировочные и тестовые данные в долях. Указывается доля тестовых данны (.2 по-умолчанию) validation_split = 0.2 i = importer(image_size, batch_size, data_directory, validation_split) # Получение имён классов, числа классов. - class_names = i.class_names num_classes = i.num_classes ## Обработка данных - # Вносится рандомизация (ротация, зум, перемещение). Также приводится яркость к понятному нейросети формату (вместо 0-255, 0-1). - i.generate_augmentation_layers(0.2, 0.1, 0.08) ### Применение слоёв обработки данных - i.apply_augmentation() ## Получение данных для модели - train_ds = i.train_ds val_ds = i.validation_ds ## Формирование модели - # Модель последовательная. Состоит из слоёв, каждый из которых исполняется после предыдущего. # В первом слое описывается форма подаваемых данных. Первые два параметра -- размеры изображения (описаны в начале). # Третий пораметр: 1 -- ч/б изображение, 2 -- RGB, 3 -- RGBA # Последний слой имеет число нейронов, равное количеству классов. + # Слои convolution 2D # Первое число -- количество фильтров, второе -- окно в пискислях (3 на 3, напрмиер), которым алгоритм проходит по изображению. # Каждый новый tuple -- новый слой Conv2D. Можно эксперементировать с числами. conv_descriptor = ( + (8, (3,3)), (16, (3,3)), - (32, (3,3)), - (16, (3,3)) + (8, (3,3)) ) - # Количсетво простых слоёв - dense_layer_number = 1 + # Количсетво простых слоёв, сильно повышать нет смысла (по умолчанию 1) + dense_layer_number = 2 m = model(image_size, num_classes, dense_layer_number, conv_descriptor) m.compile() # Обучение нейросети - # Число проходов по набору данных. Не всегда улучшает результат. Надо смотреть на графики. (50 по умолчанию, при малом наборе данных) epochs = 50 + # init_ -- методы, добавляющие функции, применяемые после каждой итерации. + # + # learning rate reduction уменьшает скорость обучения, когда сеть застряла (не улучшается точность), + # что может помочь преодолеть это состояние (overfitting) (по умолчанию включено) + # save at epoch делает сохранение сети после каждой итерации (по умолчанию отключено) m.init_learning_rate_reduction() # m.init_save_at_epoch() + # Сама тренировка m.train(train_ds, epochs, val_ds) + # Получение истории выполеннеия тренировки и модели history = m.history model_instance = m.model # Визуализация - pe = plotter_evaluator(history, model_instance, class_names) pe.calc_predictions(val_ds) ## Графики потерь и точности # Высокой должна быть и accuracy и val_accuracy. Первая -- точность на обучающей выборке, вторая -- на тестовой. # Когда/если точность на обучающей выборке начинает превосходить точность на тестовой, продолжать обучение не следует. - # Потери (loss) должны быть низкими. - pe.plot_loss_accuracy() ## Вычисление отчёта о качестве классификации # Значения accuracy, recall, f1 должны быть высокими. - pe.print_report() ## Матрица запутанности # Хорший способ понять, как именно нейросеть ошибается - pe.plot_confusion_matrix() diff --git a/image_recognition/modules/model.py b/image_recognition/modules/model.py index f41c04d..9bf7086 100644 --- a/image_recognition/modules/model.py +++ b/image_recognition/modules/model.py @@ -13,29 +13,26 @@ class model: model: keras.Model history: History - callbacks = [] + callbacks: list[keras.callbacks.Callback] = [] def __init__(self, image_size: tuple[int,int], num_classes: int, dense_layers_number: int, conv_descriptor: tuple): model = Sequential() - model.add(keras.Input(shape=image_size + (1, ))) - - model.add(Conv2D(16, (3,3), 1, activation='relu')) - model.add(MaxPooling2D()) - # model.add(Dropout(0.25)) + def add_Conv2D(conv_layer: tuple[int, tuple[int, int]]): + model.add(Conv2D(conv_layer[0], conv_layer[1], 1, activation='relu')) + model.add(MaxPooling2D()) + # model.add(Dropout(0.25)) - model.add(Conv2D(32, (3,3), 1, activation='relu')) - model.add(MaxPooling2D()) - # model.add(Dropout(0.25)) + model.add(keras.Input(shape=image_size + (1, ))) - model.add(Conv2D(16, (3,3), 1, activation='relu')) - model.add(MaxPooling2D()) - # model.add(Dropout(0.25)) + for i in range(len(conv_descriptor)): + add_Conv2D(conv_descriptor[i]) model.add(Flatten()) - model.add(Dense(256, activation='relu')) - # model.add(Dropout(0.25)) + for i in range(dense_layers_number): + model.add(Dense(256, activation='relu')) + # model.add(Dropout(0.25)) model.add(Dense(num_classes, activation = "softmax")) diff --git a/image_recognition/modules/visualization.py b/image_recognition/modules/visualization.py index 5e254b6..5c1cc23 100644 --- a/image_recognition/modules/visualization.py +++ b/image_recognition/modules/visualization.py @@ -61,5 +61,5 @@ def print_report(self): def plot_confusion_matrix(self): - fig, ax = plt.subplots(1, 2, figsize = (25, 8)) - ax = plot_confusion_matrix(self.labels, self.pred_labels, ax = ax[0], cmap= 'YlGnBu') \ No newline at end of file + plot_confusion_matrix(self.labels, self.pred_labels,cmap= 'YlGnBu') + plt.show() \ No newline at end of file