Обнаружение рака легких с использованием сверточной нейронной сети (CNN)
Компьютерное зрение — это одно из приложений глубоких нейронных сетей, которое позволяет нам автоматизировать задачи, которые ранее требовали многолетнего опыта, и одно из таких применений для прогнозирования наличия раковых клеток.
В этой статье мы узнаем, как создать классификатор, используя простую нейронную сеть свертки, которая может классифицировать нормальные ткани легких от раковых. Этот проект был разработан с использованием совместной работы, а набор данных был взят из Kaggle, ссылка на который также была предоставлена.
Процесс, который будет сопровождаться для создания этого классификатора:
Используемые модули
Библиотеки Python позволяют нам очень легко обрабатывать данные и выполнять типичные и сложные задачи с помощью одной строки кода.
- Pandas — эта библиотека помогает загружать фрейм данных в формате 2D-массива и имеет несколько функций для выполнения задач анализа за один раз.
- Numpy — массивы Numpy очень быстрые и могут выполнять большие вычисления за очень короткое время.
- Matplotlib — эта библиотека используется для рисования визуализаций.
- Sklearn — этот модуль содержит несколько библиотек с предварительно реализованными функциями для выполнения задач от предварительной обработки данных до разработки и оценки моделей.
- OpenCV — это библиотека с открытым исходным кодом, в основном предназначенная для обработки и обработки изображений.
- Tensorflow — это библиотека с открытым исходным кодом, которая используется для машинного обучения и искусственного интеллекта и предоставляет ряд функций для реализации сложных функций с помощью одной строки кода.
Python3
import numpy as np import pandas as pd import matplotlib.pyplot as plt from PIL import Image from glob import glob from sklearn.model_selection import train_test_split from sklearn import metrics import cv2 import gc import os import tensorflow as tf from tensorflow import keras from keras import layers import warnings warnings.filterwarnings( "ignore" ) |
Импорт набора данных
Набор данных, который мы будем здесь использовать, был взят с https://www.kaggle.com/datasets/andrewmvd/lung-and-colon-cancer-histopathological-images. Этот набор данных включает 5000 изображений для трех классов заболеваний легких:
- Нормальный класс
- Аденокарциномы легких
- Плоскоклеточный рак легкого
Эти изображения для каждого класса были разработаны из 250 изображений путем выполнения над ними увеличения данных. Вот почему мы больше не будем использовать Data Augmentation для этих изображений.
Python3
from zipfile import ZipFile data_path = "lung-and-colon-cancer-histopathological-images.zip" with ZipFile(data_path, "r" ) as zip : zip .extractall() print ( "The data set has been extracted." ) |
Выход:
The data set has been extracted.
Визуализация данных
В этом разделе мы попытаемся понять визуализацию некоторых изображений, которые были предоставлены нам для создания классификатора для каждого класса.
Python3
path = "lung_colon_image_set/lung_image_sets" classes = os.listdir(path) classes |
Выход:
["lung_n", "lung_aca", "lung_scc"]
Вот три класса, которые у нас есть.
Python3
path = "/lung_colon_image_set/lung_image_sets" for cat in classes: image_dir = f "{path}/{cat}" images = os.listdir(image_dir) fig, ax = plt.subplots( 1 , 3 , figsize = ( 15 , 5 )) fig.suptitle(f "Images for {cat} category . . . ." , fontsize = 20 ) for i in range ( 3 ): k = np.random.randint( 0 , len (images)) img = np.array(Image. open (f "{path}/{cat}/{images[k]}" )) ax[i].imshow(img) ax[i].axis( "off" ) plt.show() |
Выход:
Приведенный выше вывод может отличаться, если вы будете запускать его в своей записной книжке, потому что код был реализован таким образом, что он будет отображать разные изображения каждый раз, когда вы перезапускаете код.
Подготовка данных для обучения
В этом разделе мы преобразуем данные изображения в массивы пикселей NumPy после изменения их размера, потому что обучение глубокой нейронной сети на изображениях большого размера крайне неэффективно с точки зрения вычислительных затрат и времени.
Для этой цели мы будем использовать библиотеку OpenCV и библиотеку Python Numpy. Кроме того, после того, как все изображения будут преобразованы в нужный формат, мы разделим их на данные обучения и проверки, чтобы мы могли оценить производительность нашей модели.
Python3
IMG_SIZE = 256 SPLIT = 0.2 EPOCHS = 10 BATCH_SIZE = 64 |
Некоторые из гиперпараметров, которые мы можем настроить здесь для всей записной книжки.
Python3
X = [] Y = [] for i, cat in enumerate (classes): images = glob(f "{path}/{cat}/*.jpeg" ) for image in images: img = cv2.imread(image) X.append(cv2.resize(img, (IMG_SIZE, IMG_SIZE))) Y.append(i) X = np.asarray(X) one_hot_encoded_Y = pd.get_dummies(Y).values |
Одно горячее кодирование поможет нам обучить модель, которая может предсказывать мягкие вероятности того, что изображение относится к каждому классу с наибольшей вероятностью для класса, к которому оно действительно принадлежит.
Python3
X_train, X_val, Y_train, Y_val = train_test_split(X, one_hot_encoded_Y, test_size = SPLIT, random_state = 2022 ) print (X_train.shape, X_val.shape) |
Выход:
(12000, 256, 256, 3) (3000, 256, 256, 3)
На этом шаге мы добьемся автоматического перемешивания данных, потому что функция train_test_split случайным образом разделяет данные в заданном соотношении.
Разработка модели
Начиная с этого шага, мы будем использовать библиотеку TensorFlow для построения нашей модели CNN. Платформа Keras библиотеки тензорных потоков содержит все функции, которые могут понадобиться для определения архитектуры сверточной нейронной сети и ее обучения данным.
Архитектура модели
Мы реализуем последовательную модель, которая будет содержать следующие части:
- Три сверточных слоя, за которыми следуют слои MaxPooling.
- Слой Flatten для выравнивания выходных данных сверточного слоя.
- Тогда у нас будет два полносвязных слоя, за которыми следует вывод сглаженного слоя.
- Мы включили несколько слоев BatchNormalization, чтобы обеспечить стабильное и быстрое обучение, и слой Dropout перед последним слоем, чтобы избежать любой возможности переобучения.
- Последний слой — это выходной слой, который выводит мягкие вероятности для трех классов.
Python3
model = keras.models.Sequential([ layers.Conv2D(filters = 32 , kernel_size = ( 5 , 5 ), activation = "relu" , input_shape = (IMG_SIZE, IMG_SIZE, 3 ), padding = "same" ), layers.MaxPooling2D( 2 , 2 ), layers.Conv2D(filters = 64 , kernel_size = ( 3 , 3 ), activation = "relu" , padding = "same" ), layers.MaxPooling2D( 2 , 2 ), layers.Conv2D(filters = 128 , kernel_size = ( 3 , 3 ), activation = "relu" , padding = "same" ), layers.MaxPooling2D( 2 , 2 ), layers.Flatten(), layers.Dense( 256 , activation = "relu" ), layers.BatchNormalization(), layers.Dense( 128 , activation = "relu" ), layers.Dropout( 0.3 ), layers.BatchNormalization(), layers.Dense( 3 , activation = "softmax" ) ]) |
Напечатаем сводку по архитектуре модели:
Python3
model.summary() |
Выход:
Model: “sequential”
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 256, 256, 32) 2432
max_pooling2d (MaxPooling2D (None, 128, 128, 32) 0
)
conv2d_1 (Conv2D) (None, 128, 128, 64) 18496
max_pooling2d_1 (MaxPooling (None, 64, 64, 64) 0
2D)
conv2d_2 (Conv2D) (None, 64, 64, 128) 73856
max_pooling2d_2 (MaxPooling (None, 32, 32, 128) 0
2D)
flatten (Flatten) (None, 131072) 0
dense (Dense) (None, 256) 33554688
batch_normalization (BatchN (None, 256) 1024
normalization)
dense_1 (Dense) (None, 128) 32896
dropout (Dropout) (None, 128) 0
batch_normalization_1 (Batc (None, 128) 512
hNormalization)
dense_2 (Dense) (None, 3) 387
=================================================================
Total params: 33,684,291
Trainable params: 33,683,523
Non-trainable params: 768
_________________________________________________________________
Сверху мы можем видеть изменение формы входного изображения после прохождения через разные слои. Разработанная нами модель CNN содержит около 33,5 миллионов параметров. Именно это огромное количество параметров и сложность модели помогают получить высокопроизводительную модель, которая используется в реальных приложениях.
Python3
keras.utils.plot_model( model, show_shapes = True , show_dtype = True , show_layer_activations = True ) |
Выход:
Python3
model. compile ( optimizer = "adam" , loss = "categorical_crossentropy" , metrics = [ "accuracy" ] ) |
При составлении модели мы предоставляем эти три основных параметра:
- оптимизатор — это метод, который помогает оптимизировать функцию стоимости с помощью градиентного спуска.
- потеря — функция потерь, с помощью которой мы отслеживаем, улучшается ли модель с обучением или нет.
- Метрики — это помогает оценить модель, предсказывая данные обучения и проверки.
Перезвонить
Обратные вызовы используются для проверки того, улучшается ли модель с каждой эпохой или нет. Если нет, то какие необходимые шаги необходимо предпринять, например, ReduceLROnPlateau еще больше снижает скорость обучения. Даже в этом случае, если производительность модели не улучшится, обучение будет остановлено EarlyStopping. Мы также можем определить некоторые пользовательские обратные вызовы, чтобы остановить обучение между ними, если желаемые результаты были получены раньше.
Python3
from keras.callbacks import EarlyStopping, ReduceLROnPlateau class myCallback(tf.keras.callbacks.Callback): def on_epoch_end( self , epoch, logs = {}): if logs.get( "val_accuracy" ) > 0.90 : РЕКОМЕНДУЕМЫЕ СТАТЬИ |