Tôi đang chuyển mạng Caffe của mình sang TensorFlow nhưng dường như nó không có khởi chạy xavier. Tôi đang sử dụng truncated_normal
nhưng điều này dường như làm cho nó khó đào tạo hơn rất nhiều.
Câu trả lời:
Trong Tensorflow 2.0 và hơn nữa, cả hai tf.contrib.*
và 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 .
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())
get_variable
mà 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?
tf.Variable(...)
và cách sử dụngtf.get_variable(...)
Chỉ để thêm một ví dụ khác về cách xác định một tf.Variable
khở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ó nan
cá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.
@ 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
Một trình bao bọc tốt đẹp xung quanh tensorflow
được gọi prettytensor
cung 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)
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:
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_normal
có 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).
Qua kernel_initializer
tham số tới tf.layers.conv2d, tf.layers.conv2d_transpose, tf.layers.Dense
vv
ví dụ
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
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)))