22 февраля 2018 г. на обложке журнала Cell Magazine появилась статья Выявление медицинских диагнозов и излечимых заболеваний с помощью глубокого обучения на основе изображений.

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

Авторы великодушно сделали данные и код общедоступными для дальнейшего исследования. В этой статье я объясню свою успешную попытку воссоздать результаты и объясню свою собственную реализацию.

Я написал эту статью для трех разных аудиторий:

1. Широкая общественность, заинтересованная в применении ИИ для медицинской диагностики.

2. Офтальмологи, которые хотят понять, как ИИ можно использовать в своей практике.

3. Студенты машинного обучения и новые практики, которые хотят научиться внедрять такую ​​систему.

Эта статья состоит из трех частей:

  1. Задний план
  2. Реализация: обучение модели
  3. Реализация: оценить модель
  4. Резюме и ссылки для скачивания

Общий обзор того, что будет рассмотрено, приведен ниже в содержании.

Содержание

Часть 1. История вопроса и обзор

  • Оптическая когерентная томография (ОКТ) и глазные болезни
  • Нормальная сетчатка глаза (НОРМАЛЬНАЯ)
  • Неоваскуляризация хориоидеи (CNV)
  • Диабетический макулярный отек (DME)
  • Друсен (DRUSEN)
  • Обучение людей интерпретации ОКТ-изображений при глазных заболеваниях
  • Обучение компьютеров интерпретации ОКТ-изображений при глазных заболеваниях - алгоритмический подход
  • Обучение компьютеров интерпретации изображений ОКТ при заболеваниях глаз - Deep Neural Networks

Часть 2 - Внедрение: обучение модели

  • Введение
  • Выбор и установка оборудования и программного обеспечения для глубокого обучения
  • Загрузите данные и систематизируйте
  • Импортировать необходимые модули Python
  • Настройка генераторов данных обучающих и тестовых изображений
  • Загрузите InceptionV3 и прикрепите новые слои вверху
  • Скомпилируйте модель
  • Подберите модель с данными и сохраните лучшую модель во время обучения
  • Следите за тренировкой и наносите на карту результаты

Часть 3. Реализация: оценка модели

  • Введение
  • Импортировать необходимые модули Python
  • Загрузите сохраненную лучшую модель
  • Оцените модель для небольшого набора изображений.
  • Напишите служебные функции, чтобы получать прогнозы для одного изображения за раз
  • Реализуйте функцию grad_CAM для создания карт окклюзии.
  • Сделайте прогноз для одного изображения и создайте карту окклюзии
  • Делайте прогнозы для нескольких изображений и создавайте карты окклюзии для неправильно классифицированных изображений.

Часть 4. Сводка и ссылки для скачивания

Часть 1 - Предпосылки и обзор

Оптическая когерентная томография (ОКТ) и глазные болезни

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

  1. Неоваскуляризация хориоидеи (CNV)
  2. Макулярный отек (DME)
  3. Друсен (DRUSEN)

На следующем рисунке показана анатомия глаза:

Нормальная сетчатка глаза (НОРМАЛЬНАЯ)

На следующем рисунке показано ОКТ-изображение нормальной сетчатки.

Неоваскуляризация хориоидеи (CNV)

Хориоидальная неоваскуляризация (CNV) - это создание новых кровеносных сосудов в хориоидальном слое глаза. CNV может вызвать внезапное ухудшение центрального зрения, заметное в течение нескольких недель. Другие симптомы, которые могут возникнуть, включают нарушение цвета и искажения, при которых прямые линии выглядят волнистыми.

Диабетический макулярный отек (DME)

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

Друсен (DRUSEN)

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

Обучение людей интерпретации ОКТ-изображений при глазных заболеваниях

Как бы вы научили людей определять четыре класса глазных заболеваний (CNV, DME, DRUSEN или NORMAL) по изображениям ОКТ? Во-первых, вы должны собрать большое количество изображений (скажем, 100) каждого условия и систематизировать их. Затем вы должны пометить изображения (CNV, DME, DRUSEN или NORMAL) и аннотировать несколько изображений каждого состояния, чтобы показать, где искать отклонения.

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

Обучение компьютеров интерпретации ОКТ-изображений при глазных заболеваниях - алгоритмический подход

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

Обучение компьютеров интерпретации изображений ОКТ при заболеваниях глаз - Deep Neural Networks

Последние достижения в области машинного обучения с использованием глубоких нейронных сетей с прямой связью с несколькими сверточными слоями упрощают обучающие компьютеры для таких задач. Показано, что производительность нейронных сетей увеличивается с увеличением количества доступных обучающих данных. Количество опубликованных ОКТ-изображений ограничено, хотя авторы статей опубликовали 100 000 изображений. Нейронные сети, как правило, лучше работают с миллионами изображений.

Ключевая идея - использовать нейронную сеть, которая уже обучена обнаруживать 1000 классов изображений (собаки, кошки, автомобили и т. Д.) С миллионами изображений. Одним из таких наборов данных является ImageNet, состоящий из 14 миллионов изображений. Обученная ImageNet Keras модель GoogleNet (Inception v3) уже доступна здесь.

Модель реализует определенную топологию нейронной сети, состоящую из многих слоев. Проще говоря, изображения подаются на нижний уровень (вход) модели, а самый верхний слой производит выходные.

Сначала мы удаляем полностью связанные верхние слои (близкие к выходным) модели, которая классифицирует изображения по 1000 классам. Назовем эту модель без верхних слоев базовой моделью. Затем мы прикрепляем несколько новых слоев к верху, которые классифицируют изображения по четырем интересующим нас классам: 1. CNV, 2.DME, 3. DRUSEN, 4. NORMAL.

Слои в базовой модели заблокированы и недоступны для обучения. Параметры базовой модели (также называемые весами) не обновляются во время обучения. Новая обновленная модель обучается с использованием 100 000 изображений OCT с дополнительными 1 000 изображений, используемых для проверки. Этот метод получил название трансферное обучение. У меня есть полностью обученная модель Keras, которая обеспечивает точность проверки 94% и доступна для скачивания и использования любым желающим.

Наряду с моделью также доступен простой метод Python для создания карт окклюзии. Карта окклюзии показывает, какой части изображения нейронная сеть уделяла больше внимания, чтобы принять решение о классификации изображения. Одна такая карта окклюзии для DRUSEN показана ниже.

Для создания этих карт окклюзии используется техника Gradient-weighted Class Activation Mapping (Grad-CAM).

Некоторые из преимуществ использования нейронных сетей для этих задач заключаются в следующем:

  • Модель легко обучить на существующих данных и переобучить, когда станут доступны новые данные.
  • Модель может классифицировать новые невидимые изображения менее чем за секунду. Модель может быть встроена в машины OCT, а также может быть доступна в виде приложения для смартфона или веб-приложения.
  • Карты окклюзии помогают нам определить, какая часть (какие особенности) изображения сыграла ключевую роль в классификации изображения. Эти карты можно использовать для обучения людей чтению OCT.
  • Используя методы Генеративная состязательная сеть (GAN), можно сгенерировать большое количество образцов синтетических изображений и использовать их для обучения людей и новых нейронных сетей.

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

Прочтите продолжение к этой статье: Более быстрое и качественное переносное обучение с глубокими нейронными сетями (ИИ) для обнаружения глазных болезней. Здесь я объясняю лучший и более быстрый подход к обучению с тем же набором данных.

Часть 2 - Реализация: обучение модели

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

Эта часть будет охватывать следующее:

  • Подбор и установка оборудования и программного обеспечения для глубокого обучения.
  • Загрузите данные и систематизируйте.
  • Написание кода для обучения модели.
  • Следующая часть будет посвящена оценке точности модели и карт окклюзии.

Исходный код Python доступен по адресу eyediseases-AI-keras-imagenet-inception. Используйте Train.ipynb в блокноте jupyter.

Выбор и установка оборудования и программного обеспечения для глубокого обучения

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

  • Intel - Процессор Core i3–6100 3,7 ГГц
  • Материнская плата ASUS - Z270F GAMING 3X ATX LGA1151
  • Corsair 16 ГБ - Vengeance LPX 8 ГБ (8 ГБ x 2) DDR4–2400
  • Графическая карта GeForce GTX 1060 6GB Mini ITX OC
  • Блок питания Antec 600 Вт
  • Шкаф Antec (GX200)
  • Samsung- SSD PLUS 2 x 240 ГБ 2,5 ″ твердотельный накопитель

Подробный список деталей также доступен в PC Part Picker.

Вы можете узнать о том, как создать собственное оборудование для глубокого обучения, из этой замечательной статьи: Создайте установку для глубокого обучения за 800 долларов. Тот же автор опубликовал статью Руководство по установке программного обеспечения Ubuntu + Deep Learning , которая также будет вам полезна.

В качестве альтернативы вы можете использовать экземпляр Amazon Web Service (AWS) с поддержкой графического процессора. Низкий уровень обычно стоит 0,90 доллара в час. За один месяц эксплуатационных расходов вы можете создать собственную машину глубокого обучения.

Хорошие люди из Cache Technologies, Бангалор помогли мне построить машину и протестировать ее.

Для остальной части программного обеспечения я использовал следующее:

Загрузите данные и систематизируйте

Посетите страницу Меченая оптическая когерентная томография (ОКТ) и рентгеновские снимки грудной клетки для классификации и загрузите OCT2017.tar.gz (3,4 ГБ).

Набор данных проверенных ОКТ и рентгеновских снимков грудной клетки, описанных и проанализированных в «Классификации на основе глубокого обучения и направлениях излечимых заболеваний человека». Изображения ОКТ разделены на обучающий набор и набор независимых пациентов для тестирования. Изображения OCT помечены как (заболевание) - (рандомизированный идентификатор пациента) - (номер изображения этого пациента) и разделены на 4 каталога: CNV, DME, DRUSEN и NORMAL.

Распакуйте tar-файл с помощью следующей команды:

% tar xvfz OCT2017.tar.gz

В результате должна появиться папка OCT2017 со следующими вложенными папками: test и train. И test, и train будут иметь подпапки с именами: CNV, DME, DRUSEN и NORMAL. В этих самых нижних папках находятся ОКТ-изображения в оттенках серого.

Создайте еще одну папку с именем eval в разделе OCT2017. Создайте необходимые подпапки CNV, DME, DRUSEN и NORMAL. Переместите несколько (100 изображений) из папок test и train в нужные папки eval, которые, наконец, используют для оценки модели.

Импортировать необходимые модули Python

Код анализа написан на питоне, работающем внутри Jupyter notebook. Вы можете скопировать и вставить код снизу в ячейки по порядку и нажать Shift + Enter, чтобы выполнить ячейку.

Первый шаг - импортировать необходимые модули:

import keras 
from keras.preprocessing.image import ImageDataGenerator 
from keras.applications.inception_v3 import InceptionV3 
from keras.layers import Dense, GlobalAveragePooling2D 
from keras.models import Model 
from keras import optimizers 
import matplotlib.pyplot as plt 
%matplotlib inline

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

InceptionV3 - это keras реализация модели Inception V3, доступная с весами изображений.

GlobalAveragePooling2D и Dense будут новым набором слоев, который мы добавим в верхнюю часть модели InceptionV3 после удаления существующих полностью связанных верхних слоев.

Настройка генераторов данных обучающих и тестовых изображений

train_datagen = ImageDataGenerator(rescale=1./255) 
test_datagen = ImageDataGenerator(rescale=1./255) 
train_dir = '../OCT2017/train/' 
test_dir = '../OCT2017/test/' 
train_generator = train_datagen.flow_from_directory( train_dir,
  target_size=(299, 299), batch_size=128, class_mode='categorical')
test_generator = test_datagen.flow_from_directory( test_dir,
  target_size=(299, 299), batch_size=128, class_mode='categorical')

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

train_generator и test_generator выдает 128 изображений в каждом пакете размером 299 × 299. Количество изображений в пакете зависит от объема памяти вашего графического процессора и основной системы. Первоначальные авторы использовали 1000 изображений в партии. Размер изображения 299 × 299 - это входной размер, необходимый для модели Inception V3. Подробнее про ImageDataGenerator здесь.

class_mode установлен на категориальный, поскольку нам нужно, чтобы выходные данные принадлежали 4 классам (CNV, DME, DRUSEN и NORMAL).

Загрузите InceptionV3 и прикрепите новые слои вверху

# create the base pre-trained model 
base_model = InceptionV3(weights='imagenet', include_top=False) 
# Get the output layer from the pre-trained Inception V3 model 
x = base_model.output 
# Now, add new layers that will be trained with our data 
# These layers will be randomly initialized 
x = GlobalAveragePooling2D()(x) 
x = Dense(64, activation='relu')(x) 
predictions = Dense(4, activation='softmax')(x) 
# Get the final Model to train model = Model(inputs=base_model.input, outputs=predictions) 
# Freeze the layers from the original base model so that we
# don't update the weights 
for layer in base_model.layers: 
    layer.trainable = False

Сначала мы загружаем модель InceptionV3 с предварительно обученными весами для imagenet. Установите include_top = False, чтобы исключить полностью связанный слой наверху сети, который выводит 1000 классов. . Вместо этого мы добавим наш собственный полностью связанный слой, который будет выводить 4 класса с помощью softmax.

Затем добавьте три слоя (GlobalAveragePooling2D, Dense, Dense with softmax) наверх. Мы используем GlobalAveragePooling2D вместо полностью подключенного (например, Dense) для обработки выходных данных базовой модели InceptionV3. Это помогает избежать переобучения и уменьшить количество параметров в окончательной модели. Последняя модель Dense имеет 4 единицы, соответствующие количеству выходных классов: CNV, DME, DRUSEN и NORMAL.

Наконец, сделать исходную базовую модель InceptionV3 не обучаемой, то есть заморозить сеть. Эти веса уже тренировались с помощью imagenet. Если вы сделаете их обучаемыми, параметры слоя (веса) будут обновляться с большими изменениями во время начального обучения, заставляя их забыть исходное обучение. Блокировка слоев также ускоряет обучение, поскольку при обратном распространении эти параметры слоя не нужно вычислять и обновлять.

Скомпилируйте модель

adam = optimizers.adam(lr=0.001) 
# Compile the new model 
model.compile(optimizer=adam, loss='categorical_crossentropy', 
   metrics=['accuracy'])

Выберите adam в качестве оптимизатора со скоростью обучения 0,001. Мы заинтересованы в минимизации потерь для категориальной перекрестной энтропии (имеется в виду много категорий: 4, если быть точным). Тренировка, точность тестирования и потери - вот те показатели, которые нам интересны.

Подберите модель с данными и сохраните лучшую модель во время обучения

# Setup a callback to save the best model 
callbacks = [keras.callbacks.ModelCheckpoint(
  'model.{epoch:02d}-{val_acc:.2f}.hdf5', 
  monitor='val_acc', verbose=1, save_best_only=True, 
  mode='max', period=1)] 
# Fit the data and output the history history = model.fit_generator(train_generator, verbose=1, 
  steps_per_epoch=len(train_generator), epochs=100,
  validation_data=test_generator,
  validation_steps=len(test_generator), callbacks=callbacks)

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

model.03–0.94.hdf5

03 - номер эпохи, а 0,94 - точность проверки.

Чтобы соответствовать данным, укажите количество эпох, то есть количество раз, когда модель увидит весь набор данных. steps_per_epoch - это количество пакетов данных, которые модель увидит за одну эпоху. Установите это на общее количество пакетов, которые выдаст генератор данных.

Следите за тренировкой и наносите на карту результаты

def plot_history(history): 
    acc = history.history['acc'] 
    val_acc = history.history['val_acc'] 
    loss = history.history['loss'] 
    val_loss = history.history['val_loss'] 
    epochs = range(1, len(acc) + 1) 
    plt.figure() 
    plt.title('Training and validation accuracy') 
    plt.plot(epochs, acc, 'bo', label='Training acc')
    plt.plot(epochs, val_acc, 'b', color='red', \
      label='Validation acc') 
    plt.legend() 
    plt.show() 
    plt.figure() 
    plt.title('Training and validation loss')
    plt.plot(epochs, loss, 'bo', label='Training loss')
    plt.plot(epochs, val_loss, 'b', color='red', \
      label='Validation loss') 
    plt.legend() 
    plt.show() 
    return acc, val_acc, loss, val_loss 
acc, val_acc, loss, val_loss = plot_history(history)

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

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

Часть 3 - Реализация: оценка модели

  • Импортировать необходимые модули Python
  • Загрузить сохраненную лучшую модель
  • Оцените модель для небольшого набора изображений
  • Напишите служебные функции, чтобы получать прогнозы для одного изображения за раз
  • Реализуйте функцию grad_CAM для создания карт окклюзии
  • Сделайте прогноз для одного изображения и создайте карту окклюзии
  • Делайте прогнозы для нескольких изображений и создавайте карты окклюзии для неправильно классифицированных изображений

Читайте полную информацию о части 3 с аннотированным исходным кодом здесь:

Часть 4. Резюме и ссылки для скачивания

В этой статье я описал три конкретных заболевания сетчатки глаза и то, как их можно идентифицировать по изображениям оптической когерентной томографии (ОКТ) вместе с нормальной сетчаткой глаза.

Используя технику трансферного обучения, я показываю, как предварительно обученную модель InceptionV3 Keras imagenet можно обучить с использованием большого количества ОКТ-изображений. Мы удаляем верхние слои, добавляем наши собственные полностью связанные слои и блокируем базовую модель, чтобы завершить обучение.

Мы сохраняем лучшие модели во время обучения, используя обратные вызовы Keras. Используя метрики, мы анализируем ход обучения.

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

Аннотированный исходный код Python доступен на GitHub: eyediseases-AI-keras-imagenet-inception. Обученную модель с точностью проверки 94% можно скачать отсюда (файл размером 84 МБ!).

Надеюсь, вам понравилась эта статья! Поделитесь своим опытом и отзывами, чтобы сделать эту статью лучше.

Прочтите продолжение к этой статье: Более быстрое и качественное переносное обучение с глубокими нейронными сетями (ИИ) для обнаружения глазных болезней. Здесь я объясняю лучший и более быстрый подход к обучению с тем же набором данных.

Первоначально опубликовано на blog.mapshalli.org 17 марта 2018 г.