Почему обучение занимает так много времени на моем GPU?

10

Подробности:

GPU : GTX 1080

Обучение : ~ 1,1 млн. Изображений, принадлежащих 10 классам

Проверка : ~ 150 тысяч изображений, относящихся к 10 классам

Время за эпоху : ~ 10 часов

Я установил CUDA, cuDNN и Tensorflow (также Tensorflow GPU).

Я не думаю, что моя модель настолько сложна, что занимает 10 часов за эпоху. Я даже проверил, была ли проблема в моем GPU, но это не так.

Время обучения связано с полностью соединенными слоями?

Моя модель:

model = Sequential()
model.add()
model.add(Conv2D(64, (3, 3), padding="same", strides=2))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding="same", strides=2))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(3, 3), strides=2))
model.add(Flatten())
model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dense(4096))
model.add(Activation('relu'))
model.add(Dense(10))
model.add(Activation('softmax'))

model.summary()

opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)

model.compile(loss='categorical_crossentropy',
          optimizer=opt,
          metrics=['accuracy']
          )

Поскольку данных много, я использовал ImageDataGenerator.

gen = ImageDataGenerator(
 horizontal_flip=True
)

train_gen = gen.flow_from_directory(
        'train/',
        target_size=(512, 512),
        batch_size=5,
        class_mode="categorical"
)

valid_gen = gen.flow_from_directory(
        'validation/',
        target_size=(512, 512),
        batch_size=5,
        class_mode="categorical"
)
Прадьюмна Рахул
источник
2
Я проголосовал за то, чтобы переместить это в переполнение стека, но на самом деле оно относится к обмену стеками в науке о данных, IMO
generic_user
generic_user: «наука о данных» может использовать «машинное обучение», но не все «машинное обучение» предназначено для «науки о данных». (ML - просто еще один инструмент, тензор потока - просто другая библиотека; ML может скоро (если не будет) использоваться даже для рутинных задач, таких как управление файлами свойств пользовательских настроек.)
Майкл
см. также связанные (tl; dr: проверить, действительно ли работает на gpu, посмотрите статистику gpu, которую может предоставить tf) stackoverflow.com/questions/42527492/… stackoverflow.com/questions/38559755/…
michael
Я попробовал этот подход, и он утверждает, что мой текущий графический процессор используется. Для подтверждения я также использовал nvidia-smi для проверки использования графического процессора, и он колеблется от 85% до 99%.
Прадьюмна Рахул

Ответы:

7

Это об ожидаемом. Если вы поделите количество секунд на количество обработанных изображений, вы получите 33 миллисекунды на изображение, что кажется правильным для такой маленькой сети. Большие сети обычно принимают от 50 до 200 миллисекунд на изображение.

Да, большой плотный слой может снизить производительность, поскольку это огромная матрица (256 на 4096) и большое умножение матриц, которое можно использовать при каждом запуске сети.

Симао
источник
Что бы вы предложили улучшить производительность?
4
1: увеличить размер партии до 32 или 64. 2: уменьшить размер слоя FC до 1024 или 2048 единиц и посмотреть, поможет ли это. 3: Ранняя остановка. Вполне возможно, что ваша сеть сошлась или начинает переоснащаться до того, как вы закончите свою первую эпоху, и в этом случае вы должны тренироваться меньше.
Должен ли я уменьшить количество шагов в эпоху?
Прадьюмна Рахул
@shimao, что ты имел в виду под "меньше тренируйся"? Вы имеете в виду использовать меньше данных?
StatsSorceress
3

Как сказал Симао, это то, что вы ожидаете. Несмотря на то, что слоев мало, входной размер 512x512 - это большое изображение, которое нужно свернуть. Большое время вычислений, вероятно, больше из-за свертки 64 фильтров по большому изображению вместо полностью связанных слоев.

В сети, которую вы создали, есть забавное информационное узкое место. Вы начинаете с 64 фильтров на исходном размере изображения, только уменьшаясь по мере уменьшения размера изображения. Когда изображение проходит через вашу сеть, изучаемые вами функции становятся все более абстрактными и сложными. Ваш уровень Conv2D (32, (3, 3)) по существу ограничивает сеть изучением карты 128х128 из 32 объектов.

Большинство сетевых архитектур удваивает количество объектов каждый раз, когда они объединяются в пул, а последние архитектуры imagenet фактически отбрасывают полностью подключенные слои в пользу среднего пула по сравнению с конечной картой объектов и в основном выполняют логистическую регрессию на выходе этого пула.

Попробуйте начать с меньшего количества фильтров, скажем, 16 на первом слое свертки, удваивая каждый раз, когда вы шагаете или объединяетесь. Сделайте это несколько раз, чтобы увеличить восприимчивое поле и уменьшить размер карты объектов. Сделайте это до 64x64 или 32x32, что будет 128 или 256 фильтров. Вы также можете использовать глобальное среднее или максимальное объединение Keras, чтобы исключить полностью подключенные слои. Это должно примерно удвоить скорость сети, и я ожидал бы увеличение точности в то же время.

mpotma
источник
Ну, сетевая архитектура основана на исследовательской работе, которую я пытался воспроизвести. lirmm.fr/%7Echaumont/publications/…
Прадьюмна Рахул