Классификация крупномасштабных изображений с Keras - тонкая настройка vgg16 -

Последнее обновление: 04.06.2018
Python
Mашинное обучение

1. Введение

Недавно я начал изучать машинное обучение и участвовал в Kaggle , конкурсе по классификации изображений. На этот раз я подведу итог, как реализовать тонкую настройку vgg16 с библиотекой python keras 2.

2 О данных

Набор данных выглядит следующим образом. У меня был только такой набор данных, как MNIST который часто видели в обучающих материалах по ML, поэтому я чувствовал, что это очень большой набор данных.

  • Классы: около 15 000
  • Размер данных обучения: около 1,2 миллиона файлов изображений. Более 300ГБ
  • Размер каждого файла изображения: варьируется между файлами. например 1600 \ 1200 *
  • Тестовые данные: около 120000 файлов

3 Реализация

3.1 Изучить данные

Сначала я покажу вам весь код.

train.py
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.applications.vgg16 import VGG16
from keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization
from keras.models import Model, Sequential
from keras.callbacks import ModelCheckpoint
import numpy as np

train_data_dir = "/train/"
validation_data_dir = "/validation/"

train_datagen = ImageDataGenerator(rescale=1. / 255)
validation_datagen = ImageDataGenerator(rescale=1. / 255)

img_width, img_height = 200, 150
nb_train_samples = 915649
nb_validation_samples = 302091
epochs = 50
batch_size = 64
nb_category = 14951

train_generator = train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode="categorical")

validation_generator = validation_datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode="categorical")

# define input_tensor
input_tensor = Input(shape=(img_width, img_height, 3))

vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)

top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
top_model.add(Dense(256, activation='relu', kernel_initializer='he_normal'))
top_model.add(BatchNormalization())
top_model.add(Dropout(0.5))
top_model.add(Dense(nb_category, activation='softmax'))

# Connect vgg16 and top_model
model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))

# Fix layers
for layer in model.layers[:15]:
    layer.trainable = False

optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)
model.compile(loss='categorical_crossentropy',
              optimizer=optimizer,
              metrics=['accuracy'])

checkpoint_cb = ModelCheckpoint("snapshot/{epoch:03d}-{val_acc:.5f}.hdf5", save_best_only=True)

model.fit_generator(
        train_generator,
        steps_per_epoch=nb_train_samples // batch_size,
        epochs=epochs,
        validation_data=validation_generator,
        validation_steps=nb_validation_samples // batch_size,
        callbacks=[checkpoint_cb])

# Save the model
model.save("model.h5")

model.summary()

3.1.1 Учитесь с крупномасштабными данными

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

how_to_load_data
(X_train, y_train), (X_test, y_test) = mnist.load_data()

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

Сначала вам нужно создать ImageDataGenerator .

Create_ImageDataGenerator
train_datagen = ImageDataGenerator(rescale=1. / 255)
validation_datagen = ImageDataGenerator(rescale=1. / 255)

Этот класс выполняет пакетную генерацию данных изображения при выполнении предварительной обработки. На этот раз просто измените масштаб. 1/255 используется для нормализации диапазона значений RGB от 0-255 до 0-1.

Далее читаем данные

Read_data
train_generator = train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode="categorical")

validation_generator = validation_datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode="categorical")

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

Folder_structure
data/
     train/
           classA/
                 aaa.jpg
                 bbb.jpg
                 ...
           classB/
                 ccc.jpg
                 ddd.jpg
                 ...

     validation/
           classA/
                 eee.jpg
                 fff.jpg
                 ...
           classB/
                 ggg.jpg
                 hhh.jpg
                 ...

3.1.2 Использование модели vgg16

Научитесь использовать модель VGG16, которую можно использовать с Keras .

fine-tune_vgg16_model
# define input_tensor
input_tensor = Input(shape=(img_width, img_height, 3))

vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)

top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
top_model.add(Dense(256, activation='relu', kernel_initializer='he_normal'))
top_model.add(BatchNormalization())
top_model.add(Dropout(0.5))
top_model.add(Dense(nb_category, activation='softmax'))

# Connect vgg16 with top_model
model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))

# Fix layers
for layer in model.layers[:15]:
    layer.trainable = False

optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)
model.compile(loss='categorical_crossentropy',
              optimizer=optimizer,
              metrics=['accuracy'])

checkpoint_cb = ModelCheckpoint("snapshot/{epoch:03d}-{val_acc:.5f}.hdf5", save_best_only=True)

model.fit_generator(
        train_generator,
        steps_per_epoch=nb_train_samples // batch_size,
        epochs=epochs,
        validation_data=validation_generator,
        validation_steps=nb_validation_samples // batch_size,
        callbacks=[checkpoint_cb])

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

Create_model
input_tensor = Input(shape=(img_width, img_height, 3))

vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)

Затем прикрепите свою собственную модель. Обратите внимание, что для точной настройки include_top в приведенном выше аргументе должно быть установлено в False .

Connect_model
top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
top_model.add(Dense(256, activation='relu', kernel_initializer='he_normal'))
top_model.add(BatchNormalization())
top_model.add(Dropout(0.5))
top_model.add(Dense(nb_category, activation='softmax'))

# Connect vgg16 with top_model
model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))

Если честно, я не совсем понимаю функцию relu указанную здесь. Поэтому я не думаю, что содержание этой модели очень полезно.

Далее вес фиксируется. Если это не указано, веса будут изучены заново с самого начала, но на этот раз это будет исправлено.

Fix_layers
for layer in model.layers[:15]:
    layer.trainable = False

Скомпилируйте модель. В это время укажите оптимизатор. Это указывает, какой алгоритм использовать при обновлении параметров.

Compile_the_model
optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)
model.compile(loss='categorical_crossentropy',
              optimizer=optimizer,
              metrics=['accuracy'])

Наконец-то учусь. Если ModelCheckpoint установлен в обратных ModelCheckpoint , промежуточные результаты могут быть сохранены. Это не обязательно.

Learning
checkpoint_cb = ModelCheckpoint("snapshot/{epoch:03d}-{val_acc:.5f}.hdf5", save_best_only=True)

model.fit_generator(
        train_generator,
        steps_per_epoch=nb_train_samples // batch_size,
        epochs=epochs,
        validation_data=validation_generator,
        validation_steps=nb_validation_samples // batch_size,
        callbacks=[checkpoint_cb])

3.2 Предсказание

Predict
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.applications.vgg16 import VGG16
from keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization
from keras.models import Model, Sequential, load_model
import pandas as pd
import numpy as np
import os
from pandas import DataFrame

test_data_dir = "/test/"

test_datagen = ImageDataGenerator(rescale=1. / 255)

img_width, img_height = 200, 150
nb_test_samples = 115474
batch_size = 1
nb_category = 14951

test_generator = test_datagen.flow_from_directory(
        test_data_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode=None,
        shuffle=False)

model = load_model("model.h5")

pred = model.predict_generator(
        test_generator,
        steps=nb_test_samples,
        verbose=1)

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

Folder_structure
data/
     test/
           sub/
                 aaa.jpg
                 bbb.jpg
                 ...

Поскольку класс неизвестен, установите для class_mode None .

4 Резюме

  • Понял, как использовать vgg16 с керасом.
  • Загрузите крупномасштабные данные с помощью flow_from_directory .
  • Обратите внимание, что вам нужны подпапки для прогноза.

5 Ссылка

2019 Copyright Channel.241