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

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

Установите OpenCV

Установка OpenCV — это начальный этап. Существуют различные способы установки OpenCV в зависимости от вашей операционной системы. Вот несколько популярных вариантов:

Windows: на основном веб-сайте OpenCV используйте предварительно собранные двоичные файлы.

Linux: OpenCV можно установить с помощью диспетчера пакетов, включенного в дистрибутив Linux. Выполните следующую инструкцию в терминале, например, в Ubuntu:

Install libopencv-dev with sudo apt-get

Mac OS: OpenCV можно настроить с помощью Homebrew, код ниже следует ввести в терминал.

Brew install opencv

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

import cv2
print(cv2.__version__)

Вы должны увидеть номер версии, отображаемый в терминале, если OpenCV был установлен правильно.

Загрузить набор данных

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

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

kaggle datasets download -d paultimothymooney/chest-xray-pneumonia

ZIP-файл, содержащий информацию, будет загружен. Создайте подпапку на локальном компьютере и распакуйте ZIP-файл.

Подготовьте данные

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

Мы создадим два каталога для подготовки данных: один для обучающих изображений и один для проверочных изображений. 80% изображений будут использоваться для обучения, а 20% — для проверки.

Вот код для подготовки информации:

import os
import shutil
import random

# Define the paths
input_dir = 'path/to/input/dir'
train_dir = 'path/to/train/dir'
val_dir = 'path/to/val/dir'

# Create the directories
os.makedirs(train_dir, exist_ok=True)
os.makedirs(val_dir, exist_ok=True)

# Get the list of images
image_paths = []
for root, dirs, files in os.walk(input_dir):
    for file in files:
        if file.endswith('.jpeg'):
            image_paths.append(os.path.join(root, file))

# Shuffle the images
random.shuffle(image_paths)

# Split

split_idx = int(0.8 * len(image_paths))
train_image_paths = image_paths[:split_idx]
val_image_paths = image_paths[split_idx:]

Теперь скопируйте изображения в каталоги. Измените «path/to/input/dir» на путь к каталогу, в который вы извлекли информацию в этом коде. Пути к каталогам, в которых вы хотите хранить обучающие и проверочные образы, соответственно, следует заменить на «путь/к/поезду/каталогу» и «путь/к/вал/каталогу».

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

Обучение модели

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

Вот код для обучения модели:

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.applications import VGG16
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# Define the input shape of the images
input_shape = (224, 224, 3)

# Load the VGG16 model
base_model = VGG16(weights='imagenet', include_top=False, input_shape=input_shape)

# Add a global average pooling layer
x = base_model.output
x = GlobalAveragePooling2D()(x)

# Add a fully connected layer
x = Dense(128, activation='relu')(x)

# Add the output layer
output = Dense(1, activation='sigmoid')(x)

# Define the model
model = Model(inputs=base_model.input, outputs=output)

# Freeze the layers of the VGG16 model
for layer in base_model.layers:
    layer.trainable = False

# Compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

# Define the data generators for training and validation
train_datagen = ImageDataGenerator(rescale=1./255,
                                   rotation_range=10,
                                   width_shift_range=0.1,
                                   height_shift_range=0.1,
                                   shear_range=0.1,
                                   zoom_range=0.1,
                                   horizontal_flip=True,
                                   fill_mode='nearest')

val_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(train_dir,
                                                    target_size=input_shape[:2],
                                                    batch_size=32,
                                                    class_mode='binary')

val_generator = val_datagen.flow_from_directory(val_dir,
                                                target_size=input_shape[:2],
                                                batch_size=32,
                                                class_mode='binary')

# Train the model
model.fit(train_generator,
          steps_per_epoch=len(train_generator),
          epochs=10,
          validation_data=val_generator,
          validation_steps=len(val_generator))

Сначала мы загрузили предварительно обученные веса из набора данных ImageNet в модель VGG16. Мы также включаем выходной слой с сигмовидной функцией активации, полностью связанный слой со 128 нейронами и слой глобального среднего пула. Слои модели VGG16 заморожены, и для построения модели используются алгоритм Адама и бинарная кросс-энтропийная потеря. После этого мы указываем генераторы данных для обучения и проверки, которые увеличивают данные и масштабируют значения пикселей в диапазоне [0, 1].

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

Оцените модель

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

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

import numpy as np
import matplotlib.pyplot as plt

# Define the path to the test directory
test_dir = 'path/to/input/dir/chest_xray/test'

# Define the data generator for test
test_datagen = ImageDataGenerator(rescale=1./255)

test_generator = test_datagen.flow_from_directory(test_dir,
                                                  target_size=input_shape[:2],
                                                  batch_size=32,
                                                  class_mode='binary',
                                                  shuffle=False)

# Evaluate the model on the test set
loss, accuracy = model.evaluate(test_generator, steps=len(test_generator))
print(f'Test accuracy: {accuracy:.2f}')

# Get the predictions and true labels
predictions = model.predict(test_generator, steps=len(test_generator))
predictions = np.squeeze(predictions)
true_labels = test_generator.labels

# Get the image filenames
filenames = test_generator.filenames

# Find the indices of the correctly and incorrectly classified images
correct_indices = np.where((predictions >= 0.5) == true_labels)[0]
incorrect_indices = np.where((predictions >= 0.5) != true_labels)[0]

# Plot some correctly classified images
plt.figure(figsize=(10, 10))
for i, idx in enumerate(correct_indices[:9]):
    plt.subplot(3, 3, i+1)
    img = plt.imread(os.path.join(test_dir, filenames[idx]))
    plt.imshow(img, cmap='gray')
    plt.title('PNEUMONIA' if predictions[idx] >= 0.5 else 'NORMAL')
    plt.axis('off')

# Plot some incorrectly classified images
plt.figure(figsize=(10, 10))
for i, idx in enumerate(incorrect_indices[:9]):
    plt.subplot(3, 3, i+1)
    img = plt.imread(os.path.join(test_dir, filenames[idx]))
    plt.imshow(img, cmap='gray')
    plt.title('PNEUMONIA' if predictions[idx] >= 0.5 else 'NORMAL')
    plt.axis('off')

plt.show()

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

Заключение

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

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

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

Независимая от редакции, Heartbeat спонсируется и публикуется Comet, платформой MLOps, которая позволяет специалистам по данным и командам машинного обучения отслеживать, сравнивать, объяснять и оптимизировать свои эксперименты. Мы платим нашим авторам и не продаем рекламу.

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