Иногда обучение нейронных сетей может занимать дни или недели. Это имеет несколько недостатков и постоянно беспокоит специалистов по машинному обучению, особенно тех, у кого нет доступа к дополнительным вычислительным ресурсам. Длительное время обучения часто означает, что вы не можете настроить модели до тех пор, пока они не закончат обучение — несколько дней или недель. Даже после того, как они прошли обучение, вы не можете должным образом изучить все возможные настройки из-за ограниченного времени на производство. Это также невыгодно для бизнеса, так как несколько человеко-часов тратятся впустую, пока модели закончат обучение. Одним из способов сократить время обучения является оптимизация нашего подхода к машинному обучению на каждом этапе пути. Одним из таких умных способов является так называемая пакетная нормализация. В этом руководстве мы поймем, что такое пакетная нормализация, и реализуем ее с нуля.

Что такое пакетная нормализация?

Как следует из названия, пакетная нормализация направлена ​​на нормализацию. Если вы немного знакомы со статистикой и предварительной обработкой данных, вы знаете, что мы часто нормализуем наши данные, чтобы гарантировать, что функции имеют одинаковый масштаб и почти одинаковое распределение. Это ускоряет обучение и устраняет выбросы в наборе данных. Это предотвращает ковариативный сдвиг, что означает, что модель более надежна и может легко работать с новыми данными. Интуиция, стоящая за пакетной нормализацией, заключается в том, что если мы делаем это для входного слоя, почему мы не можем применить его ко всем слоям в нейронной сети?

Пакетная нормализация направлена ​​на выполнение предварительной обработки на каждом слое. Это помогает каждому из этих слоев учиться больше независимо от других слоев. Пакетная нормализация была предложена в 2015 году Сергеем Иоффе и Кристианом Сегеди. В дополнение к этому, пакетная нормализация оказывает своего рода регуляризирующий эффект на нейронные сети, поскольку добавляет шум к выходным данным каждого слоя, таким образом предотвращая переоснащение. Однако пакетную нормализацию не следует использовать в качестве регуляризатора. Пакетная нормализация позволяет нам использовать более высокую скорость обучения, поскольку каждый слой теперь нормализован, поэтому его дисперсия была уменьшена. Это означает, что он может двигаться быстрее в направлении оптимального минимума.

Реализация пакетной нормализации

Теперь мы приступим к реализации пакетной нормализации с нуля в Python. Потребуются следующие шаги:

  1. Начните с реализации прямого распространения путем инициализации параметров обучения — бета и гамма. Эпсилон для численной стабильности также должен быть инициализирован
  2. Приступить к вычислению среднего значения линейных выходов в слое.
  3. Вычислить дисперсию слоя
  4. Добавьте эпсилон к дисперсии для численной стабильности, затем перейдите к расчету стандартного отклонения.
  5. Нормализация слоя
  6. Добавьте немного шума с параметрами beta и gamma
  7. Сохраните параметры в кэше
  8. Вернуть нормализованный слой и сохраненные параметры
def batch_norm_forwardprop(Z, gamma, beta, epsilon = 1e-8):
    
    '''
    This function performs batch normalization in a forward propagation on every hidden layer of a neural network. 
    
    Inputs:
    Z - the linear output of the layer to be normalized 
    gamma - the first normalizer parameter
    beta - second normalizer parameter
    
    Output :
    Z_out - outputed normalized Z
    Cache - a temprorary storage for our prameters
    
    '''
    
    #Compute the mean of the Zs in the layer
    mean = np.mean(Z, axis = 0)
    
    #compute the variance of the Zs
    variance = np.mean((Z - mean)**2)
    
    #Normalize the Z with mean and standard deviation
    Z_norm = (Z - mean) / (np.sqrt(variance + epsilon))
    
    #Add some noise to the normalized Z so that they are reasonably different
    Z_out = (gamma * Z_norm) + beta
    
    #Store parameters in cache
    Cache = (Z, Z_norm, Z_out, mean, variance, gamma, beta)
    
    return Z_out, Cache

Теперь приступим к обратному распространению:

  1. Получить параметры из кеша[Код]
  2. Получить форму слоя[Код]
  3. Приступить к расчету градиента нормализованного Z [Код]
  4. Рассчитать градиент параметров — гамма и бета [Код]
  5. Вернуть рассчитанные градиенты [Код]
def batch_norm_backwardprop (Z_out, cache):
    
    '''
    This function performs batch normalization in a forward propagation on every hidden layer of a neural network. 
    
    Inputs:
    Z_out - the outputted normalized Z from the forward propagation 
    Cache - a temprorary storage for our prameters
    
    Outputs:
    
    dZ -gradient of Z
    dgamma - gradient of gamma
    dbeta - gradient of beta
    
    '''
    
    #Retrieve parameters from cache
    Z, Z_norm, Z_out, mean, variance, gamma, beta = Cache
    
    #Retrieve shape of Z
    X,Y = Z.shape
    
    '''
    We proceed to calculate the gradients. The formulas for the gradient can be obtained from the original 
    bactch normalization paper. Or they can be calculated by you, if you are great at calculus. 
    '''
    
    Z_mean = Z - mean
    inverted_sd = 1. / np.sqrt(var + 1e-8)

    dZ_norm = Z_out * gamma
    dvar = np.sum(dZ_norm * Z_mu, axis=0) * -.5 * inverted_sd**3
    dmean = np.sum(dZ_norm * -inverted_sd, axis=0) + dvar * np.mean(-2. * Z_mean, axis=0)

    dZ = (dZ_norm * inverted_sd) + (dvar * 2 * Z_mean / N) + (dmean / N)
    dgamma = np.sum(Zout * Z_norm, axis=0)
    dbeta = np.sum(Zout, axis=0)

    return dZ, dgamma, dbeta

Если вы когда-либо сталкивались с проблемой длительного обучения вашей нейронной сети, то пакетная нормализация может помочь решить вашу проблему. Интуиция и реализация пакетной нормализации были подробно объяснены в этом посте. Осталось применить его к вашей проблеме.

PS:Вот ссылка на статью об оригинальной пакетной нормализации.

Ссылка на код в github

Первоначально опубликовано на сайте www.tech-quantum.com 10 ноября 2018 г.