Курс Fast.ai — это потрясающий бесплатный онлайн-курс для получения практического опыта глубокого обучения. Я начал смотреть лекции давно и никогда не заканчивал с ним реальный проект, так как всегда хотел использовать его только для данных, связанных с моим докторским исследованием, которое находится на КТ грудной клетки; Обычно не так просто получить большой хорошо сохранившийся и помеченный набор данных КТ легких, чтобы начать играть с CNN. Наконец, на этот раз я решил не отставать от курса и следовать советам других людей начать с небольшого проекта, завершить его, а затем перейти к более сложным проектам.

Этот блог посвящен практическому опыту использования метода переноса обучения с ResNet для классификации типов цветов. Я хотел показать, как легко можно начать применять глубокое обучение, и помочь другим мотивировать это. Кроме того, когда я впервые начал HW курса, я столкнулся с несколькими ошибками еще до того, как смог прочитать данные, однако то, что другие смогли преодолеть ошибки и создать настоящий проект, помогло мне сохранить мотивацию; Так что я тоже хочу внести свой вклад в это.

Хотя я не собираюсь обсуждать теорию, лежащую в основе CNN, трансферного обучения, ResNet и т. д., вот краткое введение в ResNet, в котором показано, почему я буду использовать эту конкретную сеть в качестве основы для своего проекта:

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

Я получил данные изображения от Kaggle Распознавание цветов. Изображения разделены на пять классов: ромашка, тюльпан, роза, подсолнух, одуванчик.

  1. Подготовка данных

Хотя, как и многие из вас, я также очень заинтересован в создании собственной CNN, разрабатывая весь код самостоятельно построчно с тем, что я узнал при построении моделей нейронной сети (например, с Tensorflow). Однако на данный момент я хочу придерживаться библиотеки Fast.ai, чтобы изучить PyTorch. (Примечание: в этом блоге я буду обсуждать только высокоуровневое применение PyTorch через библиотеки Fast.ai и не буду вдаваться в подробности фреймворка PyTorch)

Я использую фантастический и бесплатный Google Colab, и для установки библиотеки и импорта необходимых библиотек я запускаю:

!curl -s https://course.fast.ai/setup/colab | bash
######### Or the following:
#!pip install torch_nightly -f https://download.pytorch.org/whl/nightly/cu92/torch_nightly.html
#!pip install fastai

Бывают случаи, когда разработчики курса обновляют библиотеки, и вдруг команда меняется, и мой код выдает ошибку. Поэтому рекомендуется всегда запускать приведенный выше код, чтобы поддерживать обновленную библиотеку. Вы также можете проверить свою версию библиотеки и сравнить ее с последней версией на Github курса или на его форуме.

!pip show fastai

Импортируйте библиотеку:

from fastai import *
from fastai.vision import *
from fastai.metrics import error_rate

Загрузите данные Flower на свой Google Диск и смонтируйте диск, чтобы вы могли получить доступ к данным в colab:

from google.colab import drive
drive.mount('/content/gdrive', force_remount=True)
root_dir = "/content/gdrive/My Drive/"
base_dir = root_dir + 'deep_learning_data/'
path = base_dir + 'flowers/'

Прочтите данные и взгляните на них:

Поэтому я использовал библиотеку Fast.ai для чтения изображений, нормализации данных и изменения размера изображений до 224 на 224 пикселя. Стоит отметить, что при обучении с передачей (т. Е. При использовании предварительно обученной сети) мы должны нормализовать изображения, используя нормализацию, примененную во время разработки модели (т. Е. Для Resnet мы должны использовать нормализацию из сетевых данных изображения).

np.random.seed(42)
tfms = get_transforms(do_flip=False)
# Read the data. The following command will divide the data into train and validation set. bs: determines the batch size during training.
# reducing the bs and the size will speed up the training. 
data = ImageDataBunch.from_folder(path, valid_pct=0.2,
ds_tfms=get_transforms(), size=224, bs = 32,                                    num_workers=4).normalize(imagenet_stats)
# look at the classes:
print(data.classes, data.c, len(data.train_ds), len(data.valid_ds))
# show some images
data.show_batch(rows= 3,  figsize=(7,8))

2. Выполнить классификацию

Теперь начинается самое интересное! Давайте классифицировать изображения!

С библиотекой fast.ai вы можете сделать это двумя способами: 1) использовать предварительно обученную архитектуру модели и добавить к ней несколько слоев и обучить ее веса, 2) обучить и точно настроить всю модель, чтобы лучше настроить ее. к нашему набору данных.

1. Начните с той же архитектуры предварительно обученной модели и обучите модель с новыми данными цветов в течение 4 эпох.

learn = create_cnn(data, models.resnet34, metrics=error_rate)
learn.fit_one_cycle(4) 

2. Разморозьте модель, запустите скрипт, чтобы найти оптимальную скорость обучения, и точно настройте всю модель.

learn.lr_find()
learn.recorder.plot()
learn.unfreeze()
learn.fit_one_cycle(1, max_lr=slice(1e-6,1e-4))

Оптимальная скорость обучения была получена из следующего графика, где скрипт lr_find рассчитал потери для различных скоростей обучения. Мы видим, что после 1e-4 потери начинают увеличиваться, поэтому мы выбираем диапазон (1e-6,1e-4), что означает, что более ранние слои сети начинают обучаться с меньшей скоростью обучения и по мере прохождения более глубоких слоев , скорость обучения увеличивается до максимального значения 1e-4. В основном то, что мы делаем здесь, заключается в том, что мы изменяем более ранние слои меньше, чем более глубокие слои, поскольку более глубокие слои — это те, которые изучают более конкретные свойства изображения, и мы хотим, чтобы они стали более умными, чтобы лучше понимать цветы, а не изображения. они прошли обучение (например, ImageNet).

Мой опыт работы с цветочными данными заключался в том, что обучение модели занимало гораздо больше времени. Сначала я уменьшил размер пакета до 16, а размер изображения до 100, чтобы просто получить представление о производительности.

3. Оценка эффективности

Нам нужно понять, где наша модель работает плохо. Мы можем посмотреть на изображения, которые были неправильно классифицированы.

interp = ClassificationInterpretation.from_learner(learn)
losses,idxs = interp.top_losses()
interp.plot_top_losses(9, figsize=(15,11))

когда слои модели были заморожены и обучены в 4 эпохи, моя точность составила около 93%. Я посмотрел на несколько примеров, где модель работала неправильно, и я вижу, что бывают случаи, когда модель путает розу и тюльпан или путает одуванчик с подсолнухом. Я также выяснил, что некоторые изображения в данных вообще не имеют цветов! и мне не удалось удалить эти бесполезные изображения из моего набора данных перед тренировкой. Таким образом, извлеченный урок был таким: убедитесь в качестве ваших данных!

Разморозка модели и ее обучение на 2 эпохах позволило немного улучшить производительность на 1%.

Сохраните модель или экспортируйте ее для будущего использования:

learn.export()   # will save the model with the name:   'export.pkl' in the working directory.
# or run
learn.save('flower_classifier')