2016-12-29 3 views
3

Ich mag würde Derivate ein Verhältnis f = - a/b in einem numerisch stabil berechnen tensorflow verwenden, aber Probleme leite wenn a und b klein sind (<1e-20, wenn 32-Bit-Gleitkomma-Darstellung unter Verwendung von). Natürlich ist die Ableitung von fdf_db = a/b ** 2, aber wegen der Vorrangstellung des Operators wird das Quadrat im Nenner zuerst berechnet, Unterläufe und führt zu einem undefinierten Gradienten.Wie Gradienten in einem numerisch stabil berechnen

Wenn das Derivat als df_db = (a/b)/b berechnet wurde, würde der Unterlauf nicht auftreten und der Gradient wäre wohldefiniert, wie in der folgenden Abbildung dargestellt, die den Gradienten in Abhängigkeit von a = b zeigt. Die blaue Linie entspricht der Domäne, in der Tensorflow die Ableitung berechnen kann. Die orange Linie entspricht der Domäne, in der der Nenner unterläuft und einen unendlichen Gradienten ergibt. Die grüne Linie entspricht der Domäne, in der der Nenner überläuft und einen Nullgradienten liefert. In beiden problematischen Domänen kann der Gradient unter Verwendung des obigen modifizierten Ausdrucks berechnet werden.

enter image description here

Ich habe in der Lage mithilfe des hässlichen Hack

g = exp(log(a) - log(b)) 

eine numerisch stabile Expression zu erhalten, die zu f entspricht aber ergibt sich eine unterschiedliche tensorflow Graphen. Aber ich stoße auf dasselbe Problem, wenn ich ein Derivat höherer Ordnung berechnen möchte. Der Code zum Reproduzieren des Problems finden Sie here.

Gibt es einen empfohlenen Ansatz zur Linderung solcher Probleme? Ist es möglich, eine Ableitung eines Ausdrucks im Tensorfluss explizit zu definieren, wenn man sich nicht auf die Autodifferenzierung verlassen will?

+0

Vielleicht eine dumme Frage, aber können Sie nicht alle Werte von 1000 multiplizieren oder so aus diesem kleinen Bereich zu bekommen? – fafl

+0

Es gibt 'gradient_override_map', wenn Sie Ihre eigenen Implementierungen des umgekehrten AD-Operators für verschiedene Ops einbinden möchten –

+0

Sie können auch den Gradienten eines Ausdrucks in TensorFlow definieren, indem Sie diesen Ausdruck in eine Tensorflow-Funktion einbinden, ein Beispiel ist in [function_test.py] (https://github.com/tensorflow/tensorflow/blob/27711108b5fce2e1692f9440631a183b3808fa01/tensorflow/python/framework/function_test.py#L136) –

Antwort

3

Dank Yaroslav Bulatovs Zeiger konnte ich eine benutzerdefinierte Funktion mit der gewünschten Steigung implementieren.

# Define the division function and its gradient 
@function.Defun(tf.float32, tf.float32, tf.float32) 
def newDivGrad(x, y, grad): 
    return tf.reciprocal(y) * grad, - tf.div(tf.div(x, y), y) * grad 


@function.Defun(tf.float32, tf.float32, grad_func=newDivGrad) 
def newDiv(x, y): 
    return tf.div(x, y) 

Volles Notizbuch ist here. PR ist here.

enter image description here

Verwandte Themen