Целью этого руководства является разработка автоматизированной системы обнаружения диабетической ретинопатии с использованием 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
Вы можете изменить этот код, чтобы реализовать несколько вещей, таких как увеличение данных, пакетная нормализация, выпадение и настраиваемые функции потери для повышения производительности.