Ver fuente en GitHub

Capa que normaliza sus entradas.

Hereda de: Layer, Module

tf.keras.layers.BatchNormalization(
    axis=-1, momentum=0.99, epsilon=0.001, center=True, scale=True,
    beta_initializer='zeros', gamma_initializer='ones',
    moving_mean_initializer='zeros',
    moving_variance_initializer='ones', beta_regularizer=None,
    gamma_regularizer=None, beta_constraint=None, gamma_constraint=None,
    renorm=False, renorm_clipping=None, renorm_momentum=0.99, fused=None,
    trainable=True, virtual_batch_size=None, adjustment=None, name=None,**kwargs
)

La normalización por lotes aplica una transformación que mantiene la salida media cercana a 0 y la desviación estándar de salida cercana a 1.

Es importante destacar que la normalización por lotes funciona de manera diferente durante el entrenamiento y durante la inferencia.

Durante el entrenamiento (es decir, cuando se usa fit() o al llamar a la capa / modelo con el argumento training=True), la capa normaliza su salida utilizando la desviación media y estándar del lote actual de entradas. Es decir, para cada canal que se normaliza, la capa devuelve (batch - mean(batch)) / (var(batch) + epsilon) * gamma + beta, dónde:

  • epsilon es pequeña constante (configurable como parte de los argumentos del constructor)
  • gamma es un factor de escala aprendido (inicializado como 1), que puede desactivarse pasando scale=False al constructor.
  • beta es un factor de compensación aprendido (inicializado como 0), que puede desactivarse pasando center=False al constructor.

Durante la inferencia (es decir, cuando se usa evaluate() o predict() o al llamar a la capa / modelo con el argumento training=False (que es el valor predeterminado), la capa normaliza su salida utilizando un promedio móvil de la media y la desviación estándar de los lotes que ha visto durante el entrenamiento. Es decir, vuelve (batch - self.moving_mean) / (self.moving_var + epsilon) * gamma + beta.

self.moving_mean y self.moving_var son variables no entrenables que se actualizan cada vez que se llama a la capa en el modo de entrenamiento, como tales:

  • moving_mean = moving_mean * momentum + mean(batch) * (1 - momentum)
  • moving_var = moving_var * momentum + var(batch) * (1 - momentum)

Como tal, la capa solo normalizará sus entradas durante la inferencia después de haber sido entrenado con datos que tienen estadísticas similares a los datos de inferencia.

Argumentos
axis Entero o una lista de números enteros, el eje que debe normalizarse (normalmente el eje de características). Por ejemplo, después de un Conv2D capa con data_format="channels_first", colocar axis=1 en BatchNormalization.
momentum Momento de la media móvil.
epsilon Flotador pequeño agregado a la varianza para evitar dividir por cero.
center Si es verdadero, agregue el desplazamiento de beta al tensor normalizado. Si es falso, beta se ignora.
scale Si es verdadero, multiplique por gamma. Si es falso, gamma no se utiliza. Cuando la siguiente capa es lineal (también p. Ej. nn.relu), esto puede desactivarse ya que la siguiente capa realizará el escalado.
beta_initializer Inicializador para el peso beta.
gamma_initializer Inicializador para el peso gamma.
moving_mean_initializer Inicializador para la media móvil.
moving_variance_initializer Inicializador para la variación móvil.
beta_regularizer Regularizador opcional para el peso beta.
gamma_regularizer Regularizador opcional para el peso gamma.
beta_constraint Restricción opcional para el peso beta.
gamma_constraint Restricción opcional para el peso gamma.
renorm Ya sea para usar Renormalización por lotes. Esto agrega variables adicionales durante el entrenamiento. La inferencia es la misma para cualquier valor de este parámetro.
renorm_clipping Un diccionario que puede mapear keys ‘rmax’, ‘rmin’, ‘dmax’ a escalar Tensors utilizado para recortar la corrección de renorm. La correccion (r, d) se usa como corrected_value = normalized_value * r + d, con r recortado a [rmin, rmax], y d para [-dmax, dmax]. Los valores rmax, rmin y dmax que faltan se establecen en inf, 0, inf, respectivamente.
renorm_momentum Momentum utilizado para actualizar las medias móviles y las desviaciones estándar con renorm. diferente a momentum, esto afecta el entrenamiento y no debe ser ni demasiado pequeño (lo que agregaría ruido) ni demasiado grande (lo que daría estimaciones obsoletas). Tenga en cuenta que momentum todavía se aplica para obtener las medias y las variaciones para la inferencia.
fused si True, use una implementación fusionada más rápida, o genere un ValueError si la implementación fusionada no se puede usar. Si None, utilice la implementación más rápida si es posible. Si es False, no utilice la implementación fusionada.
trainable Booleano, si True las variables se marcarán como entrenables.
virtual_batch_size Un int. Por defecto, virtual_batch_size es None, lo que significa que la normalización de lotes se realiza en todo el lote. Cuando virtual_batch_size no es None, en su lugar, realice la “Normalización de lotes fantasma”, que crea sub-lotes virtuales que se normalizan por separado (con estadísticas compartidas de gamma, beta y movimiento). Debe dividir el tamaño real del lote durante la ejecución.
adjustment Una función que toma el Tensor que contiene la forma (dinámica) del tensor de entrada y devuelve un par (escala, sesgo) para aplicar a los valores normalizados (antes de gamma y beta), solo durante el entrenamiento. Por ejemplo, si axis == – 1, adjustment = lambda shape: ( tf.random.uniform(shape[-1:], 0.93, 1.07), tf.random.uniform(shape[-1:], -0.1, 0.1)) escalará el valor normalizado hasta en un 7% hacia arriba o hacia abajo, luego cambiará el resultado hasta 0.1 (con escala y sesgo independientes para cada característica, pero compartido en todos los ejemplos), y finalmente aplicará gamma y / o beta. Si None, no se aplica ningún ajuste. No se puede especificar si se especifica virtual_batch_size.

Argumentos de llamada:

  • inputs: Tensor de entrada (de cualquier rango).
  • training: Python booleano que indica si la capa debe comportarse en modo de entrenamiento o en modo de inferencia.
    • training=True: La capa normalizará sus entradas utilizando la media y la varianza del lote actual de entradas.
    • training=False: La capa normalizará sus entradas utilizando la media y la varianza de sus estadísticas móviles, aprendidas durante el entrenamiento.

Forma de entrada: arbitraria. Usa el argumento de la palabra clave input_shape (tupla de enteros, no incluye el eje de muestras) cuando se usa esta capa como la primera capa en un modelo.

Forma de salida: la misma forma que la entrada.
Acerca de la configuración layer.trainable = False en un BatchNormalization capa:

El significado de la ambientación layer.trainable = False es congelar la capa, es decir, su estado interno no cambiará durante el entrenamiento: sus pesos entrenables no se actualizarán durante fit() o train_on_batch()y sus actualizaciones de estado no se ejecutarán.

Por lo general, esto no significa necesariamente que la capa se ejecute en modo de inferencia (que normalmente está controlado por el training argumento que se puede pasar al llamar a una capa). “Estado congelado” y “modo de inferencia” son dos conceptos separados.

Sin embargo, en el caso de BatchNormalization capa, configuración trainable = False en la capa significa que la capa se ejecutará posteriormente en modo de inferencia (lo que significa que utilizará la media móvil y la varianza móvil para normalizar el lote actual, en lugar de utilizar la media y la varianza del lote actual).

Este comportamiento se introdujo en TensorFlow 2.0 para habilitar layer.trainable = False para producir el comportamiento más comúnmente esperado en el caso de uso de ajuste fino de convnet.

Tenga en cuenta que:

  • Este comportamiento solo ocurre a partir de TensorFlow 2.0. En 1. *, ajuste layer.trainable = False congelaría la capa pero no la cambiaría al modo de inferencia.
  • Configuración trainable en un modelo que contiene otras capas establecerá recursivamente el trainable valor de todas las capas internas.
  • Si el valor del trainable attribute se cambia después de llamar compile() en un modelo, el nuevo valor no entra en vigor para este modelo hasta que compile() se llama de nuevo.

Referencia: