วิธีการเริ่มต้น Xavier บน TensorFlow


86

ฉันกำลังย้ายเครือข่าย Caffe ของฉันไปที่ TensorFlow แต่ดูเหมือนว่าจะไม่มีการเริ่มต้น xavier ฉันกำลังใช้truncated_normalแต่ดูเหมือนว่าจะทำให้การฝึกยากขึ้นมาก


2
Xavier เป็นค่าเริ่มต้นเริ่มต้น ดูstackoverflow.com/questions/37350131/…
Thomas Ahle

คำตอบ:


12

ใน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 อ้างถึงเอกสาร


ฉันใช้รหัสด้านบนและได้รับข้อผิดพลาดดังต่อไปนี้ _init_xavier = tf.Variable (init (shape = shape)) NameError: ไม่ได้กำหนดชื่อ 'รูปร่าง'
Chiranga

119

เนื่องจากเวอร์ชัน 0.8 มี Xavier initializer โปรดดูเอกสารที่นี่

คุณสามารถใช้สิ่งนี้:

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

3
คุณรู้หรือไม่ว่าจะทำสิ่งนี้โดยไม่ให้รูปร่างget_variableแต่มอบให้กับ initializer แทน? ฉันเคยมีtf.truncated_normal(shape=[dims[l-1],dims[l]], mean=mu[l], stddev=std[l], dtype=tf.float64)และฉันระบุรูปร่างที่นั่น แต่ตอนนี้คำแนะนำของคุณประเภทของสกรูรหัสของฉันขึ้น คุณมีข้อเสนอแนะใด?
Pinocchio

1
@Pinocchio คุณสามารถเขียนกระดาษห่อตัวเองซึ่งมีลายเซ็นเดียวกับtf.Variable(...)และใช้งานได้tf.get_variable(...)
jns

2
ลิงก์ "ปัจจุบัน" ที่ไม่มีเวอร์ชัน: tensorflow.org/api_docs/python/tf/contrib/layers/…
scipilot

28

เพียงเพื่อเพิ่มอีกตัวอย่างเกี่ยวกับการกำหนด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


2
รูปแบบนี้เหมาะกับรหัสของฉันมากที่สุด - และอนุญาตให้ฉันคืนอัตราการเรียนรู้เป็น 0.5 (ฉันต้องลดลงเหลือ 0.06 เมื่อเพิ่มเลเยอร์ relu'd อื่น) เมื่อฉันใช้ตัวเริ่มต้นนี้กับทุกเลเยอร์ที่ซ่อนอยู่ฉันจะได้รับอัตราการตรวจสอบความถูกต้องสูงอย่างไม่น่าเชื่อตั้งแต่สองสามร้อยยุคแรก ไม่อยากจะเชื่อเลยว่ามันสร้างความแตกต่างได้!
scipilot

12

การเริ่มต้น @ 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


1
เราจะใช้มันกับฟังก์ชั่นการเปิดใช้งาน relu ได้อย่างไร
gautam840

บทความนี้ศึกษาพฤติกรรมของการไล่ระดับน้ำหนักภายใต้ฟังก์ชันการเปิดใช้งานที่แตกต่างกันด้วยการเริ่มต้นที่ใช้กันทั่วไป จากนั้นจึงเสนอการเริ่มต้นสากลโดยไม่คำนึงถึงฟังก์ชันการเปิดใช้งานใด ๆ นอกจากนี้วิธีการของคุณยังไม่ขึ้นอยู่กับฟังก์ชันการเปิดใช้งานด้วยดังนั้นจึงควรใช้การเริ่มต้น Xavier ในตัวใน Tensorflow
Vahid Mirjalili

8

เสื้อคลุมที่ดีรอบ ๆ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)

8

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)

นอกจากนี้เทนเซอร์โฟลว์ยังมีตัวเริ่มต้นอื่น ๆ :


ขอบคุณครับสิ่งนี้มีประโยชน์มากฉันต้องการถามคุณว่าฉันสามารถเริ่มต้นอคติโดยใช้ xavier_initializer
Sakhri Houssem

4

ฉันมองแล้วไม่พบสิ่งใดในตัวอย่างไรก็ตามตามนี้:

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

การเริ่มต้น Xavier เป็นเพียงการสุ่มตัวอย่างการแจกแจง (โดยปกติจะเป็น Gaussian) โดยที่ความแปรปรวนเป็นฟังก์ชันของจำนวนเซลล์ประสาท tf.random_normalสามารถทำได้สำหรับคุณคุณเพียงแค่ต้องคำนวณ stddev (เช่นจำนวนเซลล์ประสาทที่แสดงด้วยเมทริกซ์น้ำหนักที่คุณกำลังพยายามเริ่มต้น)


วินซ์คุณควรสุ่มตัวอย่างจากการแจกแจงแบบสม่ำเสมอ
ส่งของ

4

ผ่าน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

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


3

ในกรณีที่คุณต้องการใช้บรรทัดเดียวเช่นเดียวกับ:

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

คุณทำได้:

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

0

เทนเซอร์โฟลว์ 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))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.