В рамках моего учебного процесса, после SchoolofAI Paris и курса машинного обучения, который я организовываю для организации 19AI, я начал машинное обучение с помощью нового курса fast.ai и применил первый урок к своим собственным данным и поэкспериментировал с моими боковая сторона.
Цель этой статьи - дать быстрое первое знакомство с fast.ai и тем, как быстро создать первую модель.
Я решил использовать конкурс Kaggle Признание цветка для набора данных (более 4000 изображений 5 классов) и запустить его в Google Colab.
Сбор данных
Я сделал это старым способом, загрузив файлы и экспортировав их на Диск, прежде чем заметил, что вы можете напрямую импортировать данные из Kaggle в Google Colab… В следующий раз будет лучше.
На данный момент я только что создал файл Jupyter и папку с данными в одной подпапке.
# in order to link the content of your drive to you jupyter file from google.colab import drive drive.mount(‘/content/drive’)
Инициализация всего
Давайте сначала определим, где я могу найти данные:
p = pathlib.Path('./drive/My Drive/your_path/') path = p.absolute()/'flowers'
Проверяя структуру данных, обратите внимание, что здесь все картинки классифицируются по меткам.
path.ls() [PosixPath('/content/drive/My Drive/your_path/flowers/rose'), PosixPath('/content/drive/My Drive/your_path/flowers/tulip'), PosixPath('/content/drive/My Drive/your_path/flowers/dandelion'), PosixPath('/content/drive/My Drive/your_path/flowers/daisy'), PosixPath('/content/drive/My Drive/your_path/flowers/sunflower'), PosixPath('/content/drive/My Drive/your_path/flowers/models')]
Библиотека fast.ai предоставляет удобный способ получения метки в зависимости от имени папки внутри класса ImageDataBunch.
С помощью метода from_folder () мы сразу определим следующие вещи:
- Корень основной папки. В нашем случае: цветы.
- Коэффициент набора проверки. Это определение X% набора данных в качестве набора для проверки и того, что остается в качестве набора для обучения.
- Изменение размера импортируемых изображений, чтобы все они были одинакового размера.
- Используйте изменение изображения, чтобы иметь больший набор данных.
data = ImageDataBunch.from_folder(path, train = 'data', valid_pct = 0.2, size = 224, ds_tfms = get_transforms())
Мы нормализуем данные, чтобы подготовить сетевую сеть к приему данных, которые она действительно может прочитать как можно эффективнее.
data.normalize(imagenet_stats)
Теперь, когда у нас есть все данные, давайте убедимся, что все в порядке:
Тренировочный процесс
Когда данные готовы, мы можем создать пустой CCN с помощью create_cnn (). Кроме того, мы уже можем дать параметры для его настройки. Сейчас мы определяем:
- Ссылка на наши предварительно обработанные данные
- Предварительно обученная архитектура, которую мы хотели бы, чтобы у CNN уже была
- Цель CNN: здесь цель - максимально снизить error_rate.
learn = create_cnn(data, models.resnet34, metrics=error_rate)
Это та часть, которой я не особо горжусь, но надеюсь, что это поможет другим не повторять ту же ошибку.
Я начал процесс обучения на 4 эпохах (эпоха - это цикл, в котором все данные проверяются один раз):
learn.model learn.fit_one_cycle(4)
Неудивительно, что это заняло у меня слишком много времени, чтобы обработать: 4,5 мин. Действительно, я начал обрабатывать 4.000+ картинок. Четыре раза. Хорошие результаты все же.
Поэтому, прежде чем пробовать что-либо еще, я создал меньший набор данных: ~ 400 изображений.
Этот набор поможет мне настроить гиперпараметры перед тем, как начать процесс с 4000+ картинками. С этим новым набором данных я могу обрабатывать их намного быстрее. Давайте запустим lr_find, чтобы проверить кривую обучения / скорости:
Мы, несомненно, могли бы нацелиться на лучший LR, между 5e-3 и 2e-2, в конце склона.
Давайте обучим модель на этих 400 изображениях со следующим lr:
learn.fit_one_cycle(8, max_lr=slice(5e-3, 2e-2))
Давайте теперь снова проанализируем соотношение скорость обучения / потери после размораживания модели. Это поможет нам получить максимум от нашей CNN, минимизируя потери.
learn.unfreeze() learn.lr_find()
После построения мы можем определить лучший LR: от 2e-4 до 1e-6.
learn.fit_one_cycle(8, max_lr=slice(1e-6, 1e-2))
Результат меня устраивает. Мы получили 3,2 улучшения по сравнению с исходной моделью и заканчивая точностью 91,2%.
Теперь, когда я доволен результатами, я могу запустить ту же настройку на полных данных для других эпох.
94,3% точность. Не мог надеяться на лучшее с первого раза.
Всегда интересно проверить, где были самые большие ошибки, и посмотреть, является ли это честной ошибкой или есть настоящая проблема в модели.
Давайте сначала проанализируем общую ошибку.
interp = ClassificationInterpretation.from_learner(learn) interp.plot_confusion_matrix(figsize=(5,5), dpi = 120)
Мы видим, что в модели есть проблемы с классификацией роз и тюльпанов. Это меня не сильно удивляет, так как я не могу отличить их до того, как они полностью распустились. Все остальные соотношения звучат неплохо.
Давайте теперь проверим самую высокую ошибочную классификацию.
interp.plot_top_losses(9, figsize=(15, 11))
Я понятия не имею, что это за пятая картина, а картину в левом нижнем углу, конечно, нелегко классифицировать.
Мы видим 3 проблемы с тюльпанами / розами, как указано в матрице путаницы. Остальные изображения либо слишком уменьшены, либо увеличены во время раннего цветения, что затрудняет их анализ. Все хорошо.
На сегодня все кончено :-)
Следующая статья будет о скорости обучения и о том, что это такое на самом деле.
Если у вас есть отзывы, чтобы улучшить это или задать вопрос, не стесняйтесь спрашивать!
Также спасибо Реми за его статью, которая помогла мне сформировать мою.