2015-11-14 31 views
5

Tôi quan tâm đến việc tính đạo hàm của một định thức ma trận sử dụng TensorFlow. Tôi có thể nhìn thấy từ thực nghiệm rằng TensorFlow đã không được thực hiện một phương pháp phân biệt thông qua một yếu tố quyết định:sự khác biệt định thức ma trận trong tensorflow

LookupError: No gradient defined for operation 'MatrixDeterminant' 
(op type: MatrixDeterminant) 

Một nghiên cứu thêm chút tiết lộ rằng nó thực sự có thể tính toán đạo hàm; xem ví dụ Jacobi's formula. Tôi xác định rằng để thực hiện điều này có nghĩa là phân biệt thông qua một quyết định mà tôi cần phải sử dụng các chức năng trang trí,

@tf.RegisterGradient("MatrixDeterminant") 
def _sub_grad(op, grad): 
    ... 

Tuy nhiên, tôi không đủ quen thuộc với dòng chảy tensor để hiểu làm thế nào điều này có thể được thực hiện. Có ai có bất kỳ cái nhìn sâu sắc về vấn đề này?

Dưới đây là một ví dụ mà tôi chạy vào vấn đề này:

x = tf.Variable(tf.ones(shape=[1])) 
y = tf.Variable(tf.ones(shape=[1])) 

A = tf.reshape(
    tf.pack([tf.sin(x), tf.zeros([1, ]), tf.zeros([1, ]), tf.cos(y)]), (2,2) 
) 
loss = tf.square(tf.matrix_determinant(A)) 


optimizer = tf.train.GradientDescentOptimizer(0.001) 
train = optimizer.minimize(loss) 

init = tf.initialize_all_variables() 
sess = tf.Session() 
sess.run(init) 


for step in xrange(100): 
    sess.run(train) 
    print sess.run(x) 

Trả lời

8

Vui lòng kiểm tra "Thực hiện Gradient bằng Python" phần here

Đặc biệt, bạn có thể thực hiện nó như sau

@ops.RegisterGradient("MatrixDeterminant") 
def _MatrixDeterminantGrad(op, grad): 
    """Gradient for MatrixDeterminant. Use formula from 2.2.4 from 
    An extended collection of matrix derivative results for forward and reverse 
    mode algorithmic differentiation by Mike Giles 
    -- http://eprints.maths.ox.ac.uk/1079/1/NA-08-01.pdf 
""" 
    A = op.inputs[0] 
    C = op.outputs[0] 
    Ainv = tf.matrix_inverse(A) 
    return grad*C*tf.transpose(Ainv) 

Sau đó, một vòng lặp đào tạo đơn giản để kiểm tra xem nó hoạt động:

a0 = np.array([[1,2],[3,4]]).astype(np.float32) 
a = tf.Variable(a0) 
b = tf.square(tf.matrix_determinant(a)) 
init_op = tf.initialize_all_variables() 
sess = tf.InteractiveSession() 
init_op.run() 

minimization_steps = 50 
learning_rate = 0.001 
optimizer = tf.train.GradientDescentOptimizer(learning_rate) 
train_op = optimizer.minimize(b) 

losses = [] 
for i in range(minimization_steps): 
    train_op.run() 
    losses.append(b.eval()) 

Sau đó, bạn có thể hình dung sự mất mát của bạn theo thời gian

import matplotlib.pyplot as plt 

plt.ylabel("Determinant Squared") 
plt.xlabel("Iterations") 
plt.plot(losses) 

nên nhìn thấy một cái gì đó như thế này Loss plot

+0

Rất mát mẻ! vì một lý do nào đó các tài liệu trên tf đang gây ra vấn đề. ví dụ: từ các liên kết ở trên http://tensorflow.org/how_tos/adding_an_op/index.md#AUTOGENERATED-implement-the-gradient-in-python – Blaze

+0

cố định, tài liệu được chuyển đến http://tensorflow.org/how_tos/ –

0

Tôi nghĩ rằng bạn đang bị nhầm lẫn với một dẫn xuất của một ma trận yếu tố quyết định là gì.

Yếu tố quyết định ma trận là hàm được tính toán trên các phần tử của ma trận theo một số công thức. Vì vậy, nếu tất cả các phần tử của ma trận là số, thì bạn sẽ quyết định bạn chỉ một số và đạo hàm sẽ là 0. Khi một số phần tử là các biến, bạn sẽ nhận được một biểu thức của các biến này. Ví dụ:

x, x^2 
1, sin(x) 

Các yếu tố quyết định sẽ là x*sin(x) - x^2 và đạo hàm là 2x + sin(x) + x*cos(x). Công thức Jacobi chỉ kết nối yếu tố quyết định với ma trận phụ trợ.


Trong ví dụ của bạn ma trận của bạn A gồm số duy nhất và do đó yếu tố quyết định là chỉ là một số và loss chỉ là một số là tốt. GradientDescentOptimizer cần có một số biến miễn phí để giảm thiểu và không có bất kỳ biến nào vì loss của bạn chỉ là một số.

+0

Vấn đề thực sự ở đây là MatrixDeterminant lớp không cung cấp một gradient đã đăng ký. – user1936768

+0

@ user1936768 có đây là lý do tại sao bạn nhận được lỗi trong vấn đề python của bạn, nhưng đây không phải là một lý do thực sự. Giả sử phương thức gradient tồn tại.Nó sẽ luôn trả về bạn 0 cho dù thế nào đi chăng nữa. Điều này sẽ giúp bạn trong 100 lần lặp lại của bạn? Làm thế nào chính xác nó sẽ giảm thiểu bất cứ điều gì? –

+0

Không có độ dốc sẽ không bằng 0. Tôi đang giảm thiểu đối với x và y, và ma trận phụ thuộc vào x và y thông qua sin và cos tương ứng. – user1936768

0

Đối với những người quan tâm, tôi đã khám phá ra giải pháp mà làm việc về các vấn đề của tôi:

@tf.RegisterGradient("MatrixDeterminant") 
def _MatrixDeterminant(op, grad): 
    """Gradient for MatrixDeterminant.""" 
    return op.outputs[0] * tf.transpose(tf.matrix_inverse(op.inputs[0])) 
+1

không backprop một cách chính xác nếu bạn có một cái gì đó trên đầu trang của yếu tố quyết định (ví dụ, nếu bạn giảm thiểu yếu tố quyết định bình phương) –

Các vấn đề liên quan