Всем файлам стоит лежать в одной папке. Список необходимых файлов/папок:
- model_learning.ipynb - ноутбук с обучением модели
- process_results.json- текстовый файл с ответами
- saved_model - обученная модель
- Usage_script.ipynb - ноутбук с скриптом
- Usage_script.py- скрипт
- internship_data.tar.gz - архив с данными для обучения
- faces - папка, в которой лежат тестовые фотографии. Имя папки можно менять- оно вводится в скрипте
Необходимо обучить нейросеть, способную по входному изображению лица определять пол человека на изображении.
tarfile matplotlib.pyplot time json copy PIL numpy torch.nn.functional as F torch torchvision os natsort numpy glob
Для обучения и тестирования будет предоставлен набор из 100 тысяч картинок, из которых 50 тысяч будут содержать изображения лиц мужчин, а остальные 50 тысяч - изображения лиц женщин. В загруженном архиве есть две папки, male и female, с изображениями лиц мужчин и женщин соответственно. Разбить данные на тренировочный и валидационный сет предлагается самостоятельно.
Для работы был выбран Фреймворк PyTorch. Порядок:
- обучить модель (model_learning.ipynb) или сразу использовать обученную мной (saved_model),
- запустить скрипт и указать имя (расположение) папки с тестовыми фото.
- Ответы сохранятся в process_results.json
model_learning.ipynb
Фотографии разархивированы из internship_data.tar.gz с помощью tar и помещены в одноимённую папку "internship_data".
В transforms для обучения модели были объединены следующие шаги изменения фотографий:
- Лица случайным образом повернули на угол до 45 градусов
- Ре-мештабированы и приведены к одинаковому размеру- количество узлов на входе в нейросеть зафиксировано. 224 выбрал, потому что так выбирают большинство из тех, кто работает с фотографиями
- Переведены в серый, но сохранены все три канала. R==G==B==255, чтобы не мучиться с изменением размерности каждого узла в архитектуре нейросети
- Загнаны в тензор
- Нормализованы- так рекомендуется поступать с фото для лучшего обучения
Валидационная выборка сделана с помощью SubsetRandomSampler, размером 0.2 от всех данных. Сформированы батчи- тренировочные и валидационные. Тут вкралась ошибка, из-за которой accuracy на валидационной выборке при обучении нужно в уме умножать на четыре- значения точности считались без учёта разной длины dataloader'ов.
С помощью imshow и обратных действий по нормализации и переводу из тензора посмотрели, что получилось с фотографиями.
В качестве модели была взята resnet18, хорошо подходящая под условия задачи
Количество выводящих узлов изменено с 512 до двух- (мужчина и женщина). Веса и сдвиги по умолчанию разморожены. Сначала я разморозил их вручную, потом обратил на это внимание.
Код с finetuning взял с сайта pytorch и незначительно подправил- отключил is_inception, чтобы уменьшить нагрузку на своё домашнее железо и подправил алгоритм проверки качества (в их примере валидационная выборка лежит в своей отдельной папке, когда успешно забыл про четвёрку при учёте точностей. Ссылка:
Остановился на пяти эпохах и запустил обучение модели на своей видеокарте с помощью 'cuda'
- функция потерь- кросс-энтропия
- оптимизатор - Стохастический Градиентный Спуск (SGD), lr = .001, momentum = 0.9.
Итоговое значение точности на валидационной выборке не превысило 80%- до того, как включил случайные повороты на 45 градусов, достигало 90. Считаю, что это к лучшему- мало ли, что попадётся при тестировании.
Параметры модели сохранены в ту же папку, где лежат данные, код обучения, код тестирования, с помощью torch.save
Usage_script.ipynb, Usage_script.py
Алгоритм прост: вводится имя папки, из неё считываются фотографии, делается предсказание и выводится в созданный текстовый файл.
В тестовой выборке для предобработки не делается поворот на 45 градусный угол- это ни к чему
В loader загружаем сразу все файлы- почему бы и нет.
В модель добавляется последний слой, softmax(). Почему-то в оригинальном реснет18 его нет.
Результаты определяются через if. Сравнивается, вероятность какого класса выше, и в зависимости от этого в словарь добавляется тот или иной ответ. male/female. Результаты сохраняются в process_results.json