Классификация изображений рака кожи с помощью fastai и Render

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

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

Я планирую вскоре написать аналогичную статью о НЛП - следуй за мной, чтобы не пропустить! 😄

Заявление об отказе от ответственности:

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

Технические: этот пример не предназначен для крупномасштабного веб-сайта с миллионами посещений. Если у вас есть такая проблема - что ж, это хорошая проблема. 😀 Эта установка может работать. Render негласно использует Docker и Kubernetes, чтобы сделать масштабирование максимально безболезненным.

Хорошо - вернемся к действию!

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

Вот план:

  1. Найдите данные.
  2. Постройте и обучите модель.
  3. Разверните модель.
  4. Повысьте производительность модели.

Давайте немного уточним этот план. 😉

Шаги

  1. Найдите данные. Я помню, как где-то видел набор данных о родинках на коже - может быть, UCI, data.world или Kaggle. Я поищу и посмотрю.
  2. Постройте и обучите модель. Я сейчас использую MOOC для глубокого обучения fast.ai, поэтому я буду использовать fastai, высокоуровневую библиотеку PyTorch, для обучения моей модели. Fastai позволяет применять множество новейших приемов, а API удобен для задач компьютерного зрения. Я буду использовать увеличение данных, трансферное обучение и отжиг скорости обучения. Я буду тренироваться в Jupyter Notebook с графическим процессором в облаке.
  3. Разверните модель. Документы Fastai содержат руководство по развертыванию модели на Render за 5 долларов в месяц.
  4. После того, как у нас будет развернутая модель, мы вернемся и попытаемся улучшить ее производительность.

Поехали! 🚀

Охота за данными

Я обнаружил, что исследователи из Гарварда собрали здесь 10 015 изображений с рядом кожных заболеваний: https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/DBW86T.

Похоже, что ежегодно проводится конкурс ISIC по нескольким аспектам данных - информация здесь. Здесь вы можете увидеть изображения с разными фильтрами.

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

Изображения поражений кожи заархивированы в двух заархивированных папках. Я не видел простого способа объединить файлы из двух заархивированных папок с наборами данных на Kaggle. Я загрузил данные, заархивировал их и повторно загрузил. Теперь вы можете использовать данные в одной папке на Kaggle here. 😄

Изучение данных

Есть один файл с метаданными: HAM10000_metadata.csv. Это удобно. Вот содержание и мои первые мысли:

lesion_id - по одному для каждого очага поражения. Каждое поражение может иметь более одного изображения.
image_id - перечисляет идентификатор изображения для каждого поражения. Это также имена файлов без .jpg.
dx - диагностика. 7 видов. Полагаю, это должен быть DV.
dx_type - как был поставлен диагноз.
age - 57 значений отсутствуют. Могли бы попробовать разные стратегии работы с.
полом - 3 значения.
локализация - расположение на теле. 15 ценностей.

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

Начальные вопросы

Сколько классификационных меток существует для переменной результата? Семь: меланоцитарные невусы, меланома, доброкачественный кератоз, базальноклеточный рак, актинический кератоз , сосудистые поражения, дерматофиброма. Учтите, что меланома - самый опасный вид рака кожи. Вам также не нужна базальноклеточная карцинома - наиболее частый тип рака кожи. Актинический кератоз считается потенциальным предраком.

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

Данные несбалансированы? Да, 67% относятся к классу nv, что означает меланоцитарные невусы.

Мы должны быть осторожны с нашими показателями отчетности с несбалансированными классами. Точность, например, не очень полезный показатель. Однако, по словам Джереми Ховарда из fast.ai, нам не нужно беспокоиться о несбалансированном наборе данных при обучении с использованием моделей глубокого обучения. Сеть выяснит классы.

Подготовьте данные

Мы импортируем наши обычные библиотеки и настроим их для глубокого обучения. Поскольку в Kaggle нет новейших библиотек PyTorch и fastai, мы включим Интернет и установим их с помощью pip.

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

Я переключился на Colab, когда мне надоело ждать загрузки моего объединенного файла данных. Я понял, что могу использовать Kaggle API, чтобы получить набор данных из Kaggle в Colab. Затем я объединил файлы изображений и сохранил их в папке Google Диска. Это было немного хлопотно, но теперь, когда данные находятся в моей папке на Диске, это довольно удобно. 😄 Вот моя тетрадь Colab.

Постройте модель

Я использую fastai v.1.50.0, torch v1.0.1.post2, torchvision v0.2.2.post3.

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

Разделение на обучение и тест - fastai разделит наши данные на наборы для обучения и проверки. Мы отложим 20% изображений для проверки.

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

Оптимизатор - я использую значение по умолчанию: Адам.

Слои - слои fastai по умолчанию для CNN объясняются здесь. Это блоки слоев PyTorch с функциями batchnorm, dropout, linear и Relu. Последний набор слоев состоит из 2-го объединяющего слоя и выравнивающего слоя.

Скорость обучения. Мы будем использовать отжиг скорости обучения в соответствии с Политикой 1 цикла Лесли Смита. Мы начнем со стандартной скорости обучения fastai 3E-10 для первых эпох (которая была подтверждена как подходящая с помощью средства поиска скорости обучения fastai). После размораживания мы создадим диапазон скоростей обучения для политики 1Cycle с помощью средства поиска скорости обучения и практического правила, чтобы уменьшить предыдущую скорость обучения в 10 раз.

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

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

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

Развернуть

Вот пять шагов для развертывания модели.

  1. Форк пример fastai GitHub repo и клонируем его.
  2. Зарегистрируйтесь на Render.
  3. Настройте свой проект, следуя гайду fastai Render.
  4. Настройте код приложения Render в редакторе кода.
  5. Отправьте свой код на GitHub. Вот репозиторий GitHub для моего приложения на Render.

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

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

Вы можете проверить мое живое приложение здесь: https://skin-render.onrender.com/. Я, вероятно, уберу его через несколько недель, поэтому, если эта ссылка не работает для вас, вот почему. 😄

Запустите приложение локально в Jupyter Lab

Вы также можете запустить свое приложение локально. Фактически, если вы используете Jupyter Lab, вы можете увидеть свое приложение в своем блокноте, что очень круто!

Вот три шага, чтобы увидеть ваше приложение в записной книжке:

  1. Запустите сервер Jupyter Lab
  2. В терминале, находясь в папке локального приложения для рендеринга, запустите сервер с python app/server.py serve
  3. Введите следующий код в ячейку записной книжки и запустите его, чтобы создать iframe:
from IPython.display import IFrame
IFrame(‘http://localhost:5042/', width=’100%’, height=500)

Ваше приложение должно работать на выходе вашей ячейки.

Потрясающие! Рендеринг довольно гладкий. Теперь посмотрим, сможем ли мы улучшить нашу модель.

Улучшение модели

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

Использование обучения с половинной точностью и размера пакета 64 с 8 полными эпохами привело к ошибке в 14%. Звучит неплохо. Но затем я посмотрел на матрицу путаницы и увидел, что почти половина всех случаев меланомы была классифицирована как доброкачественная. Это проблема. 😟

Я работал над рядом возможных исправлений. Лучшая модель использовала трансферное обучение с ResNet50, 12 общих периодов обучения, размер пакета 64 и точность с плавающей запятой 32.

Уровень ошибок снизился до 10,7%, и вот матрица путаницы:

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

Возможные направления в будущем

  • Проверьте больше комбинаций гиперпараметров.
  • Попросите пользователей указать свой возраст в дополнение к изображению. Эти данные, вероятно, повысят точность. Однако это также увеличило бы трение.
  • Добавьте увеличение времени тестирования (TTA) для повышения эффективности прогнозирования. Это усовершенствование будет непростым, поскольку приложению потребуется создать несколько изображений из предоставленного изображения. TTA также может немного замедлить работу приложения. В качестве альтернативы мы также можем попросить пользователя загрузить три разных изображения поражения и прогнозировать по ним.
  • Сделайте это задачей бинарной классификации, в которой вы классифицируете эти поражения как опасные или не опасные. Если такая информация действительно нужна конечному пользователю, я бы попросил приложение дать эту рекомендацию, если бы я собирался его выпустить.

Что мы узнали?

Выводы

Эти изображения были в хорошем состоянии, и подобрать для них нужный формат было не так уж сложно. Заставить Kaggle и Colab работать с источниками данных потребовалось больше всего усилий. У Kaggle и Colab есть свои препятствия, но они бесплатны. 😄

Ждать, пока графический процессор Colab K80 обучит вашу модель, уже устарело. Это нормально для обработки небольшой модели на ранних этапах, но если вы хотите протестировать множество гиперпараметров, возможно, стоит перейти на платную услугу. Я нашел Google Cloud Platform (GCP) самым простым в использовании поставщиком облачных услуг с хорошей ценой. См. Мою статью о сравнении поставщиков облачных GPU здесь. Я бы, вероятно, использовал V100 на GCP, если бы собирался тренировать эти модели дальше.

Размер обучающего набора данных был важен. Модель не тренировалась, когда тренировалась с 800 наблюдениями вместо 8k.

Fastai и Render - отличная команда. Fastai хорош для быстрого создания высокопроизводительных моделей, а Render упрощает их развертывание. 👍

Сворачивать

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

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

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

Удачного обучения и развертывания!

Данные и ресурсы

Вот изображения и метаданные на Kaggle, изначально загруженные Кевином Мадером. Теперь изображения доступны в одной папке, которую я загрузил в Kaggle здесь. Моя записная книжка Colab находится здесь.

Вот ядра Kaggle, которые использовали тот же исходный набор данных. А вот еще две статьи на Medium, в которых обсуждается решение этой проблемы: 1, 2.

Исходный источник данных

Tschandl, P., Rosendahl, C. & Kittler, H. Набор данных HAM10000, большая коллекция дерматоскопических изображений из нескольких источников распространенных пигментных поражений кожи. Sci. Данные 5, 180161 (2018). DOI: 10.1038 / sdata.2018.161

Https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/DBW86T