или, почему тестовые оценки моей 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.