Я переношу свою сеть Caffe на TensorFlow, но у нее нет инициализации xavier. Я использую truncated_normal
, но это, похоже, делает его намного сложнее тренироваться.
Как сделать инициализацию Xavier на TensorFlow
Ответ 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)
В дополнение к этому, тензорный поток имеет и другие инициализаторы: