ฉันกำลังย้ายเครือข่าย Caffe ของฉันไปที่ TensorFlow แต่ดูเหมือนว่าจะไม่มีการเริ่มต้น xavier ฉันกำลังใช้truncated_normal
แต่ดูเหมือนว่าจะทำให้การฝึกยากขึ้นมาก
ฉันกำลังย้ายเครือข่าย Caffe ของฉันไปที่ TensorFlow แต่ดูเหมือนว่าจะไม่มีการเริ่มต้น xavier ฉันกำลังใช้truncated_normal
แต่ดูเหมือนว่าจะทำให้การฝึกยากขึ้นมาก
คำตอบ:
ใน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 เป็นชื่อที่แตกต่างกันสองชื่อในประเภทการเริ่มต้นเดียวกัน หากคุณต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับวิธีการใช้ initializations ใน TF2.0 มีหรือไม่มี Keras อ้างถึงเอกสาร
เนื่องจากเวอร์ชัน 0.8 มี Xavier initializer โปรดดูเอกสารที่นี่
คุณสามารถใช้สิ่งนี้:
W = tf.get_variable("W", shape=[784, 256],
initializer=tf.contrib.layers.xavier_initializer())
get_variable
แต่มอบให้กับ initializer แทน? ฉันเคยมี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
ค่าเริ่มต้นโดยใช้วิธีของXavier และ Yoshua :
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) และชนิดของฟังก์ชันการกระตุ้น (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 พร้อมตัวอย่าง end-to-end: 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)
นอกจากนี้เทนเซอร์โฟลว์ยังมีตัวเริ่มต้นอื่น ๆ :
ฉันมองแล้วไม่พบสิ่งใดในตัวอย่างไรก็ตามตามนี้:
http://andyljones.tumblr.com/post/110998971763/an-explanation-of-xavier-initialization
การเริ่มต้น Xavier เป็นเพียงการสุ่มตัวอย่างการแจกแจง (โดยปกติจะเป็น Gaussian) โดยที่ความแปรปรวนเป็นฟังก์ชันของจำนวนเซลล์ประสาท tf.random_normal
สามารถทำได้สำหรับคุณคุณเพียงแค่ต้องคำนวณ stddev (เช่นจำนวนเซลล์ประสาทที่แสดงด้วยเมทริกซ์น้ำหนักที่คุณกำลังพยายามเริ่มต้น)
ผ่านkernel_initializer
พารามิเตอร์ไปยังtf.layers.conv2d, tf.layers.conv2d_transpose, tf.layers.Dense
ฯลฯ
เช่น
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
ในกรณีที่คุณต้องการใช้บรรทัดเดียวเช่นเดียวกับ:
W = tf.Variable(tf.truncated_normal((n_prev, n), stddev=0.1))
คุณทำได้:
W = tf.Variable(tf.contrib.layers.xavier_initializer()((n_prev, n)))
เทนเซอร์โฟลว์ 1:
W1 = tf.get_variable("W1", [25, 12288],
initializer = tf.contrib.layers.xavier_initializer(seed=1)
เทนเซอร์โฟลว์ 2:
W1 = tf.get_variable("W1", [25, 12288],
initializer = tf.random_normal_initializer(seed=1))