2015-11-14 9 views
5

Ich interessiere mich für die Berechnung der Ableitung einer Matrix Determinante mit TensorFlow. I kann von Experimenten, dass TensorFlow ein Verfahren zum Differenzieren durch eine Determinante nicht umgesetzt hat:Matrix-Determinant-Differenzierung im Tensorflow

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

Etwas weiter Untersuchung ergab, dass es tatsächlich möglich ist, die Ableitung zu berechnen; siehe zum Beispiel Jacobi's formula. Ich festgestellt, dass, um dies zu implementieren bedeutet durch eine Determinante der Unterscheidung, die ich brauche die Funktion Dekorateur zu verwenden,

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

Aber ich bin nicht vertraut genug mit Tensor Fluss zu verstehen, wie dies erreicht werden kann. Hat jemand einen Einblick in diese Angelegenheit?

Hier ist ein Beispiel, wo ich in dieser Frage führen:

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) 

Antwort

8

Bitte überprüfen „Implementieren Gradient in Python“ Abschnitt here

Insbesondere können Sie es wie folgt implementieren

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

Dann eine einfache Ausbildung Schleife zu überprüfen, ob es funktioniert:

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

Dann können Sie Ihren Verlust im Laufe der Zeit

import matplotlib.pyplot as plt 

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

so etwas wie dieses hier Loss plot

+0

Sehr cool! Aus irgendeinem Grund verursachen die Dokumente auf tf Probleme. zB: von den Links oben http://tensorflow.org/how_tos/adding_an_op/index.md#AUTOGENERATED-implement-the-gradient-in-python – Blaze

+0

fixiert ist, bewegt docs zu http://tensorflow.org/how_tos/ –

0

Ich glaube, Sie mit verwirrt, was ist ein Derivat einer Matrix Determinante.

Matrix Determinante ist eine Funktion, die über die Elemente der Matrix durch eine Formel berechnet wird. Wenn also alle Elemente der Matrix Zahlen sind, werden Sie die Determinante nur eine Zahl haben und die Ableitung wird 0 sein. Wenn einige der Elemente Variablen sind, erhalten Sie einen Ausdruck dieser Variablen. Zum Beispiel:

x, x^2 
1, sin(x) 

Die Determinante wird x*sin(x) - x^2 sein und das Derivat 2x + sin(x) + x*cos(x). Die Jacobi-Formel verbindet nur die Determinante mit der Adjunct-Matrix.


In Ihrem Beispiel Ihre Matrix A besteht nur aus Zahlen und damit die Determinante ist nur eine Zahl und die loss ist nur so gut Nummer. GradientDescentOptimizer benötigt einige freie Variablen zu minimieren und hat keine, weil Ihre loss nur eine Zahl ist.

+0

Das eigentliche Problem ist, sollte sehen visualisieren, dass MatrixDeterminant Klasse bietet keine registrierten Gradienten. – user1936768

+0

@ user1936768 ja dies ist ein Grund, warum Sie den Fehler in Ihrem Python-Problem haben, aber das ist kein wirklicher Grund. Angenommen, die Gradientenmethode existiert.Es wird dir immer 0 zurückgeben, egal was passiert. Wird dies in Ihren 100 Iterationen helfen? Wie genau wird es etwas minimieren? –

+0

Nein, der Farbverlauf ist nicht Null. Ich minimiere in Bezug auf x und y, und die Matrix hängt von x und y durch sin bzw. cos ab. – user1936768

0

Für diejenigen, die interessiert sind, entdeckte ich die Lösung, die auf meine Probleme funktioniert:

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

, die nicht korrekt rückpropagiert, wenn Sie etwas über Determinante haben (dh wenn Sie Determinante im Quadrat minimieren) –