Недавно я играл с Keras и Tensorflow для решения проблемы классификации. Я не могу раскрыть всю задачу классификации, но при использовании keras я обнаружил несколько тонкостей, которыми я хотел бы поделиться в этом сообщении в блоге. Я бы попытался рассказать, как можно достичь производительности при обучении на платформе с несколькими графическими процессорами с использованием keras, и рассказать о некоторых типичных ошибках, которые может сделать новичок (как это сделал я).

Предпосылки: основы CNN, создание простой модели CNN.

Keras предоставляет простую структуру для использования нескольких графических процессоров. Пример ванильного кода для того же самого приведен ниже:

Давайте создадим базовую модель CNN, которая классифицирует изображения по 10 классам.

Импортируйте необходимые библиотеки

При импорте моделей я использовал keras.layers для импорта пакетной нормализации, если вы используете тензорный поток, тогда используйте from tensorflow.layers import BatchNormalization. Для использования мощности нескольких графических процессоров с помощью keras я импортирую библиотеку multi_gpu_model.

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

Создание базового классификатора изображений

Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 99, 99, 20)        260       
_________________________________________________________________
batch_normalization_2 (Batch (None, 99, 99, 20)        80        
_________________________________________________________________
activation_1 (Activation)    (None, 99, 99, 20)        0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 49, 49, 20)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 48, 48, 64)        5184      
_________________________________________________________________
activation_2 (Activation)    (None, 48, 48, 64)        0         
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 24, 24, 64)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 23, 23, 64)        16448     
_________________________________________________________________
activation_3 (Activation)    (None, 23, 23, 64)        0         
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 11, 11, 64)        0         
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 10, 10, 64)        16448     
_________________________________________________________________
activation_4 (Activation)    (None, 10, 10, 64)        0         
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 4, 4, 64)          16448     
_________________________________________________________________
activation_5 (Activation)    (None, 4, 4, 64)          0         
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 2, 2, 64)          0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 256)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 100)               25700     
_________________________________________________________________
dense_2 (Dense)              (None, 16)                1616      
_________________________________________________________________
activation_6 (Activation)    (None, 16)                0         
=================================================================
Total params: 82,184
Trainable params: 82,144
Non-trainable params: 40

Создание параллельной модели

Я определил num_gpu как 1, num_epochs как 100 и batch_size как 30.

Стоит отметить, что эта сеть небольшая и с меньшими параметрами. С настройкой CPU эта нейронная сеть занимает ~ 2600 секунд, а при вычислениях на GPU эта же сеть обучается за ~ 196 секунд. Обучение базовых сетей с использованием нескольких графических процессоров может усложнить задачу и занять больше времени. Несколько графических процессоров эффективны только тогда, когда накладные расходы одного графического процессора насыщены.

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

Класс Imagedatagenerator из keras.preprocessing.image генерирует изображения в пакетах (расширенных и не расширенных) на основе предоставленных массивов изображений. Если распределения классов четные, то сгенерированные пакеты изображений также будут иметь одинаковое распределение классов. Однако, если имеется дисбаланс высокого класса, тогда сгенерированный пакет изображений может не подчиняться подобному распределению. Что ж, это может быть частью расследования и стать моей следующей статьей Medium. Хотя для более полного изучения класса Imagedatagenerator я рекомендую вам прочитать ссылки это и это.

Создание генератора изображений для обучающих и проверочных данных

train_img_generator будет генерировать нормализованные масштабированные изображения с некоторым случайным поворотом от 0 до 100 градусов. Пользователь может указать различные другие параметры, такие как zoom_range, shift, zca_whitening, яркость_range и т. Д. Подробности находятся по этой ссылке. Для проверки мы генерируем только нормализованные масштабированные изображения.

Использование расширенных данных для обучения

Создание параллельной модели с использованием дополненных данных

Train_generator [0] [0] принимает массивы изображений, а train_generator [0] [1] принимает соответствующие метки классов. Ввод данных напрямую как train_generator вызовет ошибку, поскольку пакеты формируются в виде кортежей. train_generator [0] [0] и train_generator [0] [1] извлекали массивы numpy из этих кортежей и служили модели как X_train и y_train. Для каждой эпохи train_generator генерирует 2000 расширенных массивов изображений, а val_generator генерирует 50 массивов изображений. Для каждой эпохи сеть учится на разном стиле изображения, и, следовательно, это ведет к надежному обучению. Графики производительности для них можно извлечь, используя ниже:

Если вам понравился этот кусок, пожалуйста, поставьте лайк, поделитесь и внедрите.!