Мы завершаем нашу последнюю неделю в программе General Assembly Immersive Programme. Чтобы получить высшее образование, нам нужно завершить финальный проект по выбранному нами предмету. У меня есть предыстория политической кампании, но я хочу больше узнать об аналитике здравоохранения и считаю компьютерное зрение интересным, поэтому я принял участие в Конкурсе рака шейки матки Kaggle.

Нам дали более 1000 фотографий шейки матки, и мы должны были обучить модель тому, как правильно определять тип шейки матки на основе этих фотографий. Какой тип шейки матки зависит от того, где находится зона трансформации, область, где может развиться рак. Это важно, потому что в местах, где у них нет ресурсов для мазка Папаниколау, они проводят визуальный осмотр, применяя аскусную кислоту в зоне трансформации для выявления раковых образований. Если шейка матки 3-го типа и часть зоны трансформации не видна, врач должен будет учесть это во время этой процедуры. Проблема усложняется тем, что неподготовленным глазом трудно различать типы шейки матки, поэтому Kaggle проводит это соревнование.

Чтобы принять участие, вам необходимо запустить тестовый набор фотографий Kaggle через вашу модель и вывести вероятность того, что каждая фотография будет шейкой матки типа 1, типа 2 или 3. Соревнование оценивается по наименьшему значению лог-потерь в тестовой выборке, что наказывает больше за ошибку, чем за неуверенность. Базовая отправка для Kaggle имеет лог-потерю 1,00575.

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

Урок 1. Убедитесь, что вы умеете различать классы

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

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

Урок 2. Используйте собственные функции потерь

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

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

По-видимому, лог-потеря и кросс-энтропия - это одно и то же. Итак, я переключил свою потерю на категориальную перекрестную энтропию, и моя потеря проверки более точно отражает потерю, которую я получаю на Kaggle.

Урок 3. Нейронные сети склонны к переобучению

После того, как я решил проблему с моей функцией потерь, я продолжал сталкиваться с проблемой, когда мои сети были переоборудованы. Чем больше эпох я добавил, тем больше расходились потери поезда и потери при тестировании, показывая, что моя архитектура плохо обобщается. Даже если бы я тренировался всего несколько эпох, я бы все равно не добился результата, который превзошел бы базовый уровень. Я пробовал изменять свою модель разными способами: добавлял выпадение, уменьшал мой сверточный шаг, обрезал и увеличивал оттенки серого для моих изображений. Независимо от того, как я изменил свою архитектуру или сколько эпох я пробежал (будь то высокий или низкий), я не смог превзойти базовый уровень.

Мне действительно нужна была помощь, поэтому я решил посмотреть, что люди делают на Kaggle, и увидел ядро Owl1. Первоначально я использовал архитектуру, рекомендованную профессором Стэнфорда Андреем Карпати для подбора более сложных функций (Ввод - ›[Conv -› Relu - ›Conv -› Relu - ›Pool] * 3 -› [FC - › Релу] * 2 - ›FC). Ядро Owl1 намного проще, похоже на другой фреймворк, который предлагает Карпати (Input - ›[Conv -› Relu - ›Pool] * 2 -› FC - ›Relu -› FC]). Owl1 также может похвастаться 0,89 logloss, намного лучше, чем любой полученный мной результат.

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

  • Использовалась более простая архитектура (Input - ›[Conv -› Relu - ›Pool] * 2 -› FC - ›Relu -› FC])
  • Использовано меньше фильтров
  • Заменил последнюю активацию relu на tanh
  • Изменен оптимизатор с rmsprop на adamax
  • Используется версия фотографий RGB вместо фотографий в оттенках серого
  • Добавлен отсев после FC

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

Заключительный урок - нейронные сети сложны и требуют много времени

В конце этого проекта у меня есть:

  • 11 дней потратил на изготовление моделей
  • Сделано 30 нейронных сетей
  • Сделано 16 уникальных архитектур
  • Обучался более 607 эпох
  • Потрачено более 150 долларов на облачный кредит Google

Это привело к созданию нейронных сетей ZERO, которые превзошли базовый уровень Kaggle. Ближайшей из них была первая нейронная сеть, которую я создал с лог-потерей 1,00616, и на ней обучалось только 2 эпохи.

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

Комбинация PCA и SVM

Я преодолел базовый уровень Kaggle с помощью альтернативного метода. Я использовал версию изображений с серым масштабированием / обрезкой и прогнал их через анализ главных компонентов (PCA). PCA - это метод уменьшения размерности, который использует линейную алгебру для объединения функций (дополнительную информацию см. В сообщении моего учителя Мэтта Брема). Каждая фотография размером 100 x 100 представлена ​​10 000 переменных, каждая из которых указывает, насколько ярким или темным является пиксель. После прогона фотографий через PCA я выбрал 61 из 1036 результирующих компонентов (или комбинированных функций), которые объяснили 90% дисперсии яркости / темноты пикселей.

Затем я загрузил результаты в классификатор векторов поддержки scikitlearn, используя его параметры по умолчанию (результат gridsearch хуже). Я едва перескочил через исходное представление Kaggle с лог-потерей 1,00574 после отправки моих результатов.

Источники:

Видео для мобильного ODT: https://www.youtube.com/watch?v=N8OGrykSgy0&t=543s

Стэнфордский курс CNN: http://cs231n.github.io/

Keras Docs: https://keras.io/

Блог Кераса: https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html

Ядро Owl1: https://www.kaggle.com/the1owl/artificial-intelligence-for-cc-screening