Курс Fast.AI «Практическое глубокое обучение для программистов - версия 3» был начат в понедельник вечером Джереми и Рэйчел. Мне посчастливилось присоединиться к этой прямой трансляции на Youtube с 1000 других студентов со всего мира.

На первом уроке Джереми использовал Oxford-IIIT Pet Dataset от O. M. Parkhi et al., 2012 , в котором представлены 12 пород кошек и 25 пород собак для создания детализированной модели распознавания изображений и показано, как превзойти результаты оригинального исследования с помощью 10 строк кода.

Эта детализированная модель распознавания изображений смогла научиться различать эти 37 различных категорий. Согласно исходному исследовательскому документу, максимальная точность, которую они могли получить в 2012 году, составила 59,21% при использовании сложной модели, специально предназначенной для обнаружения домашних животных, с отдельными моделями Изображение, Голова и Тело для фотографий домашних животных. Однако Джереми смог достичь коэффициента ошибок 0,043507 с помощью Fast.AI Vision-Learner и архитектуры Resnet34. Он имеет основу сверточной нейронной сети, полностью подключенную головку с единственным скрытым слоем в качестве классификатора.

Войдите в меня!

В одном из моих предыдущих исследовательских проектов в Skava (мы создаем продукты и микросервисы для преобразования цифровой коммерции) я наткнулся на DeepFashion Database, крупномасштабный набор данных по распознаванию и извлечению моды (DeepFashion) для прогнозирования категорий и атрибутов одежды. Создано мультимедийной лабораторией Китайского университета Гонконга.

Тест прогнозирования категорий и атрибутов оценивает эффективность модели FashionNet при прогнозировании 50 категорий и 1000 атрибутов одежды. из данных изображений. Это большое подмножество DeepFashion Work, содержащее огромное количество описательных категорий и атрибутов одежды в дикой природе. На момент написания этой статьи она содержала 289 222 изображений одежды в 46 различных категориях одежды.

Для получения дополнительной информации о наборе данных посетите веб-сайт проекта: http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion.html

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

Подождите, так где же те 10 строк кода, которые могут побить исходный тест на точность исследования?

Ну вот (технически их всего 9)

from fastai import *
from fastai.vision import *
path = Path("data/cloth_categories/")
data = ImageDataBunch.from_csv(path, csv_labels="train_labels.csv", ds_tfms=get_transforms(), size=224)
data.normalize(imagenet_stats)
learn = create_cnn(data, models.resnet34, metrics=accuracy)
learn.fit_one_cycle(8)
learn.save('stage-1_sz-150')

Для тех, кто спешит, вот Репозиторий GitHub. Убедитесь, что он помечен, нет необходимости клонировать, просто загрузите его.

Для людей, которые увлечены DL и этой исследовательской статьей, пожалуйста, следуйте инструкциям.

Получение набора данных:

Http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion/AttributePrediction.html

На этой странице перейдите по ссылке Google Drive или Baidu Drive, а затем загрузите:

  • Изображения одежды (2,8 ГБ Zip-файл)
  • Аннотации категорий (текстовый файл)
  • Разделы Train / Val / Test (текстовый файл)

Убедитесь, что вы правильно цитируете авторов этого исследования и набора данных. Поскольку это самая сложная часть любого проекта ML & DL.

Огромное спасибо @Ziwei Liu, @Ping Luo, @Shi Qiu, @Xiaogang Wang и @Xiaoou Tang из Китайского университета Гонконга.

@inproceedings{liu2016deepfashion,
 author = {Ziwei Liu, Ping Luo, Shi Qiu, Xiaogang Wang, and Xiaoou Tang},
 title = {DeepFashion: Powering Robust Clothes Recognition and Retrieval with Rich Annotations},
 booktitle = {Proceedings of IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
 month = June,
 year = {2016} 
 }

Установка и настройка библиотек Fast.AI

# ОК, приступим к кодированию…

Импорт библиотек Fast.AI

from fastai import *
from fastai.vision import *

Загрузка данных

# Creating path object
path = Path("data/cloth_categories/")
# Creating data from CSV
data = ImageDataBunch.from_csv(path, csv_labels="labels.csv" ,ds_tfms=get_transforms(), size=150)
#Normalize dataset and augmentated image tranformation 
data.normalize(imagenet_stats)

Визуализировать данные

# show 8*8 grid of random images from our dataset
data.show_batch(rows=8, figsize=(14,12))

Ознакомьтесь с целевыми классами данных

print(data.classes)
print (len(data.classes),data.c)
>>> ['Blouse', 'Blazer', 'Button-Down', 'Bomber', 'Anorak', 'Tee', 'Tank', 'Top', 'Sweater', 'Flannel', 'Hoodie', 'Cardigan', 'Jacket', 'Henley', 'Poncho', 'Jersey', 'Turtleneck', 'Parka', 'Peacoat', 'Halter', 'Skirt', 'Shorts', 'Jeans', 'Joggers', 'Sweatpants', 'Jeggings', 'Cutoffs', 'Sweatshorts', 'Leggings', 'Culottes', 'Chinos', 'Trunks', 'Sarong', 'Gauchos', 'Jodhpurs', 'Capris', 'Dress', 'Romper', 'Coat', 'Kimono', 'Jumpsuit', 'Robe', 'Caftan', 'Kaftan', 'Coverup', 'Onesie']
(46, 46)

Наконец-то тренировка с Resnet-34

# create fast.ai vision Conv learner aka CNN from resnet34 architecture
# Please note, we are using metrics as top-1 Accuracy
learn = create_cnn(data, models.resnet34, metrics=accuracy)
# fit learner on data in 8 cycle
learn.fit_one_cycle(8)
# save our fitted model
learn.save('stage-1_arch-34_sz-150')
>>> 
Total time: 49:55
epoch  train loss  valid loss  accuracy
1      1.632115    1.474118    0.561742  (06:13)
2      1.548713    1.408220    0.583295  (06:12)
3      1.512822    1.369032    0.596267  (06:13)
4      1.450622    1.345870    0.601440  (06:14)
5      1.445819    1.308995    0.612246  (06:16)
6      1.361442    1.289868    0.617319  (06:16)
7      1.370456    1.276496    0.621509  (06:16)
8      1.364946    1.272343    0.621870  (06:12)

Наша окончательная точность = 62%, давайте сравним ее с результатами исследования.

DeepFashion: обеспечение надежного распознавания и поиска одежды
с богатыми аннотациями

Их диапазоны точности для классификации категорий показаны 82,58 для топ-3 и 90,17 для топ-5. Что, черт возьми, такое точность топ-3 и топ-5 и как мы ее вычисляем?

Давай погуглим.

Https://stackoverflow.com/questions/37668902/evaluation-calculate-top-n-accuracy-top-1-and-top-5

Подождите ... поэтому по умолчанию, когда мы говорим о точности в нашей модели классификации Fast.AI, мы рассчитывали только точность первого уровня. А в научных статьях используются топ-3 и топ-5 точности. Вау, это откровение!

(Но почему в исследовательских работах точность модели рассчитывается по результатам трех или пяти самых популярных прогнозов? Мы узнаем об этом в нескольких абзацах ниже на этапе анализа)

Итак, как рассчитать точность топ-3, топ-5 или топ-k и, что наиболее важно, как использовать это с fast.ai? Поищем на форумах fast.ai.

@Matthew Teschke любезно предоставил функцию максимальной точности k.

# This is for accuracy in top 3, change k to other values as needed
def accuracy_topk(output, target, topk=(3,)):
   """Computes the precision@k for the specified values of k"""
   
   maxk = max(topk)
   batch_size = target.size(0)
   
   _, pred = output.topk(maxk, 1, True, True)
   pred = pred.t()
   correct = pred.eq(target.view(1, -1).expand_as(pred))
 
  res = []
  for k in topk:
    correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
    res.append(correct_k.mul_(100.0 / batch_size))
  return res

Давайте попробуем использовать эти специальные метрики точности с нашими прогнозами учащихся.

# load our saved model
learn.load('stage-1_arch-34_sz-150')
# Get Output predictions and original targets
output, target = learn.get_preds()

Итак, ТОП-3 точности:

print (accuracy_topk(output=output, target=target))
>>> [tensor([84.4762])]

И ТОП-5 Точность:

print (accuracy_topk(output=output, target=target, topk=(5,)))
>>> [tensor([91.5972])]

Ух ты !!!! Наша быстрая модель с несколькими линиями превосходит эталон оригинальной бумаги еще на ~ 2% для точности типа 3 и на дополнительные ~ 1,5% для точности типа 5. Звучит слишком хорошо, чтобы быть правдой.

Давайте визуализируем и анализируем

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

# Let's see most confused cloth categories
interp.most_confused(min_val=80)
>>>
[('Romper', 'Dress', 611),
 ('Skirt', 'Dress', 551),
 ('Tee', 'Blouse', 481),
 ('Top', 'Blouse', 460),
 ('Blouse', 'Dress', 450),
 ('Blouse', 'Tee', 430),
 ('Tank', 'Tee', 416),
 ('Top', 'Tee', 377),
 ('Jumpsuit', 'Dress', 353),
 ('Tee', 'Dress', 335),
 ('Tee', 'Tank', 300),
 ('Sweater', 'Tee', 286),
 ('Cardigan', 'Sweater', 272),
 ('Tank', 'Dress', 260),
 ('Cardigan', 'Blouse', 244),
 ('Cutoffs', 'Shorts', 237),
 ('Top', 'Dress', 215),
 ('Tee', 'Sweater', 213),
 ('Sweater', 'Blouse', 209),
 ('Blouse', 'Tank', 203),
 ('Sweater', 'Cardigan', 193),
 ('Blazer', 'Jacket', 190),
 ('Shorts', 'Tee', 189),
 ('Top', 'Tank', 187),
 ('Cardigan', 'Dress', 187),
 ('Shorts', 'Skirt', 186),
 ('Dress', 'Skirt', 185),
 ('Dress', 'Blouse', 184),
 ('Tank', 'Blouse', 174),
 ('Jacket', 'Blazer', 174),
 ('Jacket', 'Cardigan', 161),
 ('Skirt', 'Shorts', 161),
 ('Shorts', 'Dress', 140),
 ('Sweater', 'Dress', 138),
 ('Jacket', 'Blouse', 137),
 ('Tee', 'Shorts', 133),
 ('Blouse', 'Sweater', 131),
 ('Blazer', 'Blouse', 130),
 ('Blouse', 'Skirt', 129),
 ('Shorts', 'Blouse', 129),
 ('Hoodie', 'Tee', 128),
 ('Blazer', 'Cardigan', 126),
 ('Sweatpants', 'Joggers', 126),
 ('Joggers', 'Jeans', 123),
 ('Dress', 'Tee', 120),
 ('Top', 'Shorts', 115),
 ('Cardigan', 'Tee', 115),
 ('Cardigan', 'Jacket', 113),
 ('Cardigan', 'Blazer', 110),
 ('Kimono', 'Dress', 108),
 ('Top', 'Sweater', 104),
 ('Blouse', 'Shorts', 99),
 ('Tank', 'Shorts', 96),
 ('Blouse', 'Jacket', 90),
 ('Jacket', 'Dress', 90),
 ('Top', 'Skirt', 89),
 ('Blouse', 'Cardigan', 87),
 ('Joggers', 'Sweatpants', 83),
 ('Dress', 'Romper', 83),
 ('Hoodie', 'Sweater', 81)]

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

Например, линия («Верх», «Юбка», 82) означает, что имеется 82 различных изображения из общего числа 289 222 изображений, которые были неправильно интерпретированы нашей моделью.

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

Теперь наша обученная модель посмотрела на это изображение, на котором есть и «Топ», и «Юбка», а затем попыталась предсказать 1 наиболее подходящую категорию для этого изображения из заданных 46 категорий (топ и юбка - две из этих категорий).

Даже если кто-то попросит меня посмотреть на это изображение и найти, что я вижу? Тогда я скажу, что это должна быть черная «Юбка», тогда как это наверняка пренебрегает тем фактом, что на ней есть синий «Топ» и черная «Шляпа».

Теперь, в тот момент, когда наша модель интерпретирует то же самое и помещает это изображение только в 1 категорию, предположим, что она поместила это изображение в категорию «Юбка», тогда она ошибочно предсказала это изображение, поскольку изображение изначально относится к категории «Лучшие».

Вот почему наша топ-1 точность распознавания мелкозернистых изображений действительно ниже.

Хорошо, а как насчет того, если кто-то попросит меня еще раз взглянуть на изображение и найти, что я вижу, а затем дать мне 3 варианта для точного прогноза? (например, викторины с несколькими вариантами ответов)

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

Между прочим, в этих 46 категориях одежды нет «шляпы». Итак, я буду вынужден выбрать что-то еще из 46 категорий, помимо топа и юбки в третьем варианте. В этом случае мой третий вариант ответа будет «Шорты», что снова будет неправильным ответом.

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

Вот почему топ-3 точности у нашей модели выше.

Этот же пример можно применить и к топ-5 точности, что приведет к еще большей точности.

Вывод: определение максимальной точности имеет смысл. Вместо того, чтобы просить модель найти только 1 элемент, давайте попросим модель найти 3 первых элемента или 5 лучших элементов изображения. Это, несомненно, поможет с изображениями, состоящими из нескольких элементов.

Размораживание, точная настройка и скорость обучения

Поскольку наша модель работает так, как мы ожидаем, мы разморозим нашу модель и потренируем ее еще раз.

А вот и главное мясо Fast.AI. (Извините, веганы ..)

# Let's find optimal learning rate for unfreeze training
learn.load('stage-1_arch-34_sz-150')
# so unfreeze the learner
learn.unfreeze()
# find optimal learning rate
learn.lr_find()
learn.recorder.plot()

Похоже, оптимальный диапазон скорости обучения, при котором потери были низкими, составляет от 1e-6 до 1e-4. Давайте воспользуемся им, чтобы обучить учащегося размораживания.

learn.fit_one_cycle(8, max_lr=slice(1e-6,1e-4))
learn.save('stage-2_sz-150')
>>>
Total time: 50:13
epoch  train loss  valid loss  accuracy
1      1.375766    1.212036    0.638859  (06:15)
2      1.323883    1.186296    0.645760  (06:16)
3      1.277714    1.169039    0.652099  (06:16)
4      1.253536    1.144417    0.660691  (06:16)
5      1.217483    1.132032    0.665600  (06:16)
6      1.218301    1.124285    0.667854  (06:17)
7      1.200194    1.117262    0.669806  (06:17)
8      1.221006    1.116483    0.670188  (06:17)

Давайте проверим пользовательские топ-3 и топ-5 точности.

# load our saved model
learn.load('stage-1_sz-150')
# Get Output predictions and original targets
output, target = learn.get_preds()

Итак, ТОП-3 точности:

print (accuracy_topk(output=output, target=target))
>>> [tensor([86.7439])]

И ТОП-5 Точность:

print (accuracy_topk(output=output, target=target, topk=(5,)))
>>> [tensor([92.7784])]

Ух ты !!!! Наши модели Unfreeze работают лучше, чем наша быстро обученная модель. Поиск оптимальной скорости обучения и разморозка архитектуры resent34, несомненно, работают лучше.

Сейчас мы опережаем эталонный показатель для оригинальной бумаги еще на ~ 4% для точности типа 3 и на дополнительные ~ 2,5% для точности типа 5. Звучит слишком хорошо, чтобы быть правдой.

Наша обученная модель - это довольно хорошая детализированная модель распознавания изображений! Но пойдем дальше ...

Обучение: resnet50

data = ImageDataBunch.from_csv(path, ds_tfms=get_transforms(), size=150)
data.normalize(imagenet_stats)
learn = create_cnn(data, models.resnet50, metrics=accuracy)
#Before Unfreezing let's see how much effetive is resnet50
learn.fit_one_cycle(8)
# let’s save model for further unfreeze training
learn.save(’stage-1_res-50_sz-150’)
>>>
Total time: 51:12
epoch  train loss  valid loss  accuracy
1      1.546525    1.370602    0.595873  (06:25)
2      1.413914    1.311594    0.612949  (06:25)
3      1.409325    1.286178    0.618038  (06:23)
4      1.376256    1.237087    0.635968  (06:23)
5      1.366462    1.204111    0.645569  (06:24)
6      1.303884    1.180323    0.649763  (06:23)
7      1.254254    1.163054    0.656125  (06:23)
8      1.215397    1.163006    0.656502  (06:23)

Давайте проверим пользовательские топ-3 и топ-5 точности.

# load our saved model
learn.load('stage-1_res-50_sz-150’)
# Get Output predictions and original targets
output, target = learn.get_preds()

Итак, ТОП-3 точности:

print (accuracy_topk(output=output, target=target))
>>> [tensor([85.6439])]

И ТОП-5 Точность:

print (accuracy_topk(output=output, target=target, topk=(5,)))
>>> [tensor([92.3150])]

Нет, в этом случае точность наших топ-3 и топ-5 не увеличилась по сравнению с нашей архитектурой resnet-34, поэтому давайте подведем итоги.

Резюме и следующие шаги

Я бы сказал, что для нескольких часов или обучения и анализа (игнорируя медленное время обучения resnet50 и низкую точность), это неплохое начало для продвижения вперед с исследовательским докладом DeepFashion: обеспечение надежного распознавания и поиска одежды с помощью богатых аннотаций »

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

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

Например: как насчет индийской категории одежды, такой как Дхоти, мы обязательно хотим, чтобы ИИ знал о Ганди и его одежде?

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

А пока желаю удачного глубокого обучения ...

Вот мой Github Repo для этой статьи.