Tensorflow 2.0 Keras BatchNorm: как обновить онлайн-параметры в пользовательском обучении? - PullRequest
0 голосов
/ 02 октября 2019

Как тренировать слой пакетной нормы без использования каких-либо методов keras.compile? Обычно слои имеют потери, которые доступны. Здесь метод потерь пуст.

ОБНОВЛЕНИЕ:

Кажется, что в этом много путаницы, и даже способ реализации BatchNorm довольно запутан.

Во-первых, есть только способ обучения онлайн-параметрам (используйте в режиме обучения = ложный режим) для масштабирования и сдвига функций: вызовите слой в режиме обучения = истинный режим. И если вы НИКОГДА не хотите использовать «пакетную» часть нормализации партии (т. Е. Вам просто нужен онлайн-нормализатор, который тренируется с потерей Normal log-prob, вы в принципе не можете сделать это за один вызов AFAIK.

Вызов слоя с обучением = False не обновляет параметры. Вызов его с обучением = True обновляет параметры, но затем вы получаете пакетный нормированный слой (не использует онлайн-локализацию и масштаб).

import tensorflow as tf

class Model(tf.keras.models.Model):
    def __init__(self):
        super().__init__()
        self.dense = tf.keras.layers.Dense(4)
        self.bn = tf.keras.layers.BatchNormalization()
    def call(self, x, training=False):
        x = self.dense(x)
        x = self.bn(x, training=training)
        return x

model = Model()    
x = 10 * np.random.randn(30, 4).astype(np.float32)

print(tf.math.reduce_std(model(x)))
tf.keras.backend.set_learning_phase(1)
print(tf.math.reduce_std(model(x)))
print(tf.math.reduce_std(model(x)))
tf.keras.backend.set_learning_phase(0)
print(tf.math.reduce_std(model(x)))
print(tf.math.reduce_std(model(x)))


tf.Tensor(9.504262, shape=(), dtype=float32)
tf.Tensor(0.99999136, shape=(), dtype=float32)
tf.Tensor(0.99999136, shape=(), dtype=float32)
tf.Tensor(5.4472375, shape=(), dtype=float32)
tf.Tensor(5.4472375, shape=(), dtype=float32)

ОБНОВЛЕНИЕ:

Отображение слоев keras иногда приводит к потерям (когда существуют подзадачи, такие как регулирование):

In [335]: l = tf.keras.layers.Dense(8, kernel_regularizer=tf.keras.regularizers.L1L2())

In [336]: l(np.random.randn(2, 4))

Out[336]:
<tf.Tensor: id=2521999, shape=(2, 8), dtype=float32, numpy=
array([[ 1.1332406 ,  0.32000083,  0.8104123 ,  0.5066328 ,  0.35904446, -1.4265257 ,  1.3057183 ,  0.34458983],
       [-0.23246719, -0.46841025,  0.9706465 ,  0.42356712,  1.705613  , -0.08619405, -0.5261058 , -1.1696107 ]], dtype=float32)>

In [337]: l.losses
Out[337]: [<tf.Tensor: id=2522000, shape=(), dtype=float32, numpy=0.0>]

In [338]: l = tf.keras.layers.Dense(8)

In [339]: l(np.random.randn(2, 4))

Out[339]:
<tf.Tensor: id=2522028, shape=(2, 8), dtype=float32, numpy=
array([[ 1.0674231 , -0.13423748,  0.01775402,  2.5400681 , -0.53589094,  1.4460006 , -1.7197075 ,  0.3285858 ],
       [ 2.2171447 , -1.7448915 ,  0.4758569 ,  0.58695656,  0.32054698,  0.7813705 , -2.3022552 ,  0.44061095]], dtype=float32)>

In [340]: l.losses
Out[340]: []

1 Ответ

0 голосов
/ 02 октября 2019

BatchNorm тренируется, но не имеет потерь. Он просто отслеживает среднее и стандартное число последовательных партий во взвешенном скользящем среднем. Потери / градиента не происходит.

...