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

Краткий обзор анализа медицинских изображений, методов повышения производительности вашей CNN на реальных наборах данных

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

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

Обнаружение отклонений

Теперь переходим к основной теме, на которой мы сосредоточимся в этом блоге, - это обнаружение аномалий в костях. Заболевания и травмы костей являются основными факторами, способствующими возникновению аномалий в костях. Теперь происходит следующее: всякий раз, когда возникает травма кости, врач просит вас сделать рентгеновский снимок, поэтому, когда такие сотни пациентов посещают больницы каждый день, на регулярной основе делается огромное количество рентгеновских снимков. Если говорить конкретно о статистике, то заболевания опорно-двигательного аппарата затрагивают более 1,7 миллиарда человек во всем мире и являются наиболее частой причиной тяжелой долговременной боли и инвалидности, число которых ежегодно увеличивается до 30 миллионов обращений в отделения неотложной помощи. Итак, чтобы снизить частоту ошибок радиолога и сделать анализ намного быстрее, решение AI должно соответствовать цели.

Используемый набор данных

Итак, в прошлом году в Стэнфорде проводилось соревнование по глубокому обучению, участники которого должны были обнаружить аномалии костей. Набор данных широко известен как MURA. MURA - это набор данных рентгенограмм опорно-двигательного аппарата, состоящий из 14 863 исследований от 12 173 пациентов, в общей сложности 40 561 рентгенографический снимок в нескольких проекциях. Каждый относится к одному из семи стандартных типов рентгенографических исследований верхних конечностей: локтя, пальца, предплечья, кисти, плечевой кости, плеча и запястья. Вы можете скачать набор данных с официального сайта конкурса здесь.

Поскольку ИИ в области медицины переживает бум, я решил получить практический опыт работы с этим набором данных. Разработанные мной модели показали хорошие результаты и достигли Каппы, равной каппе, достигнутой командой Стэнфордского университета, а по некоторым показателям она действительно превзошла их. Я поделюсь сравнительной таблицей в конце этого блога. Остальная часть блога посвящена методам, которые я использовал для улучшения характеристик своих моделей. Без сомнения, вы можете попробовать эти методы и на других наборах данных.

Для начала я построил отдельные модели для всех семи разных органов. Для меня сработали модели DenseNet 169 (команда Стэнфорда использовала ансамбль из 5 таких моделей) и DenseNet121. Моими базовыми моделями были сети DenseNets, созданные в наборе данных изображений, и их передача была изучена на этом наборе данных. Но, к сожалению, результаты были не совсем близки к Стэнфордской каппе, средняя каппа, которую я достиг, составила около 0,5. А потом я начал искать в Интернете различные советы и уловки, позволяющие вашим CNN говорить за вас.

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

Планировщики скорости обучения

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

1. Step Decay: этот метод включает снижение скорости обучения после определенного заранее определенного количества эпох. Вы можете написать свою реализацию этого. У меня было следующее:

def step_decay(epoch):
   initial_lrate = 0.0001
   drop = 0.1
   epochs_drop = 10.0
   lrate = initial_lrate*          math.pow(drop,math.floor((1+epoch)/epochs_drop))
   return lrate

Эта функция в основном снижает скорость обучения до 1/10 от ее начального значения через каждые 10 эпох.
Ее можно включить в обратные вызовы следующим образом:

lrate = LearningRateScheduler(step_decay)
callbacks = [lrate]

2. Распад на основе потерь: этот метод снижает скорость обучения после выдержки определенных предопределенных эпох, когда модель перестает улучшаться. В Keras есть встроенный модуль с именем ReduceLRonPlateau, который показан в приведенном ниже коде.

reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1,
patience=10, min_delta=0.0001, verbose=1, min_lr=0.0000001)
callbacks = [reduce_lr]

Вышеупомянутая функция отслеживает потерю проверки, и как только она перестает уменьшаться в течение 10 эпох, она снижает скорость обучения в 0,1 раза. Здесь моя модель имела начальную скорость обучения 0,001, и с помощью этой функции я мог получить значение min_lr, равное 10–6.
Для меня более поздняя методика оказалась более эффективной. Чтобы получить подробный обзор того, как оптимизировать производительность модели с помощью скорости обучения, вы можете просмотреть эту впечатляющую статью.

Наказание за вес класса

Это один из приемов, с которыми я столкнулся, читая об оптимизации производительности модели при дисбалансе классов. Хотя, когда классовый дисбаланс не слишком велик, от этого мало пользы. Но в моем случае положительные случаи были примерно на 2/3 меньше отрицательных. Итак, я использовал эту технику для обучения модели. Это можно сделать двумя способами:

  1. Установите веса классов вручную для каждого из классов, вычислив дисбаланс в обучающей выборке.
class_weight = {0: 1, 1: 1.5}
model.fit(X_train, Y_train, nb_epoch=50, batch_size=32, class_weight=class_weight)

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

from sklearn.utils import class_weight
class_weights = class_weight.compute_class_weight('balanced', np.unique(y_train), y_train)
model.fit(X_train, y_train, class_weight=class_weights)

Цитата из одного из ответов stackexchange на вопрос о вычислении весов классов для обучения модели. Он говорит:

Штраф за вес класса выполняется для того, чтобы заставить ваш алгоритм обрабатывать каждый экземпляр класса 1 как 1,5 экземпляра класса 0. По сути, «обрабатывает каждый экземпляр класса 1 как 1,5 экземпляра класса 0, это означает, что в вашей функции потерь вы присваиваете более высокое значение. этим экземплярам. Следовательно, потеря становится средневзвешенной, где вес каждой выборки определяется class_weight и его соответствующим классом.

Опробование различных моделей

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

Например, команда Стэнфордского университета в этом случае использовала DenseNet169 для обучения моделей для всех костей, но я попробовал DenseNet121 для всех из них и выяснил, что для Finger and Hand DenseNet121 значительно превосходит DenseNet169. Другие, которые я пробовал, включают ResNet50 и Inceptionv3, но они никогда не работали должным образом.

Увеличение объема данных

Этот метод используется, когда набор данных состоит из меньшего количества образцов или изображения имеют разную ориентацию. Здесь мы попросили нас создать двоичный классификатор, чтобы определить, есть ли у костей какие-то аномалии или они нормальные. Хотя в наборе данных было около 1000–2000 образцов каждой кости для положительного класса, ориентация все же различалась. Ниже приведен образец изображения из Hand data.

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

from keras.preprocessing.image import ImageDataGenerator
train_datagen=ImageDataGenerator(
     horizontal_flip=True,
    #vertical_flip=True,
     rotation_range=90,
    #width_shift_range=0.2,
    #height_shift_range=0.2 )
train_datagen.fit(X_train)

Вы можете обучить модель с помощью этого генератора, используя fit_generator в Keras. Для подробного обзора генератора данных изображения вы можете посетить эту ссылку.
Вы также можете написать свой собственный batch_generator и использовать библиотеки с открытым исходным кодом, такие как imgaug, для увеличения данных.

Различные оптимизаторы

Вы можете использовать различные оптимизаторы как часть настройки гиперпараметров. Вы можете изменить его на SGD, Адам. Я всегда использовал «rmsprop» как часть тренировок, но команда Стэнфорда использовала «Adam» с измененными некоторыми конкретными параметрами. Хотя мне не удалось улучшить производительность модели, изменив оптимизаторы, но почему бы не попробовать, если у вас есть варианты, а также время?

Объединение

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

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

Результаты

Таблица сравнения результатов Стэнфордской команды и результатов из моей таблицы выглядит следующим образом.

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

P. S. Вышеупомянутые методы также полезны для улучшения ваших моделей для других наборов данных, и ни один из них не является специфическим для медицинской области. Как и в Data Science, широко говорят: «В конце концов, вкратце, действительно важна ваша интуиция». Таким образом, развивайте свою интуицию и используйте ее на практике, чтобы получить наилучшие результаты.

использованная литература

[1] Мартин Райчл, (4 июля 2018 г.), Введение в биомедицинский анализ изображений с помощью TensorFlow и DLTK
[2] С. Ренукалата и К.В. Суреш (2018), ОБЗОР БИОМЕДИЧЕСКОГО АНАЛИЗА ИЗОБРАЖЕНИЙ
[3] Официальный сайт конкурса Stanford MURA
[4] Пранав Раджпуркар, Джереми Ирвин, Арти Багул, Дейзи Динг, Тони Дуан, Хершел Мехта, Брэндон Янг, Кейли Чжу, Диллон Лэрд, Робин Л. Болл, Кертис Ланглоц, Кэти Шпанская, Мэтью П. Лунгрен, Эндрю Й. Нг, (22 мая 2018 г.), MURA: большой набор данных для обнаружения аномалий на рентгенограммах опорно-двигательного аппарата
[5 ] Джейсон Браунли, (25 января 2019 г.), Понимание влияния скорости обучения на производительность нейронной сети
[6] Тема о санкционировании веса класса при обмене стеками.
[7] Документация Кераса