Когда масштаб значений у разных фич сильно различается, то градиент по одной оси может быть очень большой, а по другой маленький, что мешает нормальной работе градиентного спуска: по одной оси он будет спускаться слишком быстро, по другой слишком медленно. Поэтому входные значения нужно привести к стандартному разбросу. Для этого для каждого параметра считается среднее и вычитается из всех значений (так среднее приводим к 0), а так же считается стандартное отклонение и делим значения на него (так получаем стандартное отклонение в 1 для всех). Batch norm делает такую коррекцию для значений скрытого слоя (обычно его ставят до применения функции активации). При этом среднее и стандартное отклонение считают на каждом шаге для текущей группы данных (если это mini batch, то только по его значениям). Но в отличие от нормализации фичей мы не хотим приводит все значения к нулевому среднем и единичной дисперсии, поэтому мы домножаем на параметр и прибавляем сдвиг -- которые становятся тоже параметрами обучения (по сути сдвиг дублирует сдвиг на слое, поэтому обычно сдвиг на слое убирается из подбираемых параметров, остаётся только сдвиг после batch norm). Batch normalization ускоряет обучение. И при использовании с mini batch имеет небольшой регуляризирующий эффект (за счёт сдвига разных batch'ей к одному и тому же среднему).