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



Я использовал экземпляр процессора Paperspace 12 VP. Нам нужно установить несколько пакетов Linux, таких как Werkzeug, Flask, numpy, Keras, gevent, Pillow, h5py и tensorflow.

Начнем непосредственно с тренировки

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import keras
from tqdm import tqdm
import os
from sklearn.model_selection import train_test_split
from cv2 import cv2
from PIL import Image
import tensorflow as tf
from matplotlib import pyplot as plt
from keras.layers import Dense, Dropout, Flatten, Input 
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
from keras.preprocessing import image
from keras.utils import plot_model
from keras.models import Model
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
from numpy import array

Я уже скачал набор данных с Kaggle. (После того, как вы загрузите набор данных, вам нужно разархивировать все обучающие и тестовые файлы, вам необходимо объединить все файлы поездов, чтобы создать простую папку для изображений поездов)
Ниже я загружаю CSV-файл, содержащий обучающие метки

df_train = pd.read_csv('/storage/trainLabels.csv')

Давайте посмотрим на все метки.
'10_left' - имя файла, а '0/1/2/3/4' - метки.
Изображение левого глаза '10_left' аналогично изображение правого глаза "10_right" для того же человека

df_train.values

array ([['10_left', 0],
['10_right', 0],
['13_left', 0],
...,
['44348_right', 0],
['44349_left', 0],
['44349_right', 1]], dtype = object)

В обучающем наборе 35125 изображений, «уровень» - это столбец, указывающий метки для соответствующих изображений.

df_train.tail()

Мы будем использовать Pandas для преобразования df_train в серию и get_dummies для выполнения одной горячей кодировки (FYI, я не использую одну горячую кодировку во время обучения на данный момент)

targets_series = pd.Series(df_train['level'])
one_hot = pd.get_dummies(targets_series, sparse = True)

Как я уже говорил ранее, существует 5 типов меток 0/1/2/3/4, они различаются следующим образом (NDPR - непролиферативная диабетическая ретинопатия).

Класс - Название
0 - Нормальный
1 - Легкий NPDR
2 - Средний NPDR
3 - Серьезный NPDR
4 - PDR

targets_series[:10]

one_hot[:10]

Давайте посмотрим на массив, содержащий только метки

one_hot_labels = np.asarray(one_hot)
one_hot_labelsY = np.asarray(targets_series)
one_hot_labelsY[:10]

array ([0, 0, 0, 0, 1, 2, 4, 4, 0, 1])

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

im_size1 = 786
im_size2 = 786
x_train = []
y_train = []

Если вам интересно проверить все имена изображений

i = 0 
for f, breed in tqdm(df_train.values):
    print(f)

10_левое
10_право
13_левое
13_право
15_левое
15_право
16_лево
16_право
17_лево
17_право < br /> 19_влево

Я создаю подмножество из 1000 изображений из 35125 изображений.

df_test = df_train[:1000]

Если вы планируете запускать этот код для всех 35125 изображений, замените df_test на df_train. Приведенный ниже фрагмент кода загрузит все изображения и метки в массив numpy.
Вы также можете загружать изображения с помощью OpenCV, я упомянул код OpenCV в комментариях ниже

”””
#this is a OpenCV implementation
i = 0 
for f, breed in tqdm(df_train.values):
    if type(cv2.imread('/storage/train/{}.jpeg'.format(f)))==type(None):
        continue
    else:
        img = cv2.imread('/storage/train/{}.jpeg'.format(f))
        label = one_hot_labels[i]
        x_train.append(cv2.resize(img, (im_size1, im_size2)))
        y_train.append(label)
        i += 1
np.save('x_train2',x_train)
np.save('y_train2',y_train)
print('Done')
"""
i=0
for f, breed in tqdm(df_test.values):
    try:
        img = image.load_img(('/storage/train/{}.jpeg'.format(f)), target_size=(786, 786))
        arr = image.img_to_array(img)
        label = one_hot_labelsY[i]
        x_train.append(arr)
        y_train.append(label)
        i += 1 
    except:
        pass

100%|██████████| 1000/1000 [01:43<00:00, 7.06it/s]

Давайте просто проверим одно из изображений из массива numpy

plt.imshow(x_train[681]/255) #681 > Try some other number too 
plt.show()

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

x_valid = []
y_valid = []
X_train, X_valid, Y_train, Y_valid = train_test_split(x_train, y_train, test_size=0.1, random_state=1)

Теперь мы определим модель. ››
Модель имеет 2 сверточных лейера, 2 максимальных слоя объединения, слой выравнивания изображения и слой плотности. Модели в Keras / TF бывают двух форм - последовательные (model = Sequential ()) или использующие функциональный API.
Ниже код использует функциональный API, который обычно используется для сложных моделей, я оставлю облегченный вариант Sequential () модель в комментариях. Вы можете изменить слои, чтобы создать свою собственную модель.

visible = Input(shape=(786,786,3))
conv1 = Conv2D(32, kernel_size=4, activation='relu')(visible)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
conv2 = Conv2D(16, kernel_size=4, activation='relu')(pool1)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
flat = Flatten()(pool2)
hidden1 = Dense(10, activation='relu')(flat)
output = Dense(1, activation='sigmoid')(hidden1)
model = Model(inputs=visible, outputs=output)

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

model = keras.Sequential ([
keras.layers.Flatten (input_shape = (786, 786, 3)),
keras.layers.Dense (128, activate = tf.nn.relu), < br /> keras.layers.Dense (10, активация = tf.nn.softmax)
])

Доступно множество оптимизаторов. ›› https://keras.io/optimizers/
Подробнее о функциях потерь ›› https://keras.io/losses/
Показатели ›› https://keras.io/metrics/

Не стесняйтесь экспериментировать с этими показателями.

model.compile(optimizer='adam', 
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

Давайте преобразуем массив в массив numpy, это может занять некоторое время.

y_train_raw = np.array(Y_train)
x_train_raw = np.array(X_train)

Вот как слои накладываются друг на друга

model.summary()

Эта команда фактически обучит модель. Даже с меньшим количеством изображений вы можете столкнуться с «ошибкой недостаточного объема памяти» или «ошибкой перезапуска ядра».

model.fit(x_train_raw, y_train_raw, epochs=5)

Давайте преобразуем массив в массив numpy для проверки набора данных

x_valid_raw = np.array(X_valid)
y_valid_raw = np.array(Y_valid)

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

test_loss, test_acc = model.evaluate(x_valid_raw, y_valid_raw)
test_loss
test_acc

Вы можете найти книгу узлов iPython по адресу https://github.com/swanandM/Diabetic-Retinopathy-Detection-with-TF.git

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