Skip to main content
 首页 » 编程设计

python之Keras 自定义损失函数中的 TensorFlow session

2024年09月07日31cyq1162

在浏览了一些 Stack 问题和 Keras 文档之后,我设法编写了一些代码来尝试评估神经网络输出的梯度 w.r.t 它的输入,目的是一个简单的逼近双变量函数的练习(f(x,y) = x^2+y^2) 使用分析微分和自动微分之间的差异作为损失。

结合两个问题(Keras custom loss function: Accessing current input pattern 和 Getting gradient of model output w.r.t weights using Keras )的答案,我得出了这个结论:

import tensorflow as tf 
from keras import backend as K 
from keras.models import Model 
from keras.layers import Dense, Activation, Input 
 
def custom_loss(input_tensor): 
 
    outputTensor = model.output        
    listOfVariableTensors = model.input       
    gradients = K.gradients(outputTensor, listOfVariableTensors) 
 
    sess = tf.InteractiveSession() 
    sess.run(tf.initialize_all_variables()) 
    evaluated_gradients = sess.run(gradients,feed_dict={model.input:input_tensor}) 
 
    grad_pred = K.add(evaluated_gradients[0], evaluated_gradients[1]) 
    grad_true = k.add(K.scalar_mul(2, model.input[0][0]), K.scalar_mul(2, model.input[0][1]))  
 
    return K.square(K.subtract(grad_pred, grad_true)) 
 
input_tensor = Input(shape=(2,)) 
hidden = Dense(10, activation='relu')(input_tensor) 
out = Dense(1, activation='sigmoid')(hidden) 
model = Model(input_tensor, out) 
model.compile(loss=custom_loss_wrapper(input_tensor), optimizer='adam') 

这会产生错误:TypeError: The value of a feed cannot be a tf.Tensor object. 因为 feed_dict={model.input:input_tensor}。我了解错误,只是不知道如何解决。

根据我收集到的信息,我不能简单地将输入数据传递给损失函数,它必须是张量。我意识到当我调用 input_tensor 时,Keras 会“理解”它。这一切都让我觉得我做错了事情,试图像那样评估梯度。非常感谢一些启发。

请您参考如下方法:

我不太明白你为什么要这个损失函数,但我还是会提供一个答案。此外,无需评估函数内的梯度(实际上,您将“断开”计算图)。损失函数可以实现如下:

from keras import backend as K 
from keras.models import Model 
from keras.layers import Dense, Input 
 
def custom_loss(input_tensor, output_tensor): 
    def loss(y_true, y_pred): 
        gradients = K.gradients(output_tensor, input_tensor) 
        grad_pred = K.sum(gradients, axis=-1) 
        grad_true = K.sum(2*input_tensor, axis=-1) 
        return K.square(grad_pred - grad_true) 
    return loss 
 
input_tensor = Input(shape=(2,)) 
hidden = Dense(10, activation='relu')(input_tensor) 
output_tensor = Dense(1, activation='sigmoid')(hidden) 
model = Model(input_tensor, output_tensor) 
model.compile(loss=custom_loss(input_tensor, output_tensor), optimizer='adam')