Я переношу свою сеть Caffe на TensorFlow, но, похоже, у нее нет инициализации xavier. Я использую, truncated_normal
но похоже, что это затрудняет тренировку.
python
tensorflow
Алехандро
источник
источник
Ответы:
В Tensorflow 2.0 и последующих версиях оба
tf.contrib.*
иtf.get_variable()
устарели. Теперь, чтобы выполнить инициализацию Xavier, вам нужно переключиться на:init = tf.initializers.GlorotUniform() var = tf.Variable(init(shape=shape)) # or a oneliner with a little confusing brackets var = tf.Variable(tf.initializers.GlorotUniform()(shape=shape))
Форма Glorot и форма Xavier - это два разных имени одного и того же типа инициализации. Если вы хотите узнать больше о том, как использовать инициализации в TF2.0 с или без Keras, обратитесь к документации .
источник
Начиная с версии 0.8 существует инициализатор Xavier, см. Здесь документы .
Вы можете использовать что-то вроде этого:
W = tf.get_variable("W", shape=[784, 256], initializer=tf.contrib.layers.xavier_initializer())
источник
get_variable
а вместо этого передавая ее инициализатору? Раньше уtf.truncated_normal(shape=[dims[l-1],dims[l]], mean=mu[l], stddev=std[l], dtype=tf.float64)
меня была форма , и я указывал здесь форму, но теперь ваше предложение как бы портит мой код. У вас есть какие-нибудь предложения?tf.Variable(...)
и использоватьtf.get_variable(...)
Просто чтобы добавить еще один пример того, как определить
tf.Variable
инициализированный с помощью метода Ксавьера и Йошуа :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
значения в моей функции потерь из-за численной нестабильности при использовании нескольких слоев с RELU.источник
@ Aleph7, инициализация 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
источник
Хорошая обертка вокруг
tensorflow
namedprettytensor
дает реализацию в исходном коде (скопированном прямо отсюда ):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)
В дополнение к этому у tenorflow есть другие инициализаторы:
источник
Я посмотрел и не нашел ничего встроенного. Однако, согласно этому:
http://andyljones.tumblr.com/post/110998971763/an-explanation-of-xavier-initialization
Инициализация Xavier - это просто выборка распределения (обычно гауссова), где дисперсия является функцией количества нейронов.
tf.random_normal
может сделать это за вас, вам просто нужно вычислить stddev (то есть количество нейронов, представленных весовой матрицей, которую вы пытаетесь инициализировать).источник
Через
kernel_initializer
параметр в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))
Ты можешь сделать:
источник
Tensorflow 1:
W1 = tf.get_variable("W1", [25, 12288], initializer = tf.contrib.layers.xavier_initializer(seed=1)
Tensorflow 2:
W1 = tf.get_variable("W1", [25, 12288], initializer = tf.random_normal_initializer(seed=1))
источник