Предположим, что вы хотите извлечь объекты из предварительно обученной сверточной нейронной сети, VGGNet, VGG16
.
Код для повторного использования сверточной базы:
from keras.applications import VGG16
conv_base = VGG16(weights='imagenet',
include_top=False,
input_shape=(150, 150, 3)) # This is the Size of your Image
Конечная карта объектов имеет форму (4, 4, 512). Это функция, поверх которой вы будете прикреплять плотно связанный классификатор.
Существует 2 способа извлечения функций:
- БЫСТРАЯ ФУНКЦИЯ ИЗВЛЕЧЕНИЕ БЕЗ УВЕЛИЧЕНИЯ ДАННЫХ: Запуск сверточной базы над вашим набором данных, запись ее вывода в массив Numpy на диске, а затем использование этих данных в качестве входных данных для автономного, плотно связанного классификатора, аналогичного тем, которые вы видели в части 1 этой книги. Это решение является быстрым и дешевым в использовании, потому что оно требует запуска сверточного основания только один раз для каждого входного изображения, а сверточное основание является безусловно самой дорогой частью конвейера. Но по той же причине этот метод не позволяет использовать увеличение данных.
Код для извлечения функций с использованием этого метода показан ниже:
import os
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
base_dir = '/Users/fchollet/Downloads/cats_and_dogs_small'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')
test_dir = os.path.join(base_dir, 'test')
datagen = ImageDataGenerator(rescale=1./255)
batch_size = 20
def extract_features(directory, sample_count):
features = np.zeros(shape=(sample_count, 4, 4, 512))
labels = np.zeros(shape=(sample_count))
generator = datagen.flow_from_directory(directory, target_size=(150, 150),
batch_size=batch_size, class_mode='binary')
i=0
for inputs_batch, labels_batch in generator:
features_batch = conv_base.predict(inputs_batch)
features[i * batch_size : (i + 1) * batch_size] = features_batch
labels[i * batch_size : (i + 1) * batch_size] = labels_batch
i += 1
if i * batch_size >= sample_count:
break
return features, labels
train_features, train_labels = extract_features(train_dir, 2000)
validation_features, validation_labels = extract_features(validation_dir,1000)
test_features, test_labels = extract_features(test_dir, 1000)
train_features = np.reshape(train_features, (2000, 4*4* 512))
validation_features = np.reshape(validation_features, (1000, 4*4* 512))
test_features = np.reshape(test_features, (1000, 4*4* 512))
from keras import models
from keras import layers
from keras import optimizers
model = models.Sequential()
model.add(layers.Dense(256, activation='relu', input_dim=4 * 4 * 512))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))
model.compile(optimizer=optimizers.RMSprop(lr=2e-5),
loss='binary_crossentropy', metrics=['acc'])
history = model.fit(train_features, train_labels, epochs=30,
batch_size=20, validation_data=(validation_features, validation_labels))
Обучение очень быстрое, потому что вам нужно иметь дело только с двумя плотными слоями - эпоха занимает меньше одной секунды даже на CPU
ДОБАВЛЕНИЕ ФУНКЦИЙ С УВЕЛИЧЕНИЕМ ДАННЫХ: Расширение имеющейся у вас модели (conv_base) путем добавления плотных слоев сверху и полного выполнения всей вещи во входных данных. Это позволит вам использовать увеличение данных, потому что каждое входное изображение проходит через сверточную базу каждый раз, когда оно просматривается моделью. Но по той же причине этот метод намного дороже, чем первый
Код для того же кода показан ниже:
from keras import models
from keras import layers
model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
train_datagen = ImageDataGenerator(rescale=1./255,rotation_range=40,
width_shift_range=0.2,height_shift_range=0.2,shear_range=0.2,
zoom_range=0.2,horizontal_flip=True,fill_mode='nearest')
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir,target_size=(150, 150), batch_size=20, class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=2e-5),
metrics=['acc'])
history = model.fit_generator(train_generator, steps_per_epoch=100, epochs=30, validation_data=validation_generator, validation_steps=50)
Для получения более подробной информации, пожалуйста, обратитесь к Раздел 5.3.1 книги «Глубокое обучение с Python», автором которой является Отец Кераса, «Франсуа Шоле»