Наука о моде спешит на помощь!

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

Во-первых, напомним, о чем мы говорим. Это то, что составляет изображение глаза. (Хорошо, возможно, вы это знали - имя этого отраженного света - луч света.)

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

Кстати, мы нашли это изображение глаза с помощью нашего приложения «All Eyes on Hue». Таким образом мы собрали более 100 тысяч селфи-портретов - исключительно в аналитических целях. Между прочим, я говорю конкретно «селфи-портреты» - это большое изображение хедшота - так как нам нужно много пикселей для радужной оболочки глаза - многие селфи не подойдут. Кстати, реальное изображение глаза было помещено в рамку с помощью модели обнаружения черт лица (OpenFace).

Фон

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

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

Наука о моде спешит на помощь

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

Эти маски были созданы с помощью очень полезного инструмента labelbox.com. Этот инструмент позволяет быстро и эффективно создавать маски для большого количества изображений. Я очень рекомендую это.

Кстати, раньше я проводил этот анализ сегментации с помощью Keras. Недавно познакомившись с fast.ai, я хотел попробовать.

Короче говоря, fast.ai великолепен! «Нисходящий» курс fast.ai - это как раз то, что мне нужно! И потрясающие результаты. fast.ai!

Сегментационный анализ с использованием fast.ai

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

Я загрузил свои изображения глаз и маски с labelbox.com в две папки - изображения и маски. Маска представляет собой изображение аналогичного размера с целым числом для каждого пикселя изображения глаза. Это метка для этого пикселя. В моем случае я сделал фон равным 0, а диафрагму - 1.

Давайте построим нашу модель fast.ai.

codes = [ "background", "iris" ]   # can extend for sclera...
get_y_fn = lambda x: PATHEYES/MASKS_Y_DN/x.name
src = (SegmentationItemList.from_folder(PATHEYES/TRAIN_DN)
       .random_split_by_pct(0.2)
       .label_from_func(get_y_fn, classes=codes))

Сначала мы помещаем наши два набора изображений в специальный тип списка элементов, SegmentationItemList. Строка «random_split_by_pct (0.2)» создает наши разделения для обучения и проверки. Обратите внимание, что «get_y_fn» добавляет изображения маски, связанные с изображением глаза.

data = (src.transform(get_transforms(), size=size, tfm_y=True)
        .databunch(bs=bs)
        .normalize(imagenet_stats))
data.show_batch(2, figsize=(10,7))

Затем мы создаем нашу группу данных. Мы используем преобразования по умолчанию, например, перевернуть по горизонтали, а не по вертикали. «Bs» обозначает размер пакета - так как наши изображения маленькие, я использую здесь 64.

Результат «data.show_batch» - просто посмотреть на наши данные, среди прочего, чтобы убедиться, что преобразования были применены к изображению одинаково, как и к маскам - так оно и есть.

wd=1e-2
learn = unet_learner(data, models.resnet50, metrics=metrics, wd=wd)

Это создает учащегося, использующего нашу группу данных с использованием конструкции unet и на основе предварительно обученной модели resnet50. Уф - серьезные словечки. «Unet» - это стандартный метод построения, используемый для биомедицинских изображений, рекомендуемый по сравнению с традиционным учащимся CNN. Использование предварительно обученного ученика resnet50 - это просто лучшие практики - кто-то еще любезно предварительно обучил его с большим объемом данных и усилий. Кстати, resnet50 превзошел resnet34 примерно на 1-2 процентных пункта точности.

lr_find(learn)
learn.recorder.plot()

Следующим шагом в «кулинарной книге» является поиск хорошей скорости обучения. Хотя я, вероятно, предположил бы (по совету инструктора Джереми) скорость обучения 1e-05 - похоже, что новая функция здесь - автоматическая рекомендация - красная точка - немного более точная на 1,2E-05. Ладно, потренируемся, в первый раз.

lr=1.2E-05
learn.fit_one_cycle(15, slice(lr), pct_start=0.9)

Freakin ’A - точность 93%!

acc_iris - процент совпадения прогнозируемой маски (для набора проверки) с исходной маской.

Замечательно. Но давайте продолжим. Это делается путем размораживания модели resnet50, которую мы использовали, и ее настройки.

learn.unfreeze()
lr_find(learn)
learn.recorder.plot()
lrs=slice(1.0E-04,lr/5)
learn.fit_one_cycle(12,lrs)
learn.recorder.plot_losses()

Теперь точность составляет 95,0%. Это безумно хорошо.

Вот графики потерь - просто чтобы показать, что мы все еще в хорошей форме с нашими тренировками. т.е. Train больше, чем Validation, проверьте!

И интересное наблюдение!

Слева находятся данные проверки - изображение глаза, наложенное на его обучающую маску, сделанную вручную. Правый столбец показывает прогнозируемую маску. (Явно бу-бу по первому!)

Что? Предсказанная маска лучше, чем маска, натренированная вручную!

Маски, созданные вручную, безусловно, небрежны. Но, возможно, в прекрасных геометрических свойствах глаза есть что-то, чему модель также научилась - и игнорирует мои тренировочные маски должным образом. Интересно!

Завершение

Конечной целью было определить цвет радужной оболочки. Для моих целей это две вещи:

  • средний цвет
  • 4 верхних цвета, перечисленных в порядке распространенности. Мы определяем 4 лучших (или любых других) цвета с помощью KMeans.

Вот пример глаза / радужной оболочки, и он дает 4 лучших цвета.

Дальнейшие действия

Как упоминалось выше, все это является частью метода создания персонализированных цветовых палитр для человека на основе цветов его частей тела. Мы показали, как это делается с радужной оболочкой. Волосы и склера очень похожи. Для кожи и губ мы используем вывод детектора черт лица (OpenFace.)

Конечная цель - использовать цветовые гармонии этих цветов для создания непрерывной модели «хороших» цветов. Затем создается репрезентативная палитра.

Быть в курсе!