Введение - Машинное обучение и нейронные сети

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

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

Узлы связаны друг с другом посредством ссылок, где каждой ссылке соответствует вес. Выход каждого узла называется его активацией или значением узла. На диаграмме топологии, показанной ниже, каждая стрелка представляет соединение между двумя узлами и указывает путь информационного потока. ИНС способны обучаться, и их нужно обучать, отсюда и термин машинное обучение. На самом деле это обучение происходит за счет изменения значений веса (в дополнение к так называемой предвзятости, о которой мы не будем вдаваться в этот момент). Если сеть генерирует желаемый результат, например, определяет, принадлежит ли показанное изображение определенному объекту, нет необходимости корректировать веса. В противном случае сеть будет продолжать изменять веса, чтобы улучшить последующие результаты.

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

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

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

TensorFlow - популярная библиотека с открытым исходным кодом, созданная Google для создания моделей глубокого обучения с использованием графов потоков данных. Узлы TensorFlow на графе представляют математические операции, а ребра графа представляют многомерные массивы данных (тензоры), передаваемые между ними. Вкратце, мы можем рассматривать TensorFlow как расширенную библиотеку для работы с многомерными массивами. TensorFlow предоставляет API-интерфейсы на разных языках программирования, таких как C ++ и Java, но в этой статье мы будем использовать Python.

Я полагаю, что на данный момент этого достаточно вводной информации. Итак, давайте продолжим и начнем с установки TensorFlow дальше!

1. Установка TensorFlow

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

  1. В зависимости от вашей операционной системы установите Docker, как описано здесь. Однако в этой статье предполагается, что установка будет выполнена на Mac OS X.
  2. Убедитесь, что Docker запущен, как показано на следующем снимке экрана:

3. Чтобы запустить контейнер Docker, содержащий двоичный образ TensorFlow вместе с исходным кодом, введите в терминал следующее:

$ docker run -it gcr.io/tensorflow/tensorflow:latest-devel

Если это происходит впервые, обратите внимание, что Docker может потребоваться несколько минут, чтобы загрузить двоичный образ TensorFlow и исходный код из реестра контейнеров Google (GCR). После завершения загрузки вы должны увидеть что-то похожее на приведенное ниже:

Примечание. Чтобы выйти из Docker и вернуться в командную строку, вы можете просто использовать ярлыкCTRL+D на Mac (CTRL+Cв Windows)

4. Чтобы проверить установку TensorFlow, запустите контейнер Docker, который запускает bash, как показано ниже:

$ docker run -it gcr.io/tensorflow/tensorflow:latest-devel bash

Затем вызовите Python из своей оболочки следующим образом:

$ python

Наконец, введите следующую короткую программу в интерактивную оболочку Python:

Если система выдает Hello, TensorFlow!, то поздравляю! Вы готовы начать писать свои собственные программы TensorFlow. Чтобы выйти из Python, вы можете просто использовать shortcutCTRL+D. Вам нужно будет снова ввести CTRL+D на Mac, если вы хотите выйти из Docker и вернуться в командную строку!

Приведенную выше короткую программу TensorFlow можно описать следующим образом:

Прежде всего, нам нужно импортировать библиотеку тензорного потока с import tensorflow as tf. Это предоставит нашему приложению Python доступ ко всем классам, методам и символам TensorFlow.

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

1. Построение вычислительного графа: этот граф описывается как серия операций TensorFlow, организованных в граф узлов. С другой стороны, каждый узел принимает ноль или более тензоров в качестве входных данных и создает тензор в качестве выходных данных. Для этой простой программы мы строим простой вычислительный граф с одним постоянным узлом, используя hello = tf.constant(‘Hello, TensorFlow!’). Этот тип узла не принимает входных данных, но выводит значение, которое хранится внутри.

2. Запуск вычислительного графа: обратите внимание, что простая печать узла hello не приведет к выводу строкиHello, TensorFlow!, как вы могли ожидать. Вместо этого необходимо оценить узел, чтобы получить эту строку. Чтобы фактически оценить узел, мы должны запустить вычислительный граф из сеанса, который можно определить как среду, которая инкапсулирует управление и состояние среды выполнения TensorFlow. Следовательно, оператор sess = tf.Session() above создает объект Session, а затем вызывает его метод run через операторprint(sess.run(hello)), который в конечном итоге оценит узел hello, запустив вычислительный граф.

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

with tf.Session() as sess:
print(sess.run(hello))

2. Загрузите наборы данных изображений повреждений кожи.

Наборы данных о поражениях кожи, использованные для переобучения нашей модели, были загружены из общедоступного архива изображений, размещенного на ISIC (Международное сотрудничество по визуализации кожи). ISIC - это академическое и промышленное партнерство, призванное облегчить применение цифровых изображений кожи для снижения смертности от меланомы.

На момент написания этой статьи в ISIC в настоящее время размещено 12668 изображений, которые определены как доброкачественные поражения кожи, и 1048 изображений, которые определены как злокачественные (см. Снимок экрана ниже). Для получения дополнительной информации вы можете перейти по этой ссылке.

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

После завершения загрузки наборов данных нам нужно будет организовать структуру каталогов, как показано ниже:

  1. Убедитесь, что Docker не запущен. Затем создайте каталог с именем tf_files в своем домашнем каталоге:
$ mkdir tf_files

2. Каталог tf_files будет содержать другой подкаталог с именем skin_lesions, который, в свою очередь, будет содержать два других подкаталога, каждый из которых должен будет соответствовать имени класса. Поскольку конечной целью является переобучение классификатора, чтобы определить, является ли предоставленное изображение поражения кожи доброкачественным или нет, загруженные изображения будут помещены в отдельные каталоги с именами benign и malignant, как показано ниже:

$ cd tf_files
$ mkdir skin_lesions
$ mkdir skin_lesions/benign skin_lesions/malignant

Хотя мы уже здесь, нам также необходимо поместить сценарий классификации, который мы будем использовать для тестирования переобученного классификатора, в каталог tf_files. Этот сценарий будет называться label_image.py, но не беспокойтесь, если вы не понимаете, зачем нам этот файл на данном этапе, мы вернемся к нему позже. Содержание скрипта обрисовано в общих чертах в следующей сущности. Либо вы можете вставить содержимое этого файла в этот файл сценария, который вы только что создали в tf_files, либо вы можете просто загрузить этот файл и переместить его в tf_files:

После добавления сценария классификации структура каталогов должна выглядеть следующим образом:

3. Свяжите контейнер Docker с наборами данных изображений.

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

$ docker run -it -v ~/tf_files:/tf_files gcr.io/tensorflow/tensorflow:latest-devel

4. Загрузите обучающий скрипт TensorFlow.

Пока указанный выше контейнер Docker все еще работает, введите следующие команды:

$ cd /tensorflow/
$ git pull

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

5. Переподготовка классификатора

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

$ python tensorflow/examples/image_retraining/retrain.py \
--bottleneck_dir=/tf_files/bottlenecks \
--how_many_training_steps 4000 \
--model_dir=/tf_files/inception \
--output_graph=/tf_files/retrained_graph.pb \
--output_labels=/tf_files/retrained_labels.txt \
--image_dir /tf_files/skin_lesions

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

  • Переобучение нашего классификатора будет основано на начальной модели, которая по сути является предварительно обученной моделью, способной распознавать общие объекты с 1000 классами (например, Зебра, Далматинец и Посудомоечная машина). Следовательно, переподготовка, которую мы здесь проводим, просто добавляет новый последний слой и обучает его на изображениях кожи, которые мы хотим, чтобы наш классификатор распознавал.
  • Упомянутый выше термин «узкое место» используется для обозначения постоянных нижних уровней сети, которые находятся непосредственно перед окончательным выходным слоем, который фактически выполняет классификацию. Поскольку эти нижние уровни фактически не изменяются, приведенная выше команда кэширует выходные файлы для этих нижних уровней в каталог bottlenecks/. Если мы перезапустим скрипт, эти кешированные файлы будут повторно использованы, что сэкономит нам время.
  • Этот скрипт выполнит 4000 обучающих шагов, где каждый шаг будет случайным образом выбирать 10 изображений из обучающего набора, находить их узкие места в кеше, а затем передавать их на последний уровень для составления прогнозов. Затем эти прогнозы сравниваются с правильными метками, чтобы соответствующим образом обновить веса последнего слоя (с помощью процесса обратного распространения ошибки).
  • Мы также передаем здесь в качестве аргумента каталог изображений tf_files/skin_lesions . Исходя из этого, сценарий будет использовать имена каталогов в skin_lesions в качестве имен меток. Предполагается, что изображения внутри каждого подкаталога будут изображениями, соответствующими этому ярлыку (доброкачественные или злокачественные).
  • Кроме того, приведенный выше сценарий переобучения записывает данные в следующие два файла, которые будут отображаться всякий раз, когда нам понадобится позже использовать нашу переобученную модель. Это: tf_files/retrained_graph.pb, которые содержат версию сети, в которой последний уровень был переобучен по нашим новым категориям. Andtf_files/retrained_labels.txt, который представляет собой текстовый файл, содержащий метки, соответствующие нашим категориям.

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

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

  • Точность обучения: представляет процент правильно помеченных изображений в текущем пакете обучения.
  • Точность проверки: представляет процент правильно помеченных изображений в случайно выбранной группе изображений из другого набора.
  • Перекрестная энтропия: это функция затрат / потерь, которая показывает, насколько хорошо идет процесс обучения. Чем ниже эти цифры, тем лучше тренировка.

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

6. Использование переквалифицированного классификатора

Теперь, когда наша модель полностью переобучена, мы можем продолжить и протестировать наш классификатор. Для этого воспользуемся скриптом label_image.py, который мы поместили в каталог tf_files.

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

  1. Во-первых, давайте запустим этот сценарий на образце изображения из каталога malignant, пока контейнер Docker все еще работает:

$ python /tf_files/label_image.py /tf_files/skin_lesions/malignant/ISIC_0011381.jpg

Вы увидите такие результаты:

malignant (score = 0.94354)
benign (score = 0.05646)

Приведенные выше результаты указывают на высокую уверенность (~ 94%) в том, что изображение имеет злокачественную природу, и низкую уверенность в том, что изображение доброкачественное.

2. Теперь давайте попробуем классифицировать случайное изображение из безопасного каталога:

$ python /tf_files/label_image.py /tf_files/skin_lesions/benign/ISIC_0010786.jpg

Результаты будут выглядеть, как показано ниже, где результат указывает на более высокую уверенность в том, что это изображение является доброкачественным (~ 96%):

benign (score = 0.95702)
malignant (score = 0.04298)

Примечание. Отображаемые выше результаты могут отличаться в зависимости от каждого конкретного сеанса переподготовки или даже от изображений, с которыми вы тестируете классификатор для этого конкретного сеанса. При этом, если есть необходимость начать все сначала с Docker, вы можете использовать опцию Reset, расположенную в Preferences for Docker. Но, пожалуйста, используйте эту опцию с осторожностью, так как она сотрет все данные вашего контейнера!

7. Выводы и обсуждения:

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

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

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

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