Keras 自定义损失函数中的 TensorFlow 会话
TensorFlow session inside Keras custom loss function
在浏览了一些 Stack 问题和 Keras 文档之后,我设法编写了一些代码来尝试评估神经网络输出的梯度 w.r.t 它的输入,目的是进行简单的近似练习双变量函数 (f(x,y) = x^2+y^2
) 使用分析微分和自动微分之间的差异作为损失。
结合两个问题的答案(Keras 自定义损失函数:访问当前输入模式
和 使用 Keras 获取模型输出的梯度 w.r.t 权重
), 我想到了这个:
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 会 'understand' 它。这一切都让我觉得我做错了事情,试图像那样评估梯度。非常感谢一些启发。
Keras 损失必须有 y_true
和 y_pred
作为输入。您可以尝试在拟合期间将输入对象添加为 x
和 y
:
def custom_loss(y_true,y_pred):
...
return K.square(K.subtract(grad_true, grad_pred))
...
model.compile(loss=custom_loss, optimizer='adam')
model.fit(X, X, ...)
这样,y_true
将是每次迭代从输入 X
处理的批次,而 y_pred
将是该特定批次的模型输出。
我不太明白你为什么要这个损失函数,但我还是会提供一个答案。此外,无需评估函数内的梯度(实际上,您将是 "disconnecting" 计算图)。损失函数可以实现如下:
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')
在浏览了一些 Stack 问题和 Keras 文档之后,我设法编写了一些代码来尝试评估神经网络输出的梯度 w.r.t 它的输入,目的是进行简单的近似练习双变量函数 (f(x,y) = x^2+y^2
) 使用分析微分和自动微分之间的差异作为损失。
结合两个问题的答案(Keras 自定义损失函数:访问当前输入模式 和 使用 Keras 获取模型输出的梯度 w.r.t 权重 ), 我想到了这个:
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 会 'understand' 它。这一切都让我觉得我做错了事情,试图像那样评估梯度。非常感谢一些启发。
Keras 损失必须有 y_true
和 y_pred
作为输入。您可以尝试在拟合期间将输入对象添加为 x
和 y
:
def custom_loss(y_true,y_pred):
...
return K.square(K.subtract(grad_true, grad_pred))
...
model.compile(loss=custom_loss, optimizer='adam')
model.fit(X, X, ...)
这样,y_true
将是每次迭代从输入 X
处理的批次,而 y_pred
将是该特定批次的模型输出。
我不太明白你为什么要这个损失函数,但我还是会提供一个答案。此外,无需评估函数内的梯度(实际上,您将是 "disconnecting" 计算图)。损失函数可以实现如下:
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')