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

Эта статья была опубликована более года назад. Информация может быть уст аревшей.
1. Введение
Недавно я начал изучать машинное обучение и участвовал в Kaggle , конкурсе по классификации изображений.
На этот раз я подведу итог, как реализовать тонкую настройку vgg16 с библиотекой python keras 1.
2 О данных
Набор данных выглядит следующим образом.
У меня был только такой набор данных, как MNIST который часто видели в обучающих материалах по ML, поэтому я чувствовал, что это очень большой набор данных.
- Классы: около 15 000
- Размер данных обучения: около 1,2 миллиона файлов изображений. Более 300ГБ
- Размер каждого файла изображения: варьируется между файлами. например 1600 \ 1200 *
- Тестовые данные: около 120000 файлов
3 Реализация
3.1 Изучить данные
Сначала я покажу вам весь код.
1from keras.preprocessing.image import ImageDataGenerator2from keras import optimizers3from keras.applications.vgg16 import VGG164from keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization5from keras.models import Model, Sequential6from keras.callbacks import ModelCheckpoint7import numpy as np8 9train_data_dir = "/train/"10validation_data_dir = "/validation/"11 12train_datagen = ImageDataGenerator(rescale=1. / 255)13validation_datagen = ImageDataGenerator(rescale=1. / 255)14 15img_width, img_height = 200, 15016nb_train_samples = 91564917nb_validation_samples = 30209118epochs = 5019batch_size = 6420nb_category = 1495121 22train_generator = train_datagen.flow_from_directory(23 train_data_dir,24 target_size=(img_width, img_height),25 batch_size=batch_size,26 class_mode="categorical")27 28validation_generator = validation_datagen.flow_from_directory(29 validation_data_dir,30 target_size=(img_width, img_height),31 batch_size=batch_size,32 class_mode="categorical")33 34# define input_tensor35input_tensor = Input(shape=(img_width, img_height, 3))36 37vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)38 39top_model = Sequential()40top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))41top_model.add(Dense(256, activation='relu', kernel_initializer='he_normal'))42top_model.add(BatchNormalization())43top_model.add(Dropout(0.5))44top_model.add(Dense(nb_category, activation='softmax'))45 46# Connect vgg16 and top_model47model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))48 49# Fix layers50for layer in model.layers[:15]:51 layer.trainable = False52 53optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)54model.compile(loss='categorical_crossentropy',55 optimizer=optimizer,56 metrics=['accuracy'])57 58checkpoint_cb = ModelCheckpoint("snapshot/{epoch:03d}-{val_acc:.5f}.hdf5", save_best_only=True)59 60model.fit_generator(61 train_generator,62 steps_per_epoch=nb_train_samples // batch_size,63 epochs=epochs,64 validation_data=validation_generator,65 validation_steps=nb_validation_samples // batch_size,66 callbacks=[checkpoint_cb])67 68# Save the model69model.save("model.h5")70 71model.summary()3.1.1 Учитесь с крупномасштабными данными
В большинстве уроков мы видим, что данные загружаются следующим образом.
1(X_train, y_train), (X_test, y_test) = mnist.load_data()Однако невозможно загружать целые данные в память, когда вы обрабатываете такие большие данные, как в этот раз.
Вместо этого вы можете использовать функцию flow_from_directory для загрузки данных 2.
Эта функция обрабатывает данные изображения, расширяя их в режиме реального времени.
Сначала вам нужно создать ImageDataGenerator .
1train_datagen = ImageDataGenerator(rescale=1. / 255)2validation_datagen = ImageDataGenerator(rescale=1. / 255)Этот класс выполняет пакетную генерацию данных изображения при выполнении предварительной обработки. На этот раз просто измените масштаб. 1/255 используется для нормализации диапазона значений RGB от 0-255 до 0-1.
Далее читаем данные
1train_generator = train_datagen.flow_from_directory(2 train_data_dir,3 target_size=(img_width, img_height),4 batch_size=batch_size,5 class_mode="categorical")6 7validation_generator = validation_datagen.flow_from_directory(8 validation_data_dir,9 target_size=(img_width, img_height),10 batch_size=batch_size,11 class_mode="categorical")Поскольку это категориальная классификация, установите class_mode как categorical .
В это время вы должны быть осторожны со структурой папок. Как показано ниже, вы должны создать подпапку для каждого класса, который вы хотите классифицировать.
1data/2 train/3 classA/4 aaa.jpg5 bbb.jpg6 ...7 classB/8 ccc.jpg9 ddd.jpg10 ...11 12 validation/13 classA/14 eee.jpg15 fff.jpg16 ...17 classB/18 ggg.jpg19 hhh.jpg20 ...3.1.2 Использование модели vgg16
Научитесь использовать модель VGG16, которую можно использовать с Keras .
1# define input_tensor2input_tensor = Input(shape=(img_width, img_height, 3))3 4vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)5 6top_model = Sequential()7top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))8top_model.add(Dense(256, activation='relu', kernel_initializer='he_normal'))9top_model.add(BatchNormalization())10top_model.add(Dropout(0.5))11top_model.add(Dense(nb_category, activation='softmax'))12 13# Connect vgg16 with top_model14model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))15 16# Fix layers17for layer in model.layers[:15]:18 layer.trainable = False19 20optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)21model.compile(loss='categorical_crossentropy',22 optimizer=optimizer,23 metrics=['accuracy'])24 25checkpoint_cb = ModelCheckpoint("snapshot/{epoch:03d}-{val_acc:.5f}.hdf5", save_best_only=True)26 27model.fit_generator(28 train_generator,29 steps_per_epoch=nb_train_samples // batch_size,30 epochs=epochs,31 validation_data=validation_generator,32 validation_steps=nb_validation_samples // batch_size,33 callbacks=[checkpoint_cb])Сначала используйте модель vgg16 по умолчанию. В это время указан размер входного набора данных.
1input_tensor = Input(shape=(img_width, img_height, 3))2 3vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)Затем прикрепите свою собственную модель.
Обратите внимание, что для точной настройки include_top в приведенном выше аргументе должно быть установлено в False .
1top_model = Sequential()2top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))3top_model.add(Dense(256, activation='relu', kernel_initializer='he_normal'))4top_model.add(BatchNormalization())5top_model.add(Dropout(0.5))6top_model.add(Dense(nb_category, activation='softmax'))7 8# Connect vgg16 with top_model9model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))Если честно, я не совсем понимаю функцию relu указанную здесь.
Поэтому я не думаю, что содержание этой модели очень полезно.
Далее вес фиксируется. Если это не указано, веса будут изучены заново с самого начала, но на этот раз это будет исправлено.
1for layer in model.layers[:15]:2 layer.trainable = FalseСкомпилируйте модель. В это время укажите оптимизатор. Это указывает, какой алгоритм использовать при обновлении параметров.
1optimizer = optimizers.rmsprop(lr=5e-7, decay=5e-5)2model.compile(loss='categorical_crossentropy',3 optimizer=optimizer,4 metrics=['accuracy'])Наконец-то учусь. Если ModelCheckpoint установлен в обратных ModelCheckpoint , промежуточные результаты могут быть сохранены. Это не обязательно.
1checkpoint_cb = ModelCheckpoint("snapshot/{epoch:03d}-{val_acc:.5f}.hdf5", save_best_only=True)2 3model.fit_generator(4 train_generator,5 steps_per_epoch=nb_train_samples // batch_size,6 epochs=epochs,7 validation_data=validation_generator,8 validation_steps=nb_validation_samples // batch_size,9 callbacks=[checkpoint_cb])3.2 Предсказание
1from keras.preprocessing.image import ImageDataGenerator2from keras import optimizers3from keras.applications.vgg16 import VGG164from keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization5from keras.models import Model, Sequential, load_model6import pandas as pd7import numpy as np8import os9from pandas import DataFrame10 11test_data_dir = "/test/"12 13test_datagen = ImageDataGenerator(rescale=1. / 255)14 15img_width, img_height = 200, 15016nb_test_samples = 11547417batch_size = 118nb_category = 1495119 20test_generator = test_datagen.flow_from_directory(21 test_data_dir,22 target_size=(img_width, img_height),23 batch_size=batch_size,24 class_mode=None,25 shuffle=False)26 27model = load_model("model.h5")28 29pred = model.predict_generator(30 test_generator,31 steps=nb_test_samples,32 verbose=1)Это не так сильно отличается от изучения кода. Аналогично, данные читаются с помощью flow_from_directory , но следует отметить, что подпапки необходимы даже для тестовых данных (= классы неизвестны). Например, в следующей конфигурации он не будет работать, если вы не организуете данные в подпапках.
1data/2 test/3 sub/4 aaa.jpg5 bbb.jpg6 ...Поскольку класс неизвестен, установите для class_mode None .
4 Резюме
- Понял, как использовать vgg16 с керасом.
- Загрузите крупномасштабные данные с помощью
flow_from_directory. - Обратите внимание, что вам нужны подпапки для прогноза.




