Как ускорить мой Keras CNN с предварительно обученным InceptionV3 - PullRequest
0 голосов
/ 20 марта 2019

Я хочу обучить сверточную нейронную сеть распознавать между двумя типами классов.
Я также хочу использовать первые сверточные слои уже обученной модели, такой как InceptionV3.
Однако учебные процессы идут очень медленно. Есть ли у вас какие-либо предложения, что я могу улучшить? Я не буду упоминать мой процессор, оперативную память, все, что меня волнует, это где узкие места и что я могу улучшить, чтобы ускорить их (мои изображения уже 229x299x3).

from keras.applications import InceptionV3
from keras import layers
from keras.models import Model
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator
import numpy as np
import os


def generator(images_dir):
    datagen = ImageDataGenerator(rescale=1. / 255)
    gen = datagen.flow_from_directory(
        images_dir,
        target_size=(segment_size, segment_size),
        batch_size=batch_size,
        class_mode='categorical',
        shuffle=True)
    return gen


def num_files_in_folder(folder):
    count = 0
    for subdir, dirs, files in os.walk(folder):
        for file in files:
            if not file.startswith("."):
                count += 1
    return count


segment_size = 229
batch_size = 32
base_model = InceptionV3(weights='imagenet',
                         include_top=False,
                         input_shape=(segment_size, segment_size, 3))
x = base_model.output
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(1024, activation='relu')(x)
predictions = layers.Dense(2, activation='softmax')(x)

model = Model(inputs=base_model.input, outputs=predictions)

for layer in base_model.layers:
    layer.trainable = False

model.compile(optimizer=optimizers.SGD(lr=0.01, nesterov=True),
              loss='categorical_crossentropy',
              metrics=['acc'])

train_dir = "/home/user/train"
validation_dir = "/home/user/val"
train_gen = generator(train_dir)
val_gen = generator(validation_dir)
steps_per_epoch = int(np.ceil(num_files_in_folder(train_dir) / batch_size))
validation_steps = int(np.ceil(num_files_in_folder(validation_dir) / batch_size))

history = model.fit_generator(
    generator=train_gen,
    steps_per_epoch=steps_per_epoch,
    epochs=10,
    validation_data=val_gen,
    validation_steps=validation_steps,
    use_multiprocessing=False,
    verbose=1)

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Прежде всего, я предлагаю вам преобразовать ваши данные в TFRecords и избегать использования flow_from_directory. ImageDataGenerator может быть хорошим вариантом для быстрого создания прототипов, но TFRecords и соответствующая им инфраструктура TF (очереди / бегуны / читатели) действительно оптимизированы для быстрого чтения. Используя tf.data API и особенно Dataset.prefetch(), вы можете значительно ускориться.

Поскольку в большинстве случаев считывание данных является узким местом, я мог бы остановиться прямо здесь. Но после этого я бы тоже попробовал:

0 голосов
/ 21 марта 2019

Я бы попробовал это с tf.data.Dataset.from_tensor_slices Предположим, у вас есть путь для набора поездов train_path.Сначала вы создаете объект набора данных из него.Также вы можете передавать не путь, а пути from_tensor_slices((image_path, labels_path)) или списки имен файлов / меток.Позже он может быть обработан с помощью функции синтаксического анализа.

dataset = tf.data.Dataset.from_tensor_slices(image_path)

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

dataset = dataset.shuffle().repeat()
dataset.apply(tf.data.experimental.map_and_batch(map_func=parse_func, batch_size,num_parallel_batches))

. Вам нужно определить функцию синтаксического анализа для загрузки фактических данных из имени файла

def parse_func(filename):
    f = tf.read_file(filename)
    img = tf.image.decode_image(f)
    label = #get label from filename
    return img, l

После применения этого к объекту набора данных он будет содержать пакетыпар image / label.

Помните, что пакетирование происходит внутри этого конвейера, поэтому вам не нужно использовать пакет в model.fit, но вам нужно передавать число эпох и шагов за эпоху.Последнее может быть немного сложнее, потому что вы не можете сделать что-то вроде len (набора данных), поэтому его следует рассчитать заранее.

model.fit(dataset, epochs, steps_per_epoch)

Вы можете сделать то же самое для тестового набора данных.Вы также можете проверить его содержимое с помощью

iterator = dataset.make_one_shot_iterator()
with tf.Session() as sess:
    print(sess.run(iterator.get_next()))

. Это выведет num_batches.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...