Публикация Школы траблшутеров

Как разработать модель для классификации изображений

Время чтения: 8 мин 35 сек
6 ноября 2025 г. Просмотров: 105

Аналитика, Искусственный интеллект | Олег Брагинский, Константин Строев

Основатель «Школы траблшутеров» Олег Брагинский и ученик Константин Строев подробно рассказывают, как компьютер видит и обрабатывает визуальные данные, изучают алгоритм KNN, разбирают основы нейронных сетей на примере распознавания рукописных цифр и цветов.

Разработка модели для классификации изображений включает сбор данных, предобработку, выбор подходящего алгоритма, обучение, оценку и, при необходимости, улучшение модели.

В качестве примеров рассмотрим два случая:

  • классификацию изображений цветов с помощью KNN и нейросетей
  • распознавание рукописных цифр на основе датасета EMNIST

Для начала работы с изображениями необходимо импортировать основные библиотеки: numpy для работы с массивами, matplotlib.pyplot для визуализации, sklearn для классических алгоритмов машинного обучения, PIL.Image для загрузки и обработки изображений, а также torch и torchvision или tensorflow и keras для построения нейросетей.

Первый шаг разработки модели – загрузка и предобработка данных. Для датасета EMNIST можно использовать встроенные загрузчики из torchvision.datasets или добавить вручную. Для цветов изображения загружаются из директорий, где каждая папка соответствует отдельному классу.

После загрузки данные необходимо разделить на обучающую и тестовую выборки. Это делается с помощью train_test_split из sklearn. Важно использовать параметр stratify, чтобы сохранить пропорции классов. Для одинакового соотношение классов и для корректной оценки модели.

Для классических алгоритмов, таких как KNN, важно стандартизировать данные. Это делается с помощью StandardScaler. Стандартизация приводит все признаки к нулевому среднему и единичной дисперсии, что особенно важно для алгоритмов, основанных на расстояниях.

Без этой процедуры признаки с большими значениями будут доминировать в вычислении расстояний, что негативно скажется на точности модели. Кроме того, стандартизация ускоряет сходимость градиентных методов при обучении нейросетей.

Теперь можно обучить модель KNN. Для этого используется KNeighborsClassifier. После подготовки данных модель дошлифовывается с помощью метода fit(), который в случае KNN просто запоминает обучающие примеры.

Выбор оптимального числа соседей K критически важен для достижения хорошего качества: слишком малое значение приводит к переобучению, большое – к недообучению. Поэтому рекомендуется провести перекрёстную проверку для подбора оптимального гиперпараметра.

Для оценки качества модели используются метрики, такие как classification_report и confusion_matrix. Визуализация confusion matrix может быть выполнена с помощью seaborn.heatmap.

Инструменты позволяют не только получить общую точность, но и детально проанализировать, какие классы модель путает. Это особенно полезно при несбалансированных данных, когда accuracy может быть обманчиво высокой, в то время как качество для редких классов остаётся низким.

Для построения нейросетей можно использовать torch.nn. Архитектура состоит из трёх слоёв: входного, скрытого с нелинейной активацией и выходного. В данном примере используется ReLU как активационная функция, которая помогает сети обучаться нелинейным зависимостям.

Обучение сети в PyTorch выглядит следующим образом. В процессе ознакомления используется цикл по эпохам, где на каждой итерации данные проходят прямой проход через сеть, вычисляется функция потерь, а затем происходит обратное распространение ошибки.

Оптимизатор Adam, обновляет веса сети на основе вычисленных градиентов. Важно не забывать обнулять градиенты перед каждым шагом с помощью optimizer.zero_grad(), иначе градиенты будут накапливаться и обучение станет нестабильным.

Для сохранения и загрузки модели используются функции torch.save и torch.load. Сохранение весов позволяет не обучать сеть заново при каждом запуске. Рекомендуется запоминать только словарь состояния (state_dict). Сначала создать экземпляр модели, затем загрузить сохранённые веса.

Для инференса важно применять те же трансформации, что и при обучении. Изображение должно быть нормализовано и преобразовано в тензор. Это делается с помощью transforms.ToTensor() и других трансформаций из torchvision.transforms.

Для улучшения модели можно использовать transfer learning. В Keras можно загрузить предобученную модель MobileNetV2 и добавить к ней собственные слои. Это даёт возможность использовать богатые признаки, выученные на ImageNet.

Сначала тренируют только верхние слои (head) с замороженной базой, затем при необходимости размораживают часть слоёв и дообучают сеть с малым learning rate (fine-tuning). Полезно подключать EarlyStopping, ModelCheckpoint и ReduceLROnPlateau, чтобы избежать переобучения и автоматически сохранять лучшую версию модели.

Для упаковки модели в библиотеку можно создать Python-пакет. Структура обычно включает модули для загрузки, предобработки изображений, утилит и файла конфигурации (setup.py или pyproject.toml), а также requirements.txt и тесты.

Содержимое mypkg/model.py демонстрирует основные функции для работы с моделью в production-среде. Реализует методы загрузки, предобработки входных данных и выполнения предсказаний. Код в model.py может включать обработку ошибок, логирование и валидацию.

Такой пакет удобно устанавливать через pip install -e, запускать тесты pytest и подключать как зависимость в веб-сервисе или CLI. Режим разработки (-e flag) позволяет вносить изменения в код пакета без необходимости переустановки, что значительно ускоряет процесс разработки и отладки.

Для тестирования можно использовать pytest. Для мониторинга в продакшене применяются логи и метрики: logging.info(f'Prediction: {pred}'). Также применяется mlflow для отслеживания экспериментов. Для развёртывания в облаке – сервисы для разработки. Локально – Docker.

Распознавание рукописных цифр на основе датасета EMNIST

Цель и задача: написать простую нейросеть на Python и научить распознавать рукописные цифры на базе публичного датасета EMNIST (60’000 изображений 28×28 пикселей, оттенки серого). Рекомендуемые библиотеки: numpy (обязательно), matplotlib (по желанию для визуализации).

Предобработка: нормализация пикселей в [0,1], преобразование формы из (60000, 28, 28) в (60000, 784), one-hot кодирование меток в форму (60000, 10).

Архитектура нейросети

  • три слоя: входной (784 нейрона = 28×28), скрытый (в примере – 20 нейронов), выходной (10 нейронов – для цифр 0–9)
  • весовые матрицы: первая – связывает вход и скрытый (shape 784×20 или 20×784 в зависимости от реализации), вторая – скрытый и выход (20×10)
  • инициализация весов случайна (в диапазоне [-0.5, 0.5]).

Bias – фиктивный нейрон со значением 1, не имеет входных синапсов, нужен чтобы сдвигать функцию активации вправо или влево. Придаёт гибкости помимо вертикального смещения.

Обратное распространение (backpropagation): Основной шаг обучения – вычисление градиентов потерь по весам и корректировка весов (обновление синапсов). Алгоритм повторяется справа-налево через слои, для каждой дополнительной скрытой прослойки операция повторяется.

Обучение и результаты: после нескольких эпох достигается 93% точности на задаче распознавания цифр. Вывод прогресса между эпохами (loss/accuracy). Обученные веса можно сохранить методом numpy.save (формат *.npy/*.npz) и позже загрузить numpy.load для инференса.

Классификация изображений цветов с помощью KNN и нейросетей

Задача: классифицировать изображения пяти видов цветов (daisy, sunflower, rose, tulip, dandelion) с помощью простого пайплайна на Python и алгоритма KNN.

Цветное изображение представляется как H×W×3 (R, G, B), пиксели принимают значения 0..255. Для модели изображения нормализуют (делят на 255 и диапазон 0..1) при классических методах «вытягивают» в вектор признаков (64×64×3 = 12’288 признаков).

Обучение и результаты: обойти папки по классам, открыть изображения, привести к RGB и единому размеру, нормализовать и преобразовать в вектор. Проверить формы и типы массивов X и Y. Показывать случайные образцы для контроля качества данных.

Разделение train_test_split (80%/20%) с stratify=y для сохранения пропорций классов.

Стандартизация: fit на обучающей выборке и transform на тестовой. Обучение KNN. Оценка предсказания на тестах accuracy, classification_report, анализ через confusion matrix.