Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Keras自定义损失函数错误“;没有提供梯度”; 问题描述_Python_Tensorflow_Keras - Fatal编程技术网

Python Keras自定义损失函数错误“;没有提供梯度”; 问题描述

Python Keras自定义损失函数错误“;没有提供梯度”; 问题描述,python,tensorflow,keras,Python,Tensorflow,Keras,我正在尝试使用基于TensorFlow 2.3.0的Keras训练网络。任务是创建新图片。在第一个简单的原型/概念验证中,我尝试训练网络仅使用给定数量的非黑色像素创建图片。因此,我需要定义一个自定义损失函数。这样我就得到了ValueError:没有为任何变量提供梯度,我还不能解决这个问题 最重要的是,我更喜欢一种不用急于运行就可以编写这个丢失函数的方法 代码片段 运行此代码会显示错误消息: ValueError: No gradients provided for any variable: [

我正在尝试使用基于TensorFlow 2.3.0的Keras训练网络。任务是创建新图片。在第一个简单的原型/概念验证中,我尝试训练网络仅使用给定数量的非黑色像素创建图片。因此,我需要定义一个自定义损失函数。这样我就得到了
ValueError:没有为任何变量提供梯度,我还不能解决这个问题

最重要的是,我更喜欢一种不用急于运行就可以编写这个丢失函数的方法

代码片段 运行此代码会显示错误消息:

ValueError: No gradients provided for any variable: ['dense/kernel:0', 'dense/bias:0', 'conv2d/kernel:0', 'conv2d/bias:0', 'conv2d_1/kernel:0', 'conv2d_1/bias:0', 'conv2d_2/kernel:0', 'conv2d_2/bias:0', 'conv2d_3/kernel:0', 'conv2d_3/bias:0'].
到目前为止我都试过了 这个错误听起来好像损失函数是不可微的,但为什么不应该呢

在谷歌上搜索一个解决方案,我发现了这个建议,我可能也有,但我已经通过保存一些带有标签的图片(见上面代码中注释的行)检查了这个建议。这个很好用

除此之外,我找不到任何有用的提示,总之没有太多的谷歌点击。。。(我想做的事似乎很有异国情调?)。有什么想法吗

编辑 感谢您的快速反馈,很抱歉没有非常清楚地描述损失函数的任务,让我再试一次:

我有一个模型,它基于单个浮点输入创建一个完整的533x800 RGB图片,并作为
y\u true
传递给损失函数。模型创建的图片也作为
y\u pred
传递给损失函数。丢失函数现在调用一个小函数
count\u nonblack\u pil
来计算
y\u pred
中的非黑色像素数。然后将损耗计算为
y_true
与计数像素之间的平方差。通过最小化这种差异,我希望训练模型,以便能够创建一个具有大量接近输入值的非黑色像素的图片。这不是真正有用的,只是一个简单的概念证明,说明我以后打算用不同的损失函数做什么(我想用其他已经训练过的模型来计算更有用和复杂任务的损失)

希望这是有道理的。更清楚地说:

y_true size : 16
y_pred size : 20467200
y_pred
包含16张533x800的图片,共3种颜色,即20467200。
y\u true
仅包含16个像素目标值

编辑:解决方案
我现在已经理解了这个问题,可以很好地概括为:“请记住,您编写的python函数(自定义丢失)调用以生成和编译C函数。编译后的函数是在培训期间调用的函数。调用python自定义丢失函数时,参数是没有附加数据的张量对象。K.eval调用将失败,K.shape调用也将失败。“

自定义丢失应仅使用tensorflow操作。Tensorflow(目前)无法计算numpy或任何其他库中操作的梯度。您必须将所有计算更改为某些
tf.op
函数


需要注意的是,即时执行并不能解决这个问题。

自定义丢失应该只使用tensorflow操作。Tensorflow(目前)无法计算numpy或任何其他库中操作的梯度。您必须将所有计算更改为某些
tf.op
函数


需要注意的是,急切执行对解决此问题没有帮助。

抛出错误是因为这些操作不是图形的一部分,因此无法区分。你想要做的并不需要急切,而是一系列的tensorflow方法来做你想做的

由于您的算法的具体细节有点模糊,我将提出一个更简单的解决方案。似乎您的总体目标是生成类似的图像,但与原始图像相比,减少黑色图像的数量。 您可以通过保留原始损失但增加罚款来实现这一点。我假设您需要MSE损失,但这并不重要,因为您可以使用任何其他:

Loss = alpha * MSE + beta * nr_of_black_pixels_in_pred 
使用
alpha
beta
调整每个项目的影响。这可以在这样的损失中实现:

def custom_loss(y_true, y_pred):
    alpha, beta = 0.8, 0.2 # percentage influence
    mse = tf.keras.losses.mean_squared_error(y_true, y_pred)
    count = tf.where(y_pred==0., tf.ones_like(y_pred), tf.zeros_like(y_pred))
    bp = tf.math.reduce_sum(count)
    return alpha * mse + beta * bp

这样做的好处是,您现在甚至可以(例如)说
y_pred抛出错误,因为这些操作不是图形的一部分,因此无法区分。你想要做的并不需要急切,而是一系列的tensorflow方法来做你想做的

由于您的算法的具体细节有点模糊,我将提出一个更简单的解决方案。似乎您的总体目标是生成类似的图像,但与原始图像相比,减少黑色图像的数量。 您可以通过保留原始损失但增加罚款来实现这一点。我假设您需要MSE损失,但这并不重要,因为您可以使用任何其他:

Loss = alpha * MSE + beta * nr_of_black_pixels_in_pred 
使用
alpha
beta
调整每个项目的影响。这可以在这样的损失中实现:

def custom_loss(y_true, y_pred):
    alpha, beta = 0.8, 0.2 # percentage influence
    mse = tf.keras.losses.mean_squared_error(y_true, y_pred)
    count = tf.where(y_pred==0., tf.ones_like(y_pred), tf.zeros_like(y_pred))
    bp = tf.math.reduce_sum(count)
    return alpha * mse + beta * bp

好处是你现在甚至可以说,比如说
y\u注意,即使只使用TF函数,如果使用“硬”计数,它可能是不可微分的——如果像素计数为开或关,梯度几乎处处为零,并且在阈值处未定义。注意,即使只使用TF函数,如果使用“硬”计数,它可能是不可微的——如果像素计数为开或关,梯度几乎处处为零,并且在阈值处未定义。你能从概念上和更精确的数学术语解释损失fct应该做什么吗?你的代码很不清楚。这看起来像是在尝试减少pred中的黑色像素。如果您的总体目标是减少pred中的黑色像素数量,则更传统、更直接的方法是只计算预测中的黑色像素数量,并将其作为原始损失的加权惩罚(我假设为MSE):
loss=alpha*MSE+beta*sum(black_pix