Реализация нейронной сети с Python (Keras) для классификации рентгеновских изображений

В моем последнем блоге я показал вам, ребята, как создать нейронную сеть, которая может прогнозировать игру игрока НБА в любую ночь. Хотя это был очень интересный проект, я не смог протестировать его в регулярном сезоне из-за COVID-19. Учитывая глобальную пандемию, я действительно не решался начинать новый проект, так как этот год можно считать нестандартным не только в спорте, но и в финансовом и эмоциональном анализе. Решив эту проблему, я начал поиск в Kaggle и наткнулся на набор данных, заполненный рентгеновскими изображениями как нормальных, так и ненормальных легких (пневмония). Это заинтриговало меня, поэтому я продолжил поиск в других базах данных и нашел больше помеченных фотографий. Мне удалось объединить два набора данных в одну папку (без дубликатов), всего 6000 изображений. Используя эти изображения, я покажу вам, как создать сверточную нейронную сеть, которая может предсказать, есть ли у человека пневмония, с точностью ~ 98% (набор тестов).

Наборы данных

  • Kaggle CoronaHack
  • Набор данных COVID GitHub
  • GoogleDrive (содержит комбинированные наборы данных, соленья и CSV с путями к изображениям / метками)

Сверточная нейронная сеть

Хотя мы видим изображения с цветом и формами, на самом базовом уровне они представляют собой списки чисел, каждое из которых соответствует значению RGB, которое затем обрабатывается вашим компьютером, чтобы показать вам изображение. Сверточные нейронные сети получили распространение при обработке изображений, поскольку они могут разбивать массив RGB на (1x1), (2x2) или (3x3) пиксели, чтобы изучать шаблоны в изображении.

** Весь приведенный ниже код можно найти на моем GitHub ***

Код

Набор данных с .csv был слишком большим для загрузки на мой GitHub, поэтому вместо этого я опубликовал его на своем GoogleDrive.

Пакеты

  • Sklearn
  • Керас
  • Tensorflow
  • Панды
  • Numpy
  • Соленый огурец
  • Матплотлиб и Сиборн

Тренировка тестового сплита

Поскольку это мой первый проект классификации изображений, понимание архитектуры для правильного разделения данных на тестирование и обучение заняло у меня несколько часов, особенно после того, как я собрал данные из нескольких источников. В итоге я выбрал следующий подход: (1) я сначала создал файл CSV с путями и метками для каждого изображения (2) Разделил поезд и протестировал, как обычно, разделив каждую группу на основе их меток, (3) Затем я перебрал каждый путь к изображению и извлек его значения RGB.

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

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

Я обнаружил, что сигмовидная активация лучше подходит для этой модели, поскольку она более точна для двоичной классификации. Если бы вы настроили эту модель для прогнозирования типа пневмонии (вирусной, грибковой и т. Д.), Тогда для выходного слоя лучше было бы активировать softmax, а использование категорической_crossentropy было бы лучше, чем binary_crossentropy.

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

Оценка модели

Параметр контрольной точки модели смог остановить модель на 30 эпохах, чтобы предотвратить дальнейшее переобучение. Глядя на график ниже, мы видим, что последовательность и точность теста стабильно превышают 96%. Однако я понял одну вещь: никогда нельзя принимать точность за чистую монету. Чтобы лучше изучить производительность модели, я построил кривые AUC, ROC и границы принятия решений, чтобы определить, как модель изменяется с использованием различных пороговых значений. Опять же, весь код этих графиков можно найти на моем GitHub.

Модель имела оценки F1, AUC и ROC 0,935, 0,972 и 0,994 соответственно.

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

Чтобы протестировать модель на внешних данных, я собрал 17 изображений из Google и использовал порог вероятности 0,65. Как вы можете видеть ниже, у модели была 100% истинно положительная оценка и 56% истинно отрицательная оценка. Если вы загрузите код в моем репо, там есть папка, в которой вы можете попробовать сделать предсказание самостоятельно. Все, что вам нужно сделать, это загрузить изображение, назвать файл нормальным или нестандартным, чтобы запомнить его метку, затем запустить код.

Будущие направления

  • Классифицируйте тип пневмонии (вирусная, грибковая и др.)
  • Используйте шкалу серого (одномерный массив)
  • Примените SMOTE, чтобы изменить дисбаланс классов
  • Используйте изображения большего размера с размерами (96,96,3) или (204, 204,4). Сначала я попытался использовать большие размеры, но мой компьютер был слишком низким. Изображение большего размера может сделать обнаружение более точным, поскольку в нем больше деталей, чем в последнем.