Подтвердить что ты не робот

Как сделать инициализацию Xavier на TensorFlow

Я переношу свою сеть Caffe на TensorFlow, но у нее нет инициализации xavier. Я использую truncated_normal, но это, похоже, делает его намного сложнее тренироваться.

4b9b3361

Ответ 1

Начиная с версии 0.8 есть инициализатор Xavier, см. здесь для документов.

Вы можете использовать что-то вроде этого:

W = tf.get_variable("W", shape=[784, 256],
           initializer=tf.contrib.layers.xavier_initializer())

Ответ 2

@Алеф7, инициализация Xavier/Glorot зависит от количества входящих соединений (fan_in), количества исходящих соединений (fan_out) и вида функции активации (сигмоида или tanh) нейрона. Смотрите это: http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf

Так что теперь, на ваш вопрос. Вот как я сделал бы это в TensorFlow:

(fan_in, fan_out) = ...
    low = -4*np.sqrt(6.0/(fan_in + fan_out)) # use 4 for sigmoid, 1 for tanh activation 
    high = 4*np.sqrt(6.0/(fan_in + fan_out))
    return tf.Variable(tf.random_uniform(shape, minval=low, maxval=high, dtype=tf.float32))

Обратите внимание, что мы должны быть выборкой из равномерного распределения, а не нормального распределения, как предложено в другом ответе.

Кстати, я написал вчера сообщение для чего-то другого, используя TensorFlow, который также использует инициализацию Xavier. Если вам интересно, есть также ноутбук python со сквозным примером: https://github.com/delip/blog-stuff/blob/master/tensorflow_ufp.ipynb

Ответ 3

Просто добавьте еще один пример того, как определить инициализацию tf.Variable, используя метод Xavier и Yoshua:

graph = tf.Graph()
with graph.as_default():
    ...
    initializer = tf.contrib.layers.xavier_initializer()
    w1 = tf.Variable(initializer(w1_shape))
    b1 = tf.Varialbe(initializer(b1_shape))
    ...

Это помешало мне иметь nan значения в моей функции потерь из-за числовых неустойчивостей при использовании нескольких слоев с помощью RELUs.

Ответ 4

Хорошая обертка вокруг tensorflow, называемая prettytensor, дает реализацию в исходном коде (скопирована непосредственно из здесь):

def xavier_init(n_inputs, n_outputs, uniform=True):
  """Set the parameter initialization using the method described.
  This method is designed to keep the scale of the gradients roughly the same
  in all layers.
  Xavier Glorot and Yoshua Bengio (2010):
           Understanding the difficulty of training deep feedforward neural
           networks. International conference on artificial intelligence and
           statistics.
  Args:
    n_inputs: The number of input nodes into each output.
    n_outputs: The number of output nodes for each input.
    uniform: If true use a uniform distribution, otherwise use a normal.
  Returns:
    An initializer.
  """
  if uniform:
    # 6 was used in the paper.
    init_range = math.sqrt(6.0 / (n_inputs + n_outputs))
    return tf.random_uniform_initializer(-init_range, init_range)
  else:
    # 3 gives us approximately the same limits as above since this repicks
    # values greater than 2 standard deviations from the mean.
    stddev = math.sqrt(3.0 / (n_inputs + n_outputs))
    return tf.truncated_normal_initializer(stddev=stddev)

Ответ 5

Я посмотрел, и я не смог найти ничего встроенного. Однако, в соответствии с этим:

http://andyljones.tumblr.com/post/110998971763/an-explanation-of-xavier-initialization

Инициализация Xavier - это просто выборка a (обычно гауссовского) распределения, где дисперсия является функцией числа нейронов. tf.random_normal может сделать это для вас, вам просто нужно вычислить stddev (т.е. количество нейронов, представленных матрицей веса, которую вы пытаетесь инициализировать).

Ответ 6

TF-contrib имеет xavier_initializer. Вот пример того, как его использовать:

import tensorflow as tf
a = tf.get_variable("a", shape=[4, 4], initializer=tf.contrib.layers.xavier_initializer())
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print sess.run(a)

В дополнение к этому, тензорный поток имеет и другие инициализаторы: