Как рассчитать количество умножений, происходящих в слое BatchNormalization во время оценки теста? - PullRequest
0 голосов
/ 12 июня 2019

или, почему тестовые оценки моей CNN занимают значительно больше времени с BatchNormalization, чем без?

Мне нужно приблизить теоретическое время выполнения для оценки обученной CNN (с использованием Keras с TF-бэкендом) на тестовом наборе,Таким образом, я попытался вычислить количество мутаций, возникающих во время оценки, чтобы использовать это как метрику.

Но по какой-то причине нормализация партии (BN), по-видимому, оказывает значительное влияние на время оценки, несмотря на то, чтоуместно в теории в моем понимании.

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

Однако, когда я тестирую одну и ту же сеть один раз и без пакетной нормализации после каждого ConvLayer, я заметил, что не могу ее игнорировать: в приведенном простом примерениже, есть только один ConvLayer с размером фильтра (3x3), за которым следует активированный softmax плотный слой, как я делаю классификацию.С BN после конвоя у меня уходит ~ 4,6 секунды на прохождение тестового набора.При использовании точно такой же сетевой архитектуры без BN один и тот же набор тестов обрабатывается за половину времени.

Сводка конфигурации теста с BN (завершает оценку набора тестов через ~ 4.6 с):

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 32, 32, 32)        896       
_________________________________________________________________
batch_normalization_1 (Batch (None, 32, 32, 32)        128       
_________________________________________________________________
flatten_1 (Flatten)          (None, 32768)             0         
_________________________________________________________________
dense_1 (Dense)              (None, 43)                1409067   
=================================================================
Total params: 1,410,091
Trainable params: 1,410,027
Non-trainable params: 64                

Без BN (завершает оценку набора тестов через ~ 2.3 с):

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_2 (Conv2D)            (None, 32, 32, 32)        896       
_________________________________________________________________
flatten_2 (Flatten)          (None, 32768)             0         
_________________________________________________________________
dense_2 (Dense)              (None, 43)                1409067   
=================================================================
Total params: 1,409,963
Trainable params: 1,409,963
Non-trainable params: 0     

Я не знаю, как это масштабируется, так как я не понимаю причину, во-первых, но я могускажем, что я тестировал другие сети с 3-6 одинаковыми конвульными слоями (используя заполнение = то же самое, чтобы сохранить размеры постоянными), и разница в оценке теста в большинстве случаев варьировалась от ~ 25% до ~ 50% (одно-Приведенный ниже пример составного слоя даже имеет ~ 100%).

Почему BN оказывает такое большое влияние, другими словами, какие вычисления происходят, что я пропускаю?Я подумал: BN просто добавляет одно умножение на вход.Так, например, в сети с BN, указанным выше: я ожидал, что batch_normalization_1, например, добавит 32 * 32 * 32 умножения и conv2d_1 32 * 32 * 32 * 3 * 3 умножения.

Но тогда как это сделатькоторые так сильно влияют на общее время выполнения, даже если ConvLayers добавляют больше умножений?

Код, используемый для построения модели:

model = Sequential()
model.add(Conv2D(32, (3, 3), activation="relu", input_shape=x_train.shape[1:], padding="same"))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(43, activation='softmax'))

с x_train.shape[1:], равным (32, 32, 3), представляющимизображение 32x32 с цветами RGB.

1 Ответ

0 голосов
/ 13 июня 2019

Ответ на мой собственный вопрос здесь, на случай, если кто-то столкнется с той же проблемой.

Встраивая библиотеку тестов Fritz AI https://docs.fritz.ai/python-library/benchmark.html, Я мог бы на самом деле проверить количество флопов на слой,и действительно оказалось, что нормализация только добавляет пренебрежимо малое количество вычислений.

----------------------------------------------------------------------------------------------------------------------
Layer (type)                                   Output Shape           MFLOPS     Weights       Core ML Compatible     
======================================================================================================================
conv2d_1 (Conv2D)                              [None, 32, 32, 32]     0.92       896           True          
----------------------------------------------------------------------------------------------------------------------
batch_normalization_1 (BatchNormalization)     [None, 32, 32, 32]     0.07       128           True          
----------------------------------------------------------------------------------------------------------------------
flatten_1 (Flatten)                            [None, 32768]          0.00       0             True          
----------------------------------------------------------------------------------------------------------------------
dense_1 (Dense)                                [None, 43]             2.82       1,409,067     True          
----------------------------------------------------------------------------------------------------------------------

Тем не менее, проблема должна быть вызвана неэффективной процедурой или даже ошибкой в ​​keras для оценки моделей с нормализацией партии.Странно, но это единственно возможное объяснение.

...