gpt4 book ai didi

python - Keras 中的二阶导数

转载 作者:太空宇宙 更新时间:2023-11-03 15:45:59 26 4
gpt4 key购买 nike

对于神经网络的自定义损失,我使用函数 enter image description here . u,给定一对 (t,x),两个点都在一个区间内,是我的神经网络的输出。问题是我被困在如何使用 K.gradient 计算二阶导数(K 是 TensorFlow 后端):

def custom_loss(input_tensor, output_tensor):
def loss(y_true, y_pred):

# so far, I can only get this right, naturally:
gradient = K.gradients(output_tensor, input_tensor)

# here I'm falling badly:

# d_t = K.gradients(output_tensor, input_tensor)[0]
# dd_x = K.gradient(K.gradients(output_tensor, input_tensor),
# input_tensor[1])

return gradient # obviously not useful, just for it to work
return loss

基于 Input(shape=(2,)),我所有的尝试都是上面代码片段中注释行的变体,主要是试图找到结果张量的正确索引。

果然我对张量的工作原理一无所知。顺便说一句,我知道在 TensorFlow 本身我可以简单地使用 tf.hessian,但我注意到它只是在使用 TF 作为后端时不存在。

最佳答案

为了 K.gradients()层要像那样工作,你必须将它包含在 Lambda() 中层,否则不会创建完整的 Keras 层,您无法链接或训练它。所以这段代码可以工作(经过测试):

import keras
from keras.models import *
from keras.layers import *
from keras import backend as K
import tensorflow as tf

def grad( y, x ):
return Lambda( lambda z: K.gradients( z[ 0 ], z[ 1 ] ), output_shape = [1] )( [ y, x ] )

def network( i, d ):
m = Add()( [ i, d ] )
a = Lambda(lambda x: K.log( x ) )( m )
return a

fixed_input = Input(tensor=tf.constant( [ 1.0 ] ) )
double = Input(tensor=tf.constant( [ 2.0 ] ) )

a = network( fixed_input, double )

b = grad( a, fixed_input )
c = grad( b, fixed_input )
d = grad( c, fixed_input )
e = grad( d, fixed_input )

model = Model( inputs = [ fixed_input, double ], outputs = [ a, b, c, d, e ] )

print( model.predict( x=None, steps = 1 ) )

def network 模型 f( x ) = log( x + 2 )x = 1def grad 是完成梯度计算的地方。此代码输出:

[array([1.0986123], dtype=float32), array([0.33333334], dtype=float32), array([-0.11111112], dtype=float32), array([0.07407408], dtype=float32), array([-0.07407409], dtype=float32)]

哪些是 log( 3 ) 的正确值-1/32, 2/33, -6/34


引用TensorFlow代码

作为引用,普通 TensorFlow 中的相同代码(用于测试):

import tensorflow as tf

a = tf.constant( 1.0 )
a2 = tf.constant( 2.0 )

b = tf.log( a + a2 )
c = tf.gradients( b, a )
d = tf.gradients( c, a )
e = tf.gradients( d, a )
f = tf.gradients( e, a )

with tf.Session() as sess:
print( sess.run( [ b, c, d, e, f ] ) )

输出相同的值:

[1.0986123, [0.33333334], [-0.11111112], [0.07407408], [-0.07407409]]

黑森州

tf.hessians()确实返回二阶导数,这是链接两个 tf.gradients() 的简写. Keras 后端没有 hessians,因此您必须将这两个 K.gradients() 链接起来。 .

数值逼近

如果出于某种原因上述方法均无效,那么您可能需要考虑通过在较小的 ε 距离上取差来在数值上逼近二阶导数。这基本上是 每个输入 的网络三倍,因此该解决方案除了缺乏准确性之外还引入了严肃的效率考虑因素。无论如何,代码(已测试):

import keras
from keras.models import *
from keras.layers import *
from keras import backend as K
import tensorflow as tf

def network( i, d ):
m = Add()( [ i, d ] )
a = Lambda(lambda x: K.log( x ) )( m )
return a

fixed_input = Input(tensor=tf.constant( [ 1.0 ], dtype = tf.float64 ) )
double = Input(tensor=tf.constant( [ 2.0 ], dtype = tf.float64 ) )

epsilon = Input( tensor = tf.constant( [ 1e-7 ], dtype = tf.float64 ) )
eps_reciproc = Input( tensor = tf.constant( [ 1e+7 ], dtype = tf.float64 ) )

a0 = network( Subtract()( [ fixed_input, epsilon ] ), double )
a1 = network( fixed_input, double )
a2 = network( Add()( [ fixed_input, epsilon ] ), double )

d0 = Subtract()( [ a1, a0 ] )
d1 = Subtract()( [ a2, a1 ] )

dv0 = Multiply()( [ d0, eps_reciproc ] )
dv1 = Multiply()( [ d1, eps_reciproc ] )

dd0 = Multiply()( [ Subtract()( [ dv1, dv0 ] ), eps_reciproc ] )

model = Model( inputs = [ fixed_input, double, epsilon, eps_reciproc ], outputs = [ a0, dv0, dd0 ] )

print( model.predict( x=None, steps = 1 ) )

输出:

[array([1.09861226]), array([0.33333334]), array([-0.1110223])]

(这只得到二阶导数。)

关于python - Keras 中的二阶导数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49935778/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com