Диагностика инфаркта миокарда с использованием сетей долгосрочной краткосрочной памяти (LSTM)

Вступление

Пару месяцев назад Керас выпустил слои CuDNNLSTM и CuDNNGRU, которые представляют собой специальные реализации обычных уровней LSTM и GRU, поддерживаемые библиотекой NVIDIA cuDNN. Это означает, что если у вас есть доступ к графическому процессору CUDA, обучение повторяющихся нейронных сетей стало намного быстрее.

В этом посте я покажу простую реализацию сети LSTM, реализованную в Keras с использованием нового CuDNNLSTM. Я также воспользуюсь этой возможностью, чтобы изучить Диагностическую базу данных ЭКГ PTB, базу данных, содержащую данные ЭКГ 238 пациентов с сердечными заболеваниями, и попытаться автоматически распознавать пациентов, перенесших инфаркт миокарда, из здоровой группы контроля.

Долговременная память

Прежде всего, что такое сети с долгосрочной памятью (LSTM)? Короткий ответ: это особая сеть, способная «запоминать» предыдущие входы. Каждый нейрон или узел LSTM в такой сети поддерживает внутреннее состояние на основе предыдущих входных данных. Он использует свое текущее состояние, чтобы делать прогнозы относительно новых входных данных. Во время тренировки он учится, что ему следует помнить и что он должен забыть, чтобы делать правильные прогнозы. Благодаря этому свойству LSTM хорошо подходят для задач классификации, касающихся данных временных рядов, таких как обработка естественного языка или… классификация сигналов ЭКГ!

Если вас больше интересует подробный ответ и вы хотите узнать больше о внутренней работе LSTM, я действительно рекомендую вам прочитать Блог Кола по этой теме, где он мастерски объясняет эту тему.

PhysioNet и база данных диагностической ЭКГ PTB

PhysioNet содержит несколько больших наборов данных о физиологических сигналах и выпустила соответствующий пакет программного обеспечения с открытым исходным кодом PhysioToolkit, который содержит множество полезных пакетов, позволяющих легко обрабатывать их наборы данных. Одним из наборов данных является База данных диагностики ЭКГ PTB. Он содержит записи ЭКГ 290 субъектов, из которых 52 являются здоровыми людьми из контрольной группы, 148 перенесли инфаркт миокарда (более известный как сердечный приступ). Остальные 90 человек страдают другим заболеванием сердца. Для этого примера мы будем использовать только записи пациентов с инфарктом миокарда и здоровых людей из контрольной группы.

Подготовка

Мы будем использовать реализацию Python Программного пакета WaveForm DataBase (wfdb) из PhysioToolkit для загрузки данных из Physiobank и взаимодействия с ними. Вы можете установить его через pip:

pip install wfdb

Помимо wfdb мы также будем использовать Tensorflow, keras, numpy, pandas, sklearn и matplotlib. Поскольку эти пакеты являются довольно стандартными в области машинного обучения, я предполагаю, что вы их уже установили, и не станете рассказывать об их установке.

Прежде чем мы начнем кодировать, сначала импортируйте все используемые пакеты:

Получение данных

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

Запись содержит несколько атрибутов. Мы будем использовать следующие:

  • record.p_signal: необработанные значения датчика из ЭКГ. Это numpy массив sig_len по n_channels. Длина сигнала (количество выборок) на запись может быть разной, но количество каналов всегда равно 15.
  • record.sig_name: имена каждого канала
  • record.sig_len: длина или номер выборки записи
  • record.comments: список строк, содержащих дополнительную информацию по теме. Он также включает причину приема (пятый пункт), который мы будем использовать в качестве ярлыка.

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

Исследование данных: сравнение данных

Теперь мы готовы заняться наукой о данных! Давайте сначала сравним ЭКГ здорового пациента контрольной группы и пациента с инфарктом:

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

Создание обучающего и тестового набора

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

Поскольку у некоторых субъектов есть несколько записей, и каждая запись разбита на отдельные окна, нам нужно отслеживать, кому принадлежит каждая последовательность в тестовом наборе. Это хранится в record_list.

Если вы хотите воспроизвести те же результаты, что и я, вы можете установить начальное число генератора случайных чисел на это псевдослучайно выбранное начальное число:

np.random.seed(1337)

Сборка LSTM

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

Обучение сети

Поскольку данные разделены на окна, сеть обучается на данных с окнами, изучая метку для каждого окна / последовательности. Поскольку существует большой дисбаланс класса (существует 16235 последовательностей инфаркта, из которых всего 3675 контрольных последовательностей), изучение здорового контроля будет сложнее, чем обучение инфаркту. Поэтому нам необходимо настроить вес выборки каждой последовательности и придать контрольным последовательностям большой вес.

Обучение этой сети не занимает много времени, около 5 минут на GTX1080.

Прогнозирование

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

В приведенном ниже блоке кода показано, как делать прогнозы, вычислять метки и использовать classification_report для расчета точности и отзыва.

Полученные результаты

Результаты могут немного отличаться в зависимости от разделения набора тестов и тренировок, но вы можете рассчитывать на точность и отзывчивость не менее 0,90 при инфаркте миокарда. Для здорового контроля эти цифры немного ниже, около 0,7 для точности и отзыва.

Заключение

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

Хотите узнать больше интересных вещей или сотрудничать с специалистами по обработке данных Orikami в индивидуальных медицинских проектах, над которыми вы или мы работаем? Отправьте электронное письмо на [email protected] или позвоните по телефону +31 24 3010100.