Los parámetros de la capa BN γ, β y la propagación hacia adelante y hacia atrás

c,b

Hay un problema

Después de estandarizar la entrada, puede ocurrir la siguiente situación: una capa en el medio de la red aprende que los datos de características en sí están distribuidos en ambos lados de la función de activación sigmoidea, y la estandarización obligará a que la media de entrada se limite a 0 y la desviación estándar se limita a 1. De esta manera, los datos se transforman en una distribución en la parte media de la función de activación sigmoidea, que destruye la distribución de características aprendida por una cierta capa en el medio de la red.

Solución

Transformar la reconstrucción, introducir parámetros aprendibles γ, β, todos los γ y todos los β se inicializan en 1 y 0 respectivamente, y cada neurona en cada capa tiene su propio γ y β. Para la propagación hacia adelante, se utilizan los propios γ y β de cada neurona. Durante la retropropagación, se calculan los gradientes de todos los γ y todos los β, es decir, dγ y dβ. Una vez finalizada la retropropagación, un optimizador (como SGD, Adam, etc.) puede actualizar cada γ y β y los gradientes correspondientes dγ y dβ respectivamente.

propagación hacia adelante

import numpy as np


def batchnorm_forward(x, gamma, beta, bn_param):
    r"""
    args:
    - x: Data of shape (N, D)
    - gamma: Scale parameter of shape (D,)
    - beta: Shift paremeter of shape (D,)
    - bn_param: Dictionary with the following keys:
    Returns:
    - out: of shape (N, D)
    - cache: A tuple of values needed in the backward pass
    """
    mode = bn_param['mode']
    eps = bn_param.get('eps', 1e-5)
    momentum = bn_param.get('momentum', 0.9)
    N, D = x.shape
    running_mean = bn_param.get('running_mean', np.zeros(D, dtype=x.dtype))
    running_var = bn_param.get('running_var', np.zeros(D, dtype=x.dtype))
    out, cache = None, None
    
    if mode == 'train':
        sample_mean = np.mean(x, axis=0)
        sample_var = np.var(x, axis=0)
        out_ = (x - sample_mean) / np.sqrt(sample_var + eps)
        running_mean = momentum * running_mean + (1 - momentum) * sample_mean
        running_var = momentum * running_var + (1 - momentum) * sample_var
        out = gamma * out_ + beta
        cache = (out_, x, sample_var, sample_mean, eps, gamma, beta)

    elif mode == 'test':
        scale = gamma / np.sqrt(running_var + eps)
        out = x * scale + (beta - running_mean * scale)

    bn_param['running_mean'] = running_mean
    bn_param['running_var'] = running_var

    return out, cache

retropropagación

import numpy as np


def batchnorm_backward(dout, cache):
    r"""
    args:
    - dout: Upstream derivatives, of shape (N, D)
    - cache: Variable of intermediates from batchnorm_forward.
    Returns:
    - dx: Gradient with respect to inputs x, of shape (N, D)
    - dgamma: Gradient with respect to scale parameter gamma, of shape (D,)
    - dbeta: Gradient with respect to shift parameter beta, of shape (D,)
    """
    dx, dgamma, dbeta = None, None, None
    out_, x, sample_var, sample_mean, eps, gamma, beta = cache
    N = x.shape[0]
    dout_ = gamma * dout
    dvar = np.sum(dout_ * (x - sample_mean) * -0.5 * (sample_var + eps) ** -1.5, axis=0)
    dx_ = 1 / np.sqrt(sample_var + eps)
    dvar_ = 2 * (x - sample_mean) / N

    di = dout_ * dx_ + dvar * dvar_
    dmean = -1 * np.sum(di, axis=0)
    dmean_ = np.ones_like(x) / N

    dx = di + dmean * dmean_
    dgamma = np.sum(dout * out_, axis=0)
    dbeta = np.sum(dout, axis=0)

    return dx, dgamma, dbeta

Referencias

Notas del estudio de normalización de lotes y su implementación: se busca programador 

Aprendizaje profundo (29) Notas de estudio de normalización de lotes - Blog de hjimce - Blog de CSDN 

Supongo que te gusta

Origin blog.csdn.net/qq_38964360/article/details/131442126
Recomendado
Clasificación