Caffe ağımı TensorFlow üzerinden taşıyorum, ancak xavier başlatmaya sahip görünmüyor. Kullanıyorum truncated_normal
ama bu, eğitmeyi çok daha zorlaştırıyor gibi görünüyor.
Yanıtlar:
Gelen Tensorflow 2.0 ve daha fazla hem tf.contrib.*
ve tf.get_variable()
önerilmemektedir. Xavier başlatmayı yapmak için şimdi şuna geçmelisiniz:
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 üniforma ve Xavier üniforma, aynı başlatma türünün iki farklı adıdır. TF2.0'da Keras ile veya Keras olmadan ilklendirmelerin nasıl kullanılacağı hakkında daha fazla bilgi edinmek isterseniz belgelere bakın .
0.8 sürümünden beri bir Xavier başlatıcı var, dokümanlar için buraya bakın .
Bunun gibi bir şey kullanabilirsiniz:
W = tf.get_variable("W", shape=[784, 256],
initializer=tf.contrib.layers.xavier_initializer())
get_variable
bunun yerine başlatıcıya vermeyi biliyor musunuz ? Eskiden tf.truncated_normal(shape=[dims[l-1],dims[l]], mean=mu[l], stddev=std[l], dtype=tf.float64)
vardı ve şekli orada belirledim ama şimdi öneriniz kodumu mahvediyor. Önerin var mı?
tf.Variable(...)
ve kullanan bir sarmalayıcı yazabilirsiniztf.get_variable(...)
Sadece Xavier ve Yoshua'nın yöntemini tf.Variable
kullanarak başlatılmış bir tanımlamanın nasıl tanımlanacağına dair başka bir örnek eklemek için :
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))
...
Bu nan
, RELU'larla birden çok katman kullanırken sayısal dengesizlikler nedeniyle kayıp fonksiyonumda değerlere sahip olmamı engelledi.
@ Aleph7, Xavier / Glorot başlatma, nöronun gelen bağlantıların sayısına (fan_in), giden bağlantıların sayısına (fan_out) ve nöronun aktivasyon fonksiyonunun türüne (sigmoid veya tanh) bağlıdır. Şuna bakın: http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf
Öyleyse şimdi sorunuza gelelim. TensorFlow'da bunu şu şekilde yapardım:
(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))
Diğer cevapta önerildiği gibi normal dağılımdan değil, tekdüze bir dağılımdan örnekleme yapmamız gerektiğini unutmayın.
Bu arada bir yazdım dün , Xavier başlatmayı da kullanan TensorFlow kullanarak farklı bir şey için gönderi . İlgileniyorsanız, uçtan uca örnek içeren bir python not defteri de var: https://github.com/delip/blog-stuff/blob/master/tensorflow_ufp.ipynb
tensorflow
Çağrılan güzel bir sarmalayıcı prettytensor
, kaynak kodda bir uygulama sağlar (doğrudan buradan kopyalanır ):
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-katkıda bulunur xavier_initializer
. İşte nasıl kullanılacağına bir örnek:
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)
Buna ek olarak, tensorflow'un başka başlatıcıları da vardır:
Baktım ve yerleşik bir şey bulamadım. Ancak buna göre:
http://andyljones.tumblr.com/post/110998971763/an-explanation-of-xavier-initialization
Xavier başlatma, varyansın nöron sayısının bir fonksiyonu olduğu bir (genellikle Gaussian) dağılımını örneklemektir. tf.random_normal
bunu sizin için yapabilir, sadece stddev'i hesaplamanız gerekir (yani, başlatmaya çalıştığınız ağırlık matrisi ile temsil edilen nöron sayısı).
Via kernel_initializer
için parametretf.layers.conv2d, tf.layers.conv2d_transpose, tf.layers.Dense
vb
Örneğin
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