Meine Kostenfunktion beinhaltet die Berechnung von log (det (A)) (vorausgesetzt, det (A) ist positiv, so dass das Protokoll sinnvoll ist, aber A ist nicht Hermiteschen so die Cholesky-Zerlegung ist hier nicht anwendbar). Wenn det (A) sehr groß/klein ist, wird ein direkter Aufruf von det (A) überlaufen/unterlaufen. Um dies zu umgehen, verwenden Sie eine die mathematische Tatsache, dassBerechne Log der Determinante in TensorFlow, wenn Determinante Überlauf/Unterlauf
log (det (A)) = Tr (log (A)),
, wo die später ausgewertet werden können LU-Zerlegung verwendet (was effizienter als Eigenwert/SVD). Dieser Algorithmus wurde in numpy als numpy.linalg.slogdet implementiert. Das Problem besteht also darin, wie numpy von TensorFlow aufgerufen wird.
Hier ist, was ich versuchte
import numpy as np
import tensorflow as tf
from tensorflow.python.framework import function
def logdet_np(a):
_, l = np.linalg.slogdet(a)
return l
def logdet1(a):
return tf.py_func(logdet_np, [a], tf.float64)
@function.Defun(tf.float64, func_name='LogDet')
def logdet2(a):
return tf.py_func(logdet_np, [a], tf.float64)
with tf.Session() as sess:
a = tf.constant(np.eye(500)*10.)
#print(sess.run(logdet1(a)))
print(sess.run(logdet2(a)))
ich zum ersten Mal einer Python-Funktion definiert das numpy Ergebnis heraus zu führen. Dann habe ich zwei logdet
Funktionen unter Verwendung tf.py_func
definiert. Die zweite Funktion ist mit function.Defun
dekoriert, die später verwendet wird, um TensorFlow-Funktionen und ihre Gradienten zu definieren. Als ich sie prüfte, fand ich, dass die erste Funktion logdet1
funktioniert und das korrekte Ergebnis gibt. Aber die zweite Funktion logdet2
gibt einen KeyError zurück.
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-
packages/tensorflow/python/ops/script_ops.py in __call__(self, token, args)
77 def __call__(self, token, args):
78 """Calls the registered function for `token` with args."""
---> 79 func = self._funcs[token]
80 if func is None:
81 raise ValueError("callback %s is not found" % token)
KeyError: 'pyfunc_0'
Meine Frage ist, was mit dem Defun
Dekorateur falsch ist? Warum steht es im Widerspruch zu py_func
? Wie kann ich numpy Funktionen in TensorFlor richtig einwickeln?
Der verbleibende Teil wird der Gradient für logdet
des Definierens matrix determinant differentiation in tensorflow auf die Frage im Zusammenhang. Gemäß der Lösung in dieser Frage versucht man
@function.Defun(tf.float64, tf.float64, func_name='LogDet_Gradient')
def logdet_grad(a, grad):
a_adj_inv = tf.matrix_inverse(a, adjoint=True)
out_shape = tf.concat([tf.shape(a)[:-2], [1, 1]], axis=0)
return tf.reshape(grad, out_shape) * a_adj_inv
@function.Defun(tf.float64, func_name='LogDet', grad_func=logdet_grad)
def logdet(a):
return tf.py_func(logdet_np, [a], tf.float64, stateful=False, name='LogDet')
Der obige Code zu schreiben funktionieren würde, wenn man den Konflikt zwischen Defun
und py_func
lösen kann, die die entscheidende Frage ist, die ich oben angehoben.
Sie SVD verwenden können und erhalten Determinante von singulären Werten –
ist eine besondere (zB positiv definite)? – dmuir
@dmuir det (A) ist positiv, aber die Eigenwerte sind nicht alle positiv (dh es gibt negative Eigenwerte, die paarweise auftreten). –