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

⏱️3 мин
Поделиться:

1. Введение

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

2 О данных

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

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

3 Реализация

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

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

python
1from keras.preprocessing.image import ImageDataGenerator
2from keras import optimizers
3from keras.applications.vgg16 import VGG16
4from keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization
5from keras.models import Model, Sequential
6from keras.callbacks import ModelCheckpoint
7import numpy as np
8
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, 150
16nb_train_samples = 915649
17nb_validation_samples = 302091
18epochs = 50
19batch_size = 64
20nb_category = 14951
21
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_tensor
35input_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_model
47model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))
48
49# Fix layers
50for layer in model.layers[:15]:
51 layer.trainable = False
52
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 model
69model.save("model.h5")
70
71model.summary()

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

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

python
1(X_train, y_train), (X_test, y_test) = mnist.load_data()

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

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

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

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

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

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

javascript
1data/
2 train/
3 classA/
4 aaa.jpg
5 bbb.jpg
6 ...
7 classB/
8 ccc.jpg
9 ddd.jpg
10 ...
11
12 validation/
13 classA/
14 eee.jpg
15 fff.jpg
16 ...
17 classB/
18 ggg.jpg
19 hhh.jpg
20 ...

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

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

python
1# define input_tensor
2input_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_model
14model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))
15
16# Fix layers
17for layer in model.layers[:15]:
18 layer.trainable = False
19
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 по умолчанию. В это время указан размер входного набора данных.

python
1input_tensor = Input(shape=(img_width, img_height, 3))
2
3vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)

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

python
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_model
9model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))

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

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

python
1for layer in model.layers[:15]:
2 layer.trainable = False

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

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

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

python
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 Предсказание

python
1from keras.preprocessing.image import ImageDataGenerator
2from keras import optimizers
3from keras.applications.vgg16 import VGG16
4from keras.layers import Dense, Dropout, Flatten, Input, BatchNormalization
5from keras.models import Model, Sequential, load_model
6import pandas as pd
7import numpy as np
8import os
9from pandas import DataFrame
10
11test_data_dir = "/test/"
12
13test_datagen = ImageDataGenerator(rescale=1. / 255)
14
15img_width, img_height = 200, 150
16nb_test_samples = 115474
17batch_size = 1
18nb_category = 14951
19
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 , но следует отметить, что подпапки необходимы даже для тестовых данных (= классы неизвестны). Например, в следующей конфигурации он не будет работать, если вы не организуете данные в подпапках.

javascript
1data/
2 test/
3 sub/
4 aaa.jpg
5 bbb.jpg
6 ...

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

4 Резюме

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

5 Ссылка

Footnotes

  1. Keras Documentation

  2. Building powerful image classification models using very little data

Поделиться:

Связанные статьи