Cách khởi tạo Xavier trên TensorFlow


Câu trả lời:


12

Trong Tensorflow 2.0 và hơn nữa, cả hai tf.contrib.*tf.get_variable()đều không được dùng nữa. Để thực hiện khởi tạo Xavier, bây giờ bạn phải chuyển sang:

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))

Đồng phục Glorot và đồng phục Xavier là hai tên gọi khác nhau của cùng một kiểu khởi tạo. Nếu bạn muốn biết thêm về cách sử dụng các khởi tạo trong TF2.0 có hoặc không có Keras, hãy tham khảo tài liệu .


Tôi đã sử dụng mã trên và gặp lỗi như bên dưới; _init_xavier = tf.Variable (init (shape = shape)) NameError: name 'shape' không được xác định
Chiranga

119

Kể từ phiên bản 0.8 có trình khởi tạo Xavier, hãy xem tài liệu tại đây .

Bạn có thể sử dụng một cái gì đó như sau:

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

3
bạn có biết làm điều này mà không cung cấp hình dạng get_variablemà thay vào đó đưa nó cho trình khởi tạo? Tôi đã từng có tf.truncated_normal(shape=[dims[l-1],dims[l]], mean=mu[l], stddev=std[l], dtype=tf.float64)và tôi đã chỉ định hình dạng ở đó nhưng bây giờ đề xuất của bạn loại vít mã của tôi lên. Bạn có đề nghị nào không?
Pinocchio

1
@Pinocchio, bạn có thể chỉ cần viết cho mình một trình bao bọc có cùng chữ ký tf.Variable(...)và cách sử dụngtf.get_variable(...)
jns

2
Liên kết "hiện tại" không có phiên bản: tensorflow.org/api_docs/python/tf/contrib/layers/…
scipilot

28

Chỉ để thêm một ví dụ khác về cách xác định một tf.Variablekhởi tạo bằng phương pháp của Xavier và 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))
    ...

Điều này đã ngăn tôi có nancác giá trị trên hàm mất mát của mình do sự không ổn định về số khi sử dụng nhiều lớp với RELU.


2
Định dạng này phù hợp nhất với mã của tôi - và nó cho phép tôi trả lại tỷ lệ học tập của mình về 0,5 (tôi đã phải giảm nó xuống 0,06 khi thêm một lớp relu'd khác). Khi tôi đã áp dụng trình khởi tạo này cho TẤT CẢ các lớp ẩn, tôi nhận được tỷ lệ xác thực cực kỳ cao ngay từ vài trăm kỷ nguyên đầu tiên. Tôi không thể tin được sự khác biệt của nó!
scipilot

12

@ Aleph7, việc khởi tạo Xavier / Glorot phụ thuộc vào số lượng kết nối đến (fan_in), số lượng kết nối đi (fan_out) và loại chức năng kích hoạt (sigmoid hoặc tanh) của nơ-ron. Xem phần này: http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf

Vì vậy, bây giờ, câu hỏi của bạn. Đây là cách tôi sẽ làm điều đó trong 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))

Lưu ý rằng chúng ta nên lấy mẫu từ phân phối đồng đều chứ không phải phân phối chuẩn như được đề xuất trong câu trả lời khác.

Tình cờ, tôi đã viết một bài đăng ngày hôm qua cho một cái gì đó khác nhau bằng cách sử dụng TensorFlow mà tình cờ cũng sử dụng khởi tạo Xavier. Nếu bạn quan tâm, cũng có một sổ ghi chép python với ví dụ end-to-end: https://github.com/delip/blog-stuff/blob/master/tensorflow_ufp.ipynb


1
Làm thế nào chúng ta có thể sử dụng nó với chức năng kích hoạt relu.
gautam840 14/09/2016

Bài báo đó nghiên cứu hành vi của các gradient trọng lượng trong các chức năng kích hoạt khác nhau với cách khởi tạo thường được sử dụng. Sau đó, họ đề xuất một khởi tạo phổ quát bất kể chức năng kích hoạt nào. Hơn nữa, phương pháp của bạn cũng không phụ thuộc vào chức năng kích hoạt, vì vậy tốt hơn nên sử dụng khởi tạo Xavier được tích hợp sẵn trong Tensorflow.
Vahid Mirjalili

8

Một trình bao bọc tốt đẹp xung quanh tensorflowđược gọi prettytensorcung cấp một triển khai trong mã nguồn (được sao chép trực tiếp từ đây ):

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 có xavier_initializer. Đây là một ví dụ về cách sử dụng nó:

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)

Ngoài điều này, tensorflow có các trình khởi tạo khác:


cảm ơn, thưa ông này là rất hữu ích, tôi muốn hỏi bạn nếu tôi có thể khởi tạo xu hướng sử dụng xavier_initializer
Sakhri Houssem

4

Tôi đã xem xét và không tìm thấy bất cứ thứ gì được tích hợp sẵn. Tuy nhiên, theo như sau:

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

Khởi tạo Xavier chỉ là lấy mẫu một phân phối (thường là Gaussian) trong đó phương sai là một hàm của số lượng tế bào thần kinh. tf.random_normalcó thể làm điều đó cho bạn, bạn chỉ cần tính toán stddev (tức là số lượng tế bào thần kinh được đại diện bởi ma trận trọng số mà bạn đang cố gắng khởi tạo).


Vì bạn nên lấy mẫu từ một phân phối đồng đều.
Delip


3

Chỉ trong trường hợp bạn muốn sử dụng một dòng như bạn làm với:

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

Bạn có thể làm:

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

0

Dòng chảy 1:

W1 = tf.get_variable("W1", [25, 12288],
    initializer = tf.contrib.layers.xavier_initializer(seed=1)

Dòng chảy 2:

W1 = tf.get_variable("W1", [25, 12288],
    initializer = tf.random_normal_initializer(seed=1))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.