Проблема с пакетной нормализацией в тензорном потоке - PullRequest
0 голосов
/ 10 ноября 2018

У меня проблемы с пониманием реализации нормализации партии в Tensorflow. Чтобы проиллюстрировать это, я создал простую сеть с одним входным узлом, одним скрытым узлом и одним выходным узлом и запускаю с 1 пакетом с размером пакета 2. Мой вход x состоит из скаляра с 2 значениями (то есть размером пакета) из 2), один установлен на 0, а другой на 1.

Я бегу в течение одной эпохи и записываю выходные данные из скрытого слоя (до и после нормализации партии), а также скользящее среднее значение нормы партии, дисперсию, гамму и бета.

Вот мой код:

import tensorflow as tf

import numpy as np

N_HIDDEN_1 = 1
N_INPUT= 1
N_OUTPUT = 1

###########################################################

# DEFINE THE Network

# Define placeholders for data that will be fed in during execution
x = tf.placeholder(tf.float32, (None, N_INPUT))
y = tf.placeholder(tf.float32, (None, N_OUTPUT))
lx = tf.placeholder(tf.float32, [])
training = tf.placeholder_with_default(False, shape=(), name='training')

# Hidden layers with relu activation
with tf.variable_scope('hidden1'):
      hidden_1 = tf.layers.dense(x, N_HIDDEN_1, activation=None, use_bias=False)
      bn_1 = tf.layers.batch_normalization(hidden_1, training=training, momentum=0.5)
      bn_1x = tf.nn.relu(bn_1)

# Output layer
with tf.variable_scope('output'):
      predx = tf.layers.dense(bn_1x, N_OUTPUT, activation=None, use_bias=False)
      pred = tf.layers.batch_normalization(predx, training=training, momentum=0.5)

###########################################################

# Define the cost function that is optimized when
# training the network and the optimizer

cost = tf.reduce_mean(tf.square(pred-y))

optimizer = tf.train.AdamOptimizer(learning_rate=lx).minimize(cost)

bout1 = tf.global_variables('hidden1/batch_normalization/moving_mean:0')
bout2 = tf.global_variables('hidden1/batch_normalization/moving_variance:0')
bout3 = tf.global_variables('hidden1/batch_normalization/gamma:0')
bout4 = tf.global_variables('hidden1/batch_normalization/beta:0')

###########################################################

# Train network

init = tf.global_variables_initializer()
extra_update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)

with tf.Session() as sess:

    sess.run(init)

    # Create dummy data
    batchx = np.zeros((2,1))
    batchy = np.zeros((2,1))
    batchx[0,0]=0.0
    batchx[1,0]=1.0
    batchy[0,0]=3.0
    batchy[1,0]=4.0

    _,_ = sess.run([optimizer, extra_update_ops], feed_dict={training: True, x:batchx, y:batchy, lx: 0.001})

    print('weight of hidden layer')
    W1 = np.array(sess.run(tf.global_variables('hidden1/dense/kernel:0')))
    W1x = np.sum(W1, axis=1)
    print(W1x)

    print()
    print('output from hidden layer, batch norm layer, and relu layer')
    hid1,b1,b1x = sess.run([hidden_1, bn_1, bn_1x], feed_dict={training: False, x:batchx})
    print('hidden_1', hid1)
    print('bn_1', b1)
    print('bn_1x', b1x)

    print()
    print('batchnorm parameters')
    print('moving mean', sess.run(bout1))
    print('moving variance', sess.run(bout2))
    print('gamma', sess.run(bout3))
    print('beta', sess.run(bout4))

Вот вывод, который я получаю, когда запускаю код:

weight of hidden layer [[1.404974]]

output from hidden layer, batch norm layer, and relu layer
hidden_1 [[0.      ]
          [1.404974]]

bn_1 [[-0.40697935]
      [ 1.215785  ]]

bn_1x [[0.      ]
      [1.215785]]

batchnorm parameters
moving mean [array([0.3514931], dtype=float32)]
moving variance [array([0.74709475], dtype=float32)]
gamma [array([0.999], dtype=float32)]
beta [array([-0.001], dtype=float32)]

Я озадачен результирующими параметрами батчнорм. В данном конкретном случае вывод из скрытого слоя до применения пакетной нормы скаляры 0 и 1.404974. Но скользящее среднее значение параметра нормы партии составляет 0,3514931. Это для случая, когда я использую импульс = 0,5. Мне не ясно, почему в этом случае скользящее среднее после 1 итерации не является точно средним значением 0 и 1,404974. У меня сложилось впечатление, что параметр импульса будет срабатывать только со второй партии.

Любая помощь будет высоко ценится.

1 Ответ

0 голосов
/ 10 ноября 2018

Поскольку вы запустили оптимизатор, трудно понять, что на самом деле происходит внутри: печатаемые вами значения hidden_1 не являются теми, которые использовались для обновления статистики пакетных норм;это значения после обновления.

В любом случае, я не вижу проблемы:

Moving mean original value = 0.0
batch mean value = (1.404974 - 0.0) / 2.0 = ~0.7
Moving mean value = momentum * Moving mean original value + (1 - momentum) * batch mean value
                  = 0.0 * 0.5 + (1 - 0.5) * 0.7
                  = 0.35

Moving variance original value = 1.0
batch variance value = ~0.5
Moving variance value = momentum * Moving variance original value + (1 - momentum) * batch variance value
                  = 1.0 * 0.5 + (1.0 - 0.5) * 0.5
                  = 0.75
...