Введение

Это проект бинарной классификации для классификации диабетической ретинопатии на одну или пять категорий. Этот проект основан на реальных данных изображений. В моем случае я пробую бинарную классификацию. Меня только что классифицировали (DR vs No_DR (Легкая, Средняя, ​​Тяжелая и Пролиферативная)).

В этой статье я интегрировал классификацию диабетической ретинопатии в WebApp (Gradio).

Понимание решения для глубокого обучения

Постановка проблемы:

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

Таким образом, потребность во всестороннем и автоматизированном методе скрининга DR давно признана, и предыдущие усилия достигли значительного прогресса с использованием классификации изображений и распознавания образов с использованием AI (DL, ML) и с цветной фотографией глазного дна в качестве входных данных. с реальным клиническим потенциалом.

Предпосылки:

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

- Требуется понимание алгоритма глубокого обучения CNN

- Требуется знание программирования Python и фреймворков Python, таких как pandas, Numpy, Tensorflow и OpenCV, а также базовые знания Gradio.

Описание набора данных:

Изображения состоят из изображений сканирования сетчатки, отфильтрованных по Гауссу, для выявления диабетической ретинопатии. Исходный набор данных доступен на APTOS 2019 Blindness Detection. Эти изображения изменены на 224x224 пикселя, чтобы их можно было легко использовать со многими предварительно обученными моделями глубокого обучения.

Все изображения уже сохранены в соответствующих папках в зависимости от тяжести/стадии диабетической ретинопатии с использованием предоставленного файла train.csv. Вы найдете пять каталогов с соответствующими изображениями: Без_DR, Мягкая, Умеренная, Серьезная, Пролиферация_DR.

Я пробовал бинарную классификацию (DR против No_DR (легкая, умеренная, тяжелая и размножающаяся)).

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

Предпочтительная среда разработки: Spyder, VSCode, PyCharm.

Анализ и предварительная обработка набора данных в решении для глубокого обучения

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

Ссылка на набор данных — Нажмите здесь

Этап 1: предварительная обработка данных, разделение Train_test, генератор данных изображения

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
import pandas as pd
import random,os
import shutil
import matplotlib.pyplot as plt
from matplotlib.image import imread
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.metrics import categorical_accuracy
from sklearn.model_selection import train_test_split

Я уже говорил об этой двоичной проблеме, поэтому я меняю набор данных (Нет DR против DR (объединение всего в одной функции — легкая, умеренная, серьезная и распространение))

#Generate new feature
def Generate_new_feature_in_csv(input=None) -> None:
'''Generate new feature, Mapping the output feature'''
    if input == None:
        input = r'/home/vk/Desktop/Retina_Webapp/archive/train.csv'
    data = pd.read_csv(input)
    Defect_binary = {
                     0:'No_DR',
                     1: 'DR',
                     2: 'DR',
                     3: 'DR',
                     4: 'DR'}
    diagnosis_all_dict = {0:'No_DR',1: 'Mild',2: 'Moderate',3: 'Severe',4: 'Proliferate_DR',}
    data['binary_type'] = data['diagnosis'].map(Defect_binary.get)
    data['type'] = data['diagnosis'].map(diagnosis_all_dict.get)
    return data
Generate_new_feature_in_csv()

#Visualize
def data_binary_type_EDA() -> None:
"""Only analysis the Data in retina diabetic binary type identification"""
    data = Generate_new_feature_in_csv()
    print("Describe the data:",data.describe)
    data['binary_type'].value_counts().plot(kind='bar')
data_binary_type_EDA()

Теперь процесс разделения данных и создание подкаталогов Train, Test и Validate являются DR и No_DR. Затем скопируйте соответствующие изображения в папку.

# Data Separation
def data_separation()-> None:
    '''Train_Test_Separation'''
    data = Generate_new_feature_in_csv()
    train,val = train_test_split(data,test_size=0.2,stratify = data['type'])
    train,test = train_test_split(train,test_size = 0.15/(1-0.15), stratify=train['type'])
    return train,val,test

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

#Create working directory
def mkdir_separate_image() -> None:
'''
1. Initiate the data
2. Create Train,Test,val directory
3. Separate train,test,val copy the images 
'''
    train,val,test = data_separation()
    base_dir = ''
    train_dir = os.path.join(base_dir, 'train')
    val_dir = os.path.join(base_dir, 'val')
    test_dir = os.path.join(base_dir, 'test')
    if os.path.exists(base_dir):
        shutil.rmtree(base_dir)
    if os.path.exists(train_dir):
        shutil.rmtree(train_dir)
    os.makedirs(train_dir)
    if os.path.exists(val_dir):
        shutil.rmtree(val_dir)
    os.makedirs(val_dir)'
    if os.path.exists(test_dir):
        shutil.rmtree(test_dir)
    os.makedirs(test_dir)
    #Copy images to respective working train,test,val directory
    src_dir = r'/home/vk/Desktop/Retina_Webapp/archive/gaussian_filtered_images/gaussian_filtered_images'
    for index,row in train.iterrows():
        diagnosis = row['type']
        binary_diagnosis = row['binary_type']
        id_code = row['id_code'] + ".png"
        srcfile = os.path.join(src_dir, diagnosis, id_code)
        dstfile = os.path.join(train_dir,binary_diagnosis)
        os.makedirs(dstfile, exist_ok=True)
        shutil.copy(srcfile,dstfile)
    for index,row in test.iterrows():
        diagnosis = row['type']
        binary_diagnosis = row['binary_type']
        id_code = row['id_code'] + ".png"
        srcfile = os.path.join(src_dir, diagnosis, id_code)
        dstfile = os.path.join(test_dir,binary_diagnosis)
        os.makedirs(dstfile, exist_ok=True)
        shutil.copy(srcfile,dstfile)
    for index,row in val.iterrows():
        diagnosis = row['type']
        binary_diagnosis = row['binary_type']
        id_code = row['id_code'] + ".png"
        srcfile = os.path.join(src_dir, diagnosis, id_code)
        dstfile = os.path.join(val_dir,binary_diagnosis)
        os.makedirs(dstfile, exist_ok=True)
        shutil.copy(srcfile,dstfile)
    return train,val,test

Генератор данных изображения:

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

def ImageDataGenerator_Data():
    train,val,test = mkdir_separate_image()
    train_path = 'train'
    val_path = 'val'
    test_path = 'test'
    train_batches = ImageDataGenerator(rescale=1/255.).flow_from_directory(train_path, target_size=(224,224), shuffle=True)
    val_batches = ImageDataGenerator(rescale=1/255.).flow_from_directory(val_path, target_size=(224,224), shuffle=True)
    test_batches = ImageDataGenerator(rescale=1/255.).flow_from_directory(test_path,target_size=(224,224), shuffle=True)
    return train_batches,val_batches,test_batches
ImageDataGenerator_Data()

Этап 2: создание и обучение моделированию глубокого обучения

Теперь давайте разработаем модель глубокого обучения классификации с использованием алгоритма нейронной сети Convolution. Мы импортируем структуру тензорного потока для разработки модели DL и сохранения весов модели.

Теперь кратко обсудим CNN с использованием проблемы классификации изображений.

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

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

Архитектура:

#Build and Train the model
def Model() -> None:
'''Building CNN model + Compile + EarlyStopping + Fit '''
    model = tf.keras.Sequential([
    layers.Conv2D(8, (3,3), padding="valid", input_shape=(224,224,3), activation='relu'),
    layers.MaxPooling2D(pool_size=(2,2)),
    layers.BatchNormalization(),
    layers.Conv2D(16,(3,3), padding="valid",activation='relu'),
    layers.MaxPooling2D(pool_size=(2,2)),
    layers.BatchNormalization(),
    layers.Conv2D(32,(4,4),padding="valid",activation='relu'),
    layers.MaxPooling2D(pool_size = (2,2)),
    layers.BatchNormalization(),
    layers.Flatten(),
    layers.Dense(32,activation='relu'),
    layers.Dropout(0.15),
    layers.Dense(2,activation='softmax')
    ])
    #Compile
    model.compile(optimizer = tf.keras.optimizers.Adam(lr=1e-5),
    loss = tf.keras.losses.BinaryCrossentropy(),metrics=['acc'])
    #Earlystopping
    es = tf.keras.callbacks.EarlyStopping(monitor='val_loss',min_delta=0,patience=5,verbose=0,mode='auto',)
    es1 = keras.callbacks.ModelCheckpoint(r'/home/vk/Desktop/Retina_Webapp/models_30epoch/model{epoch:08d}-{acc}.h5', period=1)
    
    #call the imagedatagenerator function
    train_batches,val_batches,test_batches = ImageDataGenerator_Data()
    history = model.fit(train_batches, epochs=2, validation_data=val_batches,callbacks=[es,es1])
    #accuracy
    loss,acc = model.evaluate_generator(test_batches,verbose=1)
    print("Accuracy:", acc)
    print("Loss:",loss)
    return loss,acc,model

Мы видим, что точность модели составляет 90%. Наша модель, похоже, хорошо работает на тестовых данных, и мы готовы развернуть модель в веб-приложении Gradio, чтобы сделать ее доступной для конечных пользователей.

Развертывание модели в веб-приложении Gradio

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

Gradio — это самый быстрый способ продемонстрировать модель глубокого обучения с помощью удобного веб-интерфейса.

Установка Gradio:pip install gradio

#web app implementation

import gradio as gr
import cv2
import tensorflow as tf
#predict function
def predict(img):
    model = tf.keras.models.load_model(r"/home/vk/Desktop/Retinopathy_Detection_Webapp/End2End_CNNModel_api_webapp/models_30epoch/model00000002-0.9054726362228394.h5") 
    Retina_classes = ['DR', 'No_DR']
    img_resize=img.reshape(-1,224,224,3)
    prediction=model.predict(img_resize)[0]
    return {Retina_classes[i]: float(prediction[i]) for i in range(2)}
#Just four line implementation
image = gr.inputs.Image(shape=(224,224))
label = gr.outputs.Label(num_top_classes=2)
gr.Interface(fn=predict_input_image, inputs=image, outputs=label,interpretation='default').launch(debug='True')

Вывод веб-просмотра:

Вот и все. Просто отправьте файлы проекта в репозиторий GitHub и разработайте классификацию изображений с помощью веб-приложения с помощью gradio.

Вы можете получить доступ к репозиторию проекта здесь

Заключение

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

1. Для выполнения предварительной обработки данных, особенно для разделения данных (DR против No_DR (Легкая, Средняя, ​​Серьезная и Распространенная)).

2. Разработайте модель CNN

3. Разработайте конвейер глубокого обучения и разверните его в Gradio (веб-приложение).

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

Спасибо, что заглянули, ребята!Если у вас есть какие-либо вопросы и ошибки в этой статье, прокомментируйте ее! или давайте подключим linkedin, kaggle обсуждение.

Полный кредит:

  1. https://www.kaggle.com/datasets/sovitrath/диабетическая-ретинопатия-224x224-gaussian-filtered
  2. https://www.kaggle.com/code/parisanahmadi/dl-diabetic-retinopathycdetection-95-acc-cnn
  3. Мой демонстрационный проект: https://github.com/VK-Ant/Diabetic-Retinopathy-Detection_WebApp/tree/master/End2End_CNNModel_api_webapp

Социальные сети: linkedin, Kaggle, Github