Как нормализовать все оси с помощью пакетной нормализации?

#python #tensorflow #batch-normalization

#python #тензорный поток #пакетная нормализация

Вопрос:

Насколько я понимаю, для tf.layers.batch_normalization оси, которую я определяю, это ось, которая нормализуется.

Проще говоря:

Учитывая эти значения

 a = [[0, 2], 
     [1, 4]]
  

с помощью формы (2, 2) и, следовательно, оси 0 и 1.

Нормализация по оси 1 означала бы уменьшить ось 0 до ее среднего и стандартного отклонения, а затем принять эти значения для нормализации.

Поэтому

 bn = tf.layers.batch_normalization(a, axis=[1])
  

будет иметь (почти) тот же результат, что и

 m, v = tf.nn.moments(a, axes=[0])
bn = (a - m) / tf.sqrt(v)
  

Но как бы я поступил tf.layers.batch_normalization для всех осей?

С вычислением среднего и стандартного отклонения от предыдущего, это было бы легко:

 m, v = tf.nn.moments(a, axes=[0, 1])
bn = (a - m) / tf.sqrt(v)
  

Но как это сделать с помощью пакетной нормализации?

 bn = tf.layers.batch_normalization(a, axis=[???])
  

Я попробовал следующее, что не работает:

  • axis = None : AttributeError: 'BatchNormalization' object has no attribute 'axis'
  • axis = [] : IndexError: list index out of range
  • axis = [0, 1] : Все результаты равны нулю

Комментарии:

1. В чем польза / преимущество такой пакетной нормализации? Разве нормализация не должна быть в первую очередь вдоль оси объектов?

2. @NihalSangeeth Вы можете нормализовать каждую ось, которая вам нужна. Все зависит от того, как выглядят ваши данные и что они представляют. Да, обычно нормализуется по оси объектов, но это не исключает нормализации по любому другому измерению.

Ответ №1:

К сожалению, я не думаю, что это возможно с использованием batch_normalization слоев / функций API tensorflow.

Как следует из названия функции, она предназначена для выполнения «пакетной» нормализации, поэтому ожидается, что она будет нормализована по оси объектов с учетом текущего пакета (обычно размерности 0).

Комментарии:

1. Возможно, вы правы, что реализация не допускает нормализации по всем осям. Но вторая часть вашего ответа неверна. Пакетная нормализация означает только то, что среднее значение, std, а также бета и gama вычисляются по пакетам. Это не имеет ничего общего с самим процессом нормализации. Он также не предопределяет какую-либо ось. Да, обычно нормализуется по оси объектов (которая обычно равна -1 или 1; ось 0 — это пакетная ось). Но это не означает, что другие варианты использования не выполняют пакетную нормализацию по другой оси.

Ответ №2:

Это может быть достигнуто с помощью нормализации слоев:

 >>> data = tf.constant(np.arange(10).reshape(5, 2) * 10, dtype=tf.float32)
    layer = tf.keras.layers.LayerNormalization(axis=[0, 1])
    output = layer(data)
    print(output)

tf.Tensor(
[[-1.5666981  -1.2185429 ]
 [-0.8703878  -0.5222327 ]
 [-0.17407757  0.17407756]
 [ 0.52223265  0.8703878 ]
 [ 1.2185429   1.5666981 ]], shape=(5, 2), dtype=float32)
  

Разница с пакетной нормализацией заключается в том, что нормализация уровня применяет операцию к каждой единице в пакете отдельно.

Если вы хотите выполнить эту операцию над пакетом, перейдите к пакетной норме. Аналогично это работает, устанавливая axis в виде списка.