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



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

636   8  

8 ответов:

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

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

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

просто добавить еще один пример о том, как определить tf.Variable инициализирована с помощью Ксавье и Yoshua's метод:

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

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

@Aleph7, инициализация Xavier/Glorot зависит от количества входящих соединений (fan_in), количества исходящих соединений (fan_out) и вида функции активации (sigmoid или 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

хорошая обертка вокруг 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)

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)

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

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

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

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

через до tf.layers.conv2d, tf.layers.conv2d_transpose, tf.layers.Dense etc

например

layer = tf.layers.conv2d(
     input, 128, 5, strides=2,padding='SAME',
     kernel_initializer=tf.contrib.layers.xavier_initializer())

https://www.tensorflow.org/api_docs/python/tf/layers/conv2d

https://www.tensorflow.org/api_docs/python/tf/layers/conv2d_transpose

https://www.tensorflow.org/api_docs/python/tf/layers/Dense

на всякий случай вы хотите использовать одну строку, как вы делаете с:

W = tf.Variable(tf.truncated_normal((n_prev, n), stddev=0.1))

Вы можете сделать:

W = tf.Variable(tf.contrib.layers.xavier_initializer()((n_prev, n)))

Comments

    Ничего не найдено.