Введение

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

В этом проекте мы разработали модель классификации рака кожи с использованием архитектуры ResNet50V2, которая представляет собой глубокую сверточную нейронную сеть, показавшую многообещающие результаты в различных задачах компьютерного зрения. Модель обучается на наборе данных изображений поражений кожи и может классифицировать типы рака по 9 различным классам, включая меланому, базально-клеточную карциному и плоскоклеточную карциному. Кроме того, мы использовали набор инструментов AI Analytics на основе Intel oneAPI для повышения производительности модели как при обучении, так и при тестировании.

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

Инструменты и предпосылки

Построение модели классификации рака кожи требует использования нескольких библиотек и модулей на Python. Эти предварительные условия помогают в построении, обучении и развертывании модели глубокого обучения. Эти библиотеки включают tkinter, matplotlib, tensorflow, keras, Pillow, OpenCV, scikit-image и numpy.

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

Matplotlib – это библиотека визуализации данных, позволяющая создавать графики, диаграммы и другие средства визуализации.

TensorFlow — это библиотека машинного обучения, используемая для создания, обучения и развертывания моделей глубокого обучения.

Keras — это высокоуровневый API, созданный на основе TensorFlow, который упрощает создание моделей глубокого обучения.

Pillow – это библиотека, в которую добавлена ​​поддержка открытия, обработки и сохранения множества различных форматов файлов изображений.

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

Scikit-image – это библиотека обработки изображений, предоставляющая инструменты для сегментации изображений, фильтрации и выделения признаков.

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

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

Выполнение

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('default')

import os
import tensorflow as tf
import keras
import cv2
from skimage import io

from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from tensorflow.keras.utils import plot_model
from tensorflow.keras import layers , models, optimizers
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import *
from tensorflow.keras.applications.resnet_v2 import preprocess_input
from tensorflow.keras.applications import ResNet50V2
from tensorflow.keras.models import load_model

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

  1. pandas: Эта библиотека используется для обработки и анализа данных.
  2. numpy: Эта библиотека используется для числовых вычислений и обработки данных.
  3. matplotlib: Эта библиотека используется для визуализации данных и построения графиков.
  4. os: Эта библиотека обеспечивает способ взаимодействия с файловой системой.
  5. tensorflow: эта библиотека используется для создания, обучения и развертывания моделей глубокого обучения.
  6. keras: это высокоуровневый API, созданный на основе TensorFlow и используемый для построения моделей глубокого обучения.
  7. cv2: Эта библиотека используется для обработки изображений и компьютерного зрения.
  8. skimage: Эта библиотека предоставляет инструменты для обработки изображений и манипулирования ими.
  9. ImageDataGenerator: Этот класс используется для увеличения данных в реальном времени во время обучения модели.
  10. load_img и img_to_array: эти функции используются для загрузки изображений из файла и преобразования их в массивы.
  11. EarlyStopping и ModelCheckpoint: это функции обратного вызова, используемые во время обучения модели, чтобы остановить обучение раньше, если модель сошлась, и сохранить лучшие веса модели во время обучения.
  12. plot_model: Эта функция используется для построения архитектуры модели.
  13. layers, models и optimizers: эти модули предоставляют различные функции для определения архитектуры и алгоритма оптимизации модели.
  14. ResNet50V2: Это предварительно обученная модель сверточной нейронной сети, используемая для извлечения признаков.
  15. load_model: Эта функция используется для загрузки сохраненной модели.
img_shape_x = 200
img_shape_y = 200
batch_size = 64
train_data_path = 'dataset/Train/'
val_data_path = 'dataset/Validation/'

В приведенном выше фрагменте кода мы определяем и инициализируем некоторые переменные, которые будут использоваться в модели классификации рака кожи:

  1. img_shape_x и img_shape_y: Эти переменные определяют размер входных изображений в направлениях x и y. В этом случае входные изображения изменяются до 200x200 пикселей.
  2. batch_size: эта переменная определяет количество изображений, которые будут передаваться модели во время каждой итерации обучения. В этом случае мы используем размер пакета 64.
  3. train_data_path и val_data_path: эти переменные определяют пути к наборам данных для обучения и проверки. Набор данных для обучения находится в папке dataset/Train/, а набор данных для проверки — в папке dataset/Validation/.

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

train_preprocessor = ImageDataGenerator(
        rescale = 1 / 255.,
        rotation_range=10,
        zoom_range=0.2,
        width_shift_range=0.1,
        height_shift_range=0.1,
        horizontal_flip=True,                                        
        fill_mode='nearest',
    )


val_preprocessor = ImageDataGenerator(
    rescale = 1 / 255.,
)

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

  1. rescale: этот параметр используется для нормализации значений пикселей изображений путем деления каждого значения пикселя на 255, что позволяет масштабировать значения пикселей от 0 до 1.
  2. rotation_range: этот параметр указывает диапазон случайных поворотов, которые можно применять к изображениям во время обучения. При этом изображения можно поворачивать на угол до 10 градусов.
  3. zoom_range: этот параметр указывает диапазон случайных масштабов, которые можно применять к изображениям во время обучения. В этом случае изображения можно увеличивать или уменьшать до 20%.
  4. width_shift_range и height_shift_range: эти параметры определяют диапазон случайных сдвигов по горизонтали и вертикали, которые можно применять к изображениям во время обучения. В этом случае изображения могут быть смещены до 10% от их ширины или высоты.
  5. horizontal_flip: этот параметр указывает, могут ли изображения произвольно переворачиваться по горизонтали во время обучения.
  6. fill_mode: Этот параметр указывает, как должны быть заполнены любые пустые пиксели, созданные вышеуказанными преобразованиями. В этом случае используется ближайший пиксель.

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

train_data = train_preprocessor.flow_from_directory(
    train_data_path,
    class_mode="categorical",
    target_size=(img_shape_x,img_shape_y),
    color_mode='rgb', 
    shuffle=True,
    batch_size=batch_size,
    subset='training', 
)


val_data = val_preprocessor.flow_from_directory(
    val_data_path,
    class_mode="categorical",
    target_size=(img_shape_x,img_shape_y),
    color_mode="rgb",
    shuffle=False,
    batch_size=batch_size,
)

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

  1. train_preprocessor.flow_from_directory(): этот метод создает пакеты данных для обучающего набора данных, расположенного по пути, указанному train_data_path. Параметр class_mode указывает, что метки для изображений являются категориальными. Параметр target_size указывает размер входных изображений. Параметр color_mode указывает, что изображения должны считываться в цветовом формате RGB. Параметр shuffle указывает, следует ли перемешивать пакеты данных перед их подачей в модель во время обучения. Параметр batch_size указывает количество изображений в каждом пакете данных. Параметр subset указывает, что мы используем обучающее подмножество набора данных.
  2. val_preprocessor.flow_from_directory(): этот метод создает пакеты данных для набора данных проверки, расположенного по пути, указанному val_data_path. Параметры class_mode, target_size, color_mode, shuffle и batch_size аналогичны методу train_preprocessor.flow_from_directory(), но для параметра shuffle установлено значение False, поскольку данные проверки не должны перемешиваться во время оценки.

Метод flow_from_directory() считывает изображения из каталогов, указанных в train_data_path и val_data_path, применяет шаги предварительной обработки, определенные объектами ImageDataGenerator, и создает пакеты данных указанного размера. Затем эти пакеты данных используются для обучения и оценки модели классификации рака кожи.

num_classes = train_data.num_classes

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

  1. train_data.num_classes: этот метод возвращает количество классов в обучающем наборе данных. Это основано на количестве подкаталогов в каталоге, указанном train_data_path, где каждый подкаталог представляет другой класс рака кожи.

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

ResNet50V2 = tf.keras.applications.ResNet50V2(input_shape=(img_shape_x, img_shape_y, 3),
                                               include_top= False,
                                               weights='imagenet'
                                               )

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

  1. tf.keras.applications.ResNet50V2: Этот метод загружает предварительно обученную модель CNN ResNet50V2, которая ранее была обучена на наборе данных ImageNet.
  2. input_shape: Этот параметр определяет форму входных изображений, в данном случае это 200x200 пикселей с 3 каналами (RGB).
  3. include_top: этот параметр указывает, следует ли включать последний полносвязный уровень классификации модели ResNet50V2. В этом случае мы устанавливаем его на False, так как мы заменим слой классификации нашим собственным пользовательским слоем.
  4. weights: Этот параметр указывает веса, которые будут загружены в модель. В этом случае мы используем веса, предварительно обученные в наборе данных ImageNet.

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

ResNet50V2.trainable = True

for layer in ResNet50V2.layers[:-50]:
    layer.trainable = False

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

  1. ResNet50V2.trainable = True: эта строка кода устанавливает для свойства trainable модели ResNet50V2 значение True, позволяя обновлять веса некоторых слоев во время обучения.
  2. for layer in ResNet50V2.layers[:-50]:: Эта строка кода проходит по всем слоям модели ResNet50V2, кроме последних 50 слоев.
  3. layer.trainable = False: Эта строка кода устанавливает для свойства trainable каждого слоя значение False, эффективно замораживая веса слоев и предотвращая дальнейшее обучение.

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

def Create_ResNet50V2_Model():

    model = Sequential([
                      ResNet50V2,
                      Dropout(.25),
                      BatchNormalization(),
                      Flatten(),
                      Dense(64, activation='relu'),
                      BatchNormalization(),
                      Dropout(.5),
                      Dense(num_classes,activation='softmax')
                    ])
    return model

В этом фрагменте кода мы определяем функцию Create_ResNet50V2_Model(), которая создает архитектуру для модели классификации рака кожи, используя предварительно обученную модель ResNet50V2 в качестве экстрактора признаков.

  1. model = Sequential([...]): Эта строка кода инициализирует последовательную модель, которая представляет собой линейный набор слоев и определяет архитектуру модели классификации рака кожи.
  2. ResNet50V2: это предварительно обученная модель ResNet50V2, которую мы определили ранее, которая используется в качестве экстрактора признаков для модели классификации рака кожи.
  3. Dropout(.25): Этот слой используется для упорядочения модели путем случайного исключения 25% входных единиц во время обучения.
  4. BatchNormalization(): Этот слой нормализует активации предыдущего слоя, что помогает стабилизировать процесс обучения и повысить производительность модели.
  5. Flatten(): Этот слой объединяет выходные данные предыдущего слоя в одномерный вектор, который затем передается в полносвязный слой.
  6. Dense(64, activation='relu'): Этот полностью связанный слой состоит из 64 нейронов с функцией активации ReLU.
  7. BatchNormalization(): Этот слой нормализует активации предыдущего слоя.
  8. Dropout(.5): Этот слой используется для упорядочения модели путем случайного исключения 50% входных единиц во время обучения.
  9. Dense(num_classes,activation='softmax'): Этот полностью связанный слой состоит из num_classes нейронов с функцией активации softmax, которая создает распределение вероятностей по выходным классам.

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

ResNet50V2_Model = Create_ResNet50V2_Model()

ResNet50V2_Model.summary()

ResNet50V2_Model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

В приведенном выше фрагменте кода мы создаем экземпляр модели классификации рака кожи, используя функцию Create_ResNet50V2_Model(), которую мы определили ранее, и компилируем модель для обучения, используя метод compile().

  1. ResNet50V2_Model = Create_ResNet50V2_Model(): Эта строка кода создает экземпляр модели классификации рака кожи с помощью функции Create_ResNet50V2_Model(), которую мы определили ранее. Полученная модель сохраняется в переменной ResNet50V2_Model.
  2. ResNet50V2_Model.summary(): Эта строка кода выводит сводную информацию об архитектуре ResNet50V2_Model.
  3. ResNet50V2_Model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']): Эта строка кода компилирует модель для обучения с использованием метода compile(). Параметр optimizer указывает алгоритм оптимизации, используемый во время обучения, которым в данном случае является оптимизатор Адама. Параметр loss указывает функцию потерь, используемую во время обучения, которая представляет собой категориальную кросс-энтропию. Параметр metrics указывает показатель производительности, используемый для оценки модели во время обучения, то есть точность.

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

Вот что мы получаем после успешной компиляции модели

checkpoint_path = "ResNet50V2"

Checkpoint = ModelCheckpoint(checkpoint_path, monitor="val_accuracy", save_best_only=True)

Early_Stopping = EarlyStopping(monitor = 'val_accuracy', patience = 7, restore_best_weights = True, verbose=1)

Reducing_LR = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss',
                                                  factor=0.2,
                                                  patience=2,
                                                  verbose=1)

callbacks = [Early_Stopping, Reducing_LR]

steps_per_epoch = train_data.n // train_data.batch_size
validation_steps = val_data.n // val_data.batch_size

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

  1. checkpoint_path: эта переменная указывает путь, по которому будут сохраняться лучшие веса модели во время обучения.
  2. Checkpoint: эта функция обратного вызова используется для сохранения лучших весов модели во время обучения на основе точности проверки.
  3. Early_Stopping: эта функция обратного вызова используется для досрочного прекращения обучения модели, если точность проверки не улучшается в течение заданного количества эпох.
  4. Reducing_LR: эта функция обратного вызова используется для снижения скорости обучения оптимизатора, если потери при проверке не улучшаются в течение заданного количества эпох.
  5. callbacks = [Early_Stopping, Reducing_LR]: Эта переменная содержит список функций обратного вызова, которые будут использоваться во время обучения.
  6. steps_per_epoch = train_data.n // train_data.batch_size: эта переменная вычисляет количество шагов за эпоху на основе размера обучающего набора данных и размера пакета.
  7. validation_steps = val_data.n // val_data.batch_size: эта переменная вычисляет количество шагов проверки за эпоху на основе размера набора данных проверки и размера пакета.

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

ResNet50V2_history = ResNet50V2_Model.fit(train_data ,validation_data = val_data , epochs=10, batch_size=batch_size,
                                         callbacks = callbacks, steps_per_epoch=steps_per_epoch, validation_steps=validation_steps)

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

  1. ResNet50V2_Model.fit(): Этот метод обучает модель классификации рака кожи с использованием обучающего набора данных и проверяет ее эффективность на проверочном наборе данных.
  2. train_data: этот параметр указывает набор данных для обучения, который будет использоваться для обучения модели.
  3. validation_data: этот параметр указывает набор данных проверки, который будет использоваться для оценки модели во время обучения.
  4. epochs: этот параметр указывает количество эпох для обучения модели.
  5. batch_size: этот параметр указывает размер пакетов, используемых во время обучения.
  6. callbacks: этот параметр указывает функции обратного вызова, которые следует использовать во время обучения.
  7. steps_per_epoch: этот параметр указывает количество пакетов, которые будут использоваться в эпоху во время обучения.
  8. validation_steps: этот параметр указывает количество пакетов, которые будут использоваться в эпоху во время проверки.

Обучая модель с помощью метода fit(), мы обновляем веса модели на основе градиентов функции потерь по отношению к параметрам модели. Модель обучается в течение определенного количества эпох с использованием обучающего набора данных, а ее производительность оценивается на проверочном наборе данных. Функции обратного вызова используются для мониторинга производительности модели во время обучения и корректировки скорости обучения или досрочного прекращения обучения, если это необходимо.

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

ResNet50V2_Model.save('Skin_Cancer_ResNet50.h5')
model = load_model('Skin_Cancer_ResNet50.h5')

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

  1. ResNet50V2_Model.save('Skin_Cancer_ResNet50.h5'): эта строка кода сохраняет обученную модель классификации рака кожи в файл с именем 'Skin_Cancer_ResNet50.h5' с использованием метода save().
  2. model = load_model('Skin_Cancer_ResNet50.h5'): Эта строка кода загружает сохраненную модель классификации рака кожи из файла 'Skin_Cancer_ResNet50.h5' с помощью функции load_model().
ResNet50V2_Score = model.evaluate(val_data)

print("Val Loss: {:.5f}".format(ResNet50V2_Score[0]))
print("Val Accuracy: {:.2f}%".format(ResNet50V2_Score[1] * 100))

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

  1. ResNet50V2_Score = model.evaluate(val_data): эта строка кода оценивает производительность сохраненной модели классификации рака кожи в наборе данных проверки с использованием метода evaluate().
  2. val_data: этот параметр указывает набор данных проверки, который следует использовать для оценки модели.
  3. print("Val Loss: {:.5f}".format(ResNet50V2_Score[0])): эта строка кода выводит потерю проверки, которая является значением функции потерь в наборе данных проверки.
  4. print("Val Accuracy: {:.2f}%".format(ResNet50V2_Score[1] * 100)): Эта строка кода выводит точность проверки, которая представляет собой процент правильно классифицированных изображений в наборе данных проверки.

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

def plot_curves(history):
    loss = history.history["loss"]
    val_loss = history.history["val_loss"]
    accuracy = history.history["accuracy"]
    val_accuracy = history.history["val_accuracy"]
    epochs = range(len(history.history["loss"]))
    plt.figure(figsize=(15,5))

    plt.subplot(1, 2, 1)
    plt.plot(epochs, loss, label = "training_loss")
    plt.plot(epochs, val_loss, label = "val_loss")
    plt.title("Loss")
    plt.xlabel("epochs")
    plt.legend()

    plt.subplot(1, 2, 2)
    plt.plot(epochs, accuracy, label = "training_accuracy")
    plt.plot(epochs, val_accuracy, label = "val_accuracy")
    plt.title("Accuracy")
    plt.xlabel("epochs")
    plt.legend()
plot_curves(ResNet50V2_history)

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

  1. def plot_curves(history):: Эта строка кода определяет функцию plot_curves, которая принимает объект history в качестве входных данных.
  2. loss = history.history["loss"]: эта строка кода извлекает значения потерь при обучении из объекта history.
  3. val_loss = history.history["val_loss"]: эта строка кода извлекает значения потерь проверки из объекта history.
  4. accuracy = history.history["accuracy"]: эта строка кода извлекает значения точности обучения из объекта history.
  5. val_accuracy = history.history["val_accuracy"]: эта строка кода извлекает значения точности проверки из объекта history.
  6. epochs = range(len(history.history["loss"])): Эта строка кода создает объект диапазона, содержащий количество эпох в истории обучения.
  7. plt.figure(figsize=(15,5)): Эта строка кода создает новую фигуру указанного размера.
  8. plt.subplot(1, 2, 1): Эта строка кода создает новый подграфик для кривых потерь.
  9. plt.plot(epochs, loss, label = "training_loss"): эта строка кода отображает значения потерь при обучении на подграфике.
  10. plt.plot(epochs, val_loss, label = "val_loss"): эта строка кода отображает значения потерь при проверке на подграфике.
  11. plt.title("Loss"): Эта строка кода устанавливает заголовок подзаговора на «Потери».
  12. plt.xlabel("epochs"): Эта строка кода устанавливает метку оси x подграфика на «эпохи».
  13. plt.legend(): Эта строка кода добавляет легенду к сюжету.
  14. plt.subplot(1, 2, 2): Эта строка кода создает новый подграфик для кривых точности.
  15. plt.plot(epochs, accuracy, label = "training_accuracy"): эта строка кода отображает значения точности обучения на подграфике.
  16. plt.plot(epochs, val_accuracy, label = "val_accuracy"): эта строка кода отображает значения точности проверки на подграфике.
  17. plt.title("Accuracy"): Эта строка кода устанавливает заголовок подзаголовка на «Точность».
  18. plt.xlabel("epochs"): Эта строка кода устанавливает метку оси x подграфика на «эпохи».
  19. plt.legend(): Эта строка кода добавляет легенду к сюжету.

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

Ниже приведены выходные графики потерь и точности.

ResNet50V2_Predictions = model.predict(val_data)
ResNet50V2_Predictions = np.argmax(ResNet50V2_Predictions, axis=1)

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

  1. ResNet50V2_Predictions = model.predict(val_data): эта строка кода использует сохраненную модель классификации рака кожи для прогнозирования вероятностей классов изображений в наборе данных проверки с использованием метода predict().
  2. val_data: этот параметр указывает набор данных проверки, используемый для прогнозирования классов изображений.
  3. ResNet50V2_Predictions = np.argmax(ResNet50V2_Predictions, axis=1): Эта строка кода преобразует предсказанные вероятности в предсказанные метки классов, выбирая класс с наибольшей вероятностью для каждого изображения. Это делается с помощью метода argmax() с параметром axis, установленным в 1.
from sklearn.metrics import confusion_matrix
import itertools

def plot_confusion_matrix(cm, classes, title='Confusion matrix', cmap=plt.cm.Blues):
    cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
    plt.figure(figsize=(10,10))
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    fmt = '.2f'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.tight_layout()
    
cnf_matrix = confusion_matrix(val_data.labels, ResNet50V2_Predictions)
np.set_printoptions(precision=2)

plt.figure()
plot_confusion_matrix(cnf_matrix, classes=val_data.class_indices.keys(), title='Normalized confusion matrix')
plt.show()

В приведенном выше фрагменте кода мы определяем функцию plot_confusion_matrix, которую можно использовать для построения матрицы путаницы модели классификации рака кожи.

  1. from sklearn.metrics import confusion_matrix: эта строка кода импортирует функцию confusion_matrix из модуля sklearn.metrics.
  2. import itertools: эта строка кода импортирует модуль itertools.
  3. def plot_confusion_matrix(cm, classes, title='Confusion matrix', cmap=plt.cm.Blues):: Эта строка кода определяет функцию с именем plot_confusion_matrix, которая принимает в качестве входных данных матрицу путаницы, метки классов, заголовок графика и цветовую карту.
  4. cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]: Эта строка кода нормализует матрицу путаницы путем деления каждой строки на ее сумму.
  5. plt.figure(figsize=(10,10)): Эта строка кода создает новую фигуру указанного размера.
  6. plt.imshow(cm, interpolation='nearest', cmap=cmap): Эта строка кода отображает матрицу путаницы в виде изображения с использованием указанной палитры.
  7. plt.title(title): Эта строка кода устанавливает заголовок графика на указанный заголовок.
  8. plt.colorbar(): Эта строка кода добавляет на график цветную полосу.
  9. tick_marks = np.arange(len(classes)): Эта строка кода создает массив делений для осей x и y.
  10. plt.xticks(tick_marks, classes, rotation=45): Эта строка кода устанавливает деления и метки для оси X.
  11. plt.yticks(tick_marks, classes): Эта строка кода устанавливает деления и метки для оси Y.
  12. fmt = '.2f': Эта строка кода определяет формат текста в матрице путаницы.
  13. thresh = cm.max() / 2.: Эта строка кода устанавливает пороговое значение цвета текста в матрице путаницы.
  14. for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):: Эта строка кода перебирает строки и столбцы матрицы путаницы.
  15. plt.text(j, i, format(cm[i, j], fmt), horizontalalignment="center", color="white" if cm[i, j] > thresh else "black"): Эта строка кода добавляет текст в матрицу путаницы, указывающую процент истинно положительных, ложноположительных, истинно отрицательных и ложноотрицательных результатов.
  16. plt.ylabel('True label'): Эта строка кода устанавливает метку для оси Y.
  17. plt.xlabel('Predicted label'): Эта строка кода устанавливает метку для оси X.
  18. plt.tight_layout(): Эта строка кода корректирует макет графика, чтобы предотвратить перекрытие.
  19. cnf_matrix = confusion_matrix(val_data.labels, ResNet50V2_Predictions): Эта строка кода вычисляет матрицу путаницы, используя истинные метки и предсказанные метки.
  20. np.set_printoptions(precision=2): Эта строка кода устанавливает количество знаков после запятой равным 2 для текста в матрице путаницы.
  21. plot_confusion_matrix(cnf_matrix, classes=val_data.class_indices.keys(), title='Normalized confusion matrix'): Эта строка кода вызывает функцию plot_confusion_matrix для построения матрицы путаницы.

Матрица путаницы выглядит примерно так:

rootdir = 'dataset/Train/'
Classes=[]
for file in os.listdir(rootdir):
    d = os.path.join(rootdir, file)
    if os.path.isdir(d):
        Classes.append(file)
Classes

В этом фрагменте кода мы просто итерируем внутри каталога Train и помещаем все имена каталогов (классов) в список, который позже будет использоваться для прогнозирования выходной метки.

Вот как выглядит список классов в нашем наборе данных

def load_and_prep_image(filename, img_shape_x=200, img_shape_y=200):
    img = cv2.imread(filename)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = cv2.resize(img, (img_shape_x, img_shape_y))
    img = preprocess_input(img)
    return img

Здесь мы определяем функцию с именем load_and_prep_image, которую можно использовать для загрузки и предварительной обработки изображения для прогнозирования с помощью модели классификации рака кожи.

  1. filename: этот параметр указывает путь к файлу изображения для загрузки.
  2. img_shape_x=200, img_shape_y=200: Эти параметры определяют форму изображения после изменения размера.
  3. img = cv2.imread(filename): эта строка кода считывает файл изображения с помощью функции OpenCV imread() и присваивает его переменной img.
  4. img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB): Эта строка кода преобразует цветовое пространство изображения из BGR в RGB с помощью функции OpenCV cvtColor().
  5. img = cv2.resize(img, (img_shape_x, img_shape_y)): эта строка кода изменяет размер изображения до указанной формы с помощью функции OpenCV resize().
  6. img = preprocess_input(img): эта строка кода выполняет предварительную обработку изображения с помощью функции preprocess_input() из модели ResNet50V2. Это включает в себя масштабирование значений пикселей от -1 до 1 и вычитание среднего значения пикселя набора данных ImageNet из каждого пикселя.

Функция load_and_prep_image() позволяет нам предварительно обрабатывать изображение так же, как изображения в наборах данных для обучения и проверки, чтобы мы могли использовать модель классификации рака кожи для прогнозирования класса изображения.

def pred_and_plot(filename, model, class_names, img_shape_x=200, img_shape_y=200):
    img = load_and_prep_image(filename, img_shape_x, img_shape_y)
    image = io.imread(filename)
    gray_image = np.mean(image, axis=2)
    plt.imshow(gray_image, cmap='hot')
    plt.colorbar()
    plt.show()
    pred = model.predict(np.expand_dims(img, axis=0))
    pred_class = class_names[pred.argmax()]
    img = cv2.cvtColor(cv2.imread(filename), cv2.COLOR_BGR2RGB)
    plt.imshow(img)
    plt.title(f"Prediction: {pred_class}")
    plt.axis(False)
    plt.show()

В приведенном выше коде мы определяем функцию с именем pred_and_plot, которую можно использовать для загрузки файла изображения, его предварительной обработки и использования модели классификации рака кожи для прогнозирования его класса. Затем функция отображает изображение вместе с предсказанным классом.

  1. filename: этот параметр указывает путь к файлу изображения для загрузки.
  2. model: Этот параметр указывает модель классификации рака кожи, используемую для прогнозирования.
  3. class_names: этот параметр указывает список имен классов, соответствующих выходным данным модели.
  4. img_shape_x=200, img_shape_y=200: Эти параметры определяют форму изображения после изменения размера.
  5. img = load_and_prep_image(filename, img_shape_x, img_shape_y): Эта строка кода вызывает функцию load_and_prep_image() для предварительной обработки изображения.
  6. image = io.imread(filename): Эта строка кода считывает файл изображения с помощью функции skimage io.imread() и присваивает его переменной image.
  7. gray_image = np.mean(image, axis=2): Эта строка кода преобразует изображение в оттенки серого, взяв среднее значение каналов RGB по третьей оси.
  8. plt.imshow(gray_image, cmap='hot'): Эта строка кода отображает изображение в градациях серого с использованием карты цветов.
  9. pred = model.predict(np.expand_dims(img, axis=0)): Эта строка кода использует модель классификации рака кожи для прогнозирования класса изображения.
  10. pred_class = class_names[pred.argmax()]: Эта строка кода определяет прогнозируемое имя класса на основе выходных данных модели.
  11. img = cv2.cvtColor(cv2.imread(filename), cv2.COLOR_BGR2RGB): Эта строка кода считывает файл изображения с помощью функции OpenCV imread() и преобразует цветовое пространство изображения из BGR в RGB.
  12. plt.imshow(img): Эта строка кода отображает исходное цветное изображение.
  13. plt.title(f"Prediction: {pred_class}"): Эта строка кода устанавливает заголовок графика, чтобы включить предсказанное имя класса.
  14. plt.axis(False): Эта строка кода удаляет метки осей с графика.

Функция pred_and_plot() позволяет нам загружать файл изображения, предварительно обрабатывать его и использовать модель классификации рака кожи для прогнозирования его класса, при этом отображая исходное изображение вместе с тепловой картой и предсказанным именем класса.

pred_and_plot("testset/pigmented.jpg",model, Classes, 200, 200)

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

  1. "testset/pigmented.jpg": этот параметр указывает путь к файлу изображения для загрузки.
  2. model: Этот параметр указывает модель классификации рака кожи, которую следует использовать для прогнозирования.
  3. Classes: этот параметр указывает список имен классов, соответствующих выходным данным модели.
  4. 200, 200: Эти параметры определяют форму изображения после изменения размера.

Реализация графического интерфейса

Мы взяли приведенные выше фрагменты кода и разделили их на две части. Один для окна обучения, другой для окна тестирования. Мы реализовали оба из них, используя модуль Python Tkinter GUI и внеся небольшие изменения в необработанный код, чтобы заставить его взаимодействовать с пользовательским вводом.

После реализации кодов в графическом интерфейсе окна выглядят примерно так:

Ниже приведен код для реализации показанного выше графического интерфейса:

Внедрение с использованием наборов инструментов Intel oneAPI AI Analytics

Почему наборы инструментов AI Analytics на основе Intel oneAPI?

Ниже я покажу вам несколько четких различий между обычным обучением и обучением с использованием наборов инструментов AI Analytics на основе Intel oneAPI.

Время обучения

Время обучения, затраченное на обучение модели в течение 10 эпох с помощью оптимизированного Intel python и оптимизированного Intel tensorflow, составило 1028 секунд.

Время обучения, необходимое для обучения модели в течение 10 эпох без использования оптимизированного Intel Python и оптимизированного Intel TensorFlow, составило 1160 секунд.

Точность поезда

Наивысшая точность, достигнутая после обучения модели в течение 10 эпох с использованием наборов инструментов AI Analytics на базе Intel oneAPI, составила 46,88 %.

Но самая высокая точность, достигнутая после обучения модели в течение 10 эпох без использования наборов инструментов AI Analytics на базе Intel oneAPI, составила 45,31%.

Точность теста

Когда мы использовали наборы инструментов AI Analytics на основе Intel oneAPI для обучения модели, мы получили 5 из 9 правильных прогнозов на наших тестовых изображениях всего за 10 эпох.

В приведенном ниже представлении первые пять изображений являются правильными предсказаниями, а последние 4 — неверными.

Но когда мы не использовали наборы инструментов AI Analytics на основе Intel oneAPI для обучения модели, мы получили 2/9 правильных прогнозов на наших тестовых изображениях всего за 10 эпох.

В приведенном ниже представлении только класс «меланома» (4-е изображение) и «невус» (6-е изображение) являются правильными предсказаниями, а остальные неверны.

GitHub-репозиторий проекта



Видеообъяснение внедрения оптимизированных Intel наборов инструментов искусственного интеллекта и тестирования модели

Заключение

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