Python 如何在keras中创建自定义损失函数?(自定义加权二进制交叉熵)

Python 如何在keras中创建自定义损失函数?(自定义加权二进制交叉熵),python,keras,loss-function,cross-entropy,Python,Keras,Loss Function,Cross Entropy,我正在创建一个完全卷积的神经网络,它在输入中给定一个图像,能够识别其中的区域(黑色,0),也能识别背景(白色,255)。 我的目标是二值化图像(范围为0-255),我希望在两个语义类(0或255)之间取得一些平衡。 事实上,我得到的“特殊”区域(0)是背景区域(255)的1.8倍,所以我需要抵消这种影响,我想惩罚更多的事实,以便在背景上出错,避免只预测特殊区域 我试着关注一些关于它的话题,这似乎不是很难,但我陷入了我的实现中,我真的不知道为什么 每次我的实现在编译阶段工作,但仅在安装步骤中,它都

我正在创建一个完全卷积的神经网络,它在输入中给定一个图像,能够识别其中的区域(黑色,0),也能识别背景(白色,255)。 我的目标是二值化图像(范围为0-255),我希望在两个语义类(0或255)之间取得一些平衡。 事实上,我得到的“特殊”区域(0)是背景区域(255)的1.8倍,所以我需要抵消这种影响,我想惩罚更多的事实,以便在背景上出错,避免只预测特殊区域

我试着关注一些关于它的话题,这似乎不是很难,但我陷入了我的实现中,我真的不知道为什么

每次我的实现在编译阶段工作,但仅在安装步骤中,它都会返回一个错误。
以下是我迄今为止所做的尝试:

import keras.backend as kb    
def custom_binary_crossentropy(y_true, y_pred):
        """
        Used to reequilibrate the data, as there is more black (0., articles), than white (255., non-articles) on the pages.
        """
        if y_true >=128:   # Half the 0-255 range
            return -1.8*kb.log(y_pred/255.)
        else:
            return -kb.log(1-(y_pred/255.))
但它返回:

InvalidArgumentError:  The second input must be a scalar, but it has shape [16,256,256]
     [[{{node gradient_tape/custom_binary_crossentropy/cond/StatelessIf/gradient_tape/custom_binary_crossentropy/weighted_loss/Mul/_17}}]] [Op:__inference_train_function_24327]

Function call stack:
train_function
我真的不明白这个错误

我以前试过:

def custom_binary_crossentropy(y_true, y_pred):
    """
    Used to reequilibrate the data, as there is more black (0., articles), than white (255., non-articles) on the pages.
    """
    if y_true >=128:   # Half the 0-255 range
        return 1.8*keras.losses.BinaryCrossentropy(y_true, y_pred)
    else:
        return keras.losses.BinaryCrossentropy(y_true, y_pred)
但我得到了:

TypeError: in user code:

    /Users/axeldurand/opt/anaconda3/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py:806 train_function  *
        return step_function(self, iterator)
    <ipython-input-67-7b6815236f63>:6 custom_binary_crossentropy  *
        return -1.8*keras.losses.BinaryCrossentropy(y_true, y_pred)

    TypeError: unsupported operand type(s) for *: 'float' and 'BinaryCrossentropy'
TypeError:在用户代码中:
/Users/axeldurand/opt/anaconda3/lib/python3.7/site packages/tensorflow/python/keras/engine/training.py:806 train_函数*
返回步骤_函数(self、迭代器)
:6自定义\u二进制\u交叉熵*
返回值-1.8*keras.Loss.BinaryCross熵(y_true,y_pred)
TypeError:不支持*:“float”和“BinaryCrossentropy”的操作数类型

我有点困惑,Keras总是让它变得如此简单,我必须省略一些简单的东西,但我并不真正理解。

您使用的是
Keras.loss.BinaryCrossentropy
。实际上,您需要这个损失的函数版本,即
tf.keras.loss.binary\u crossentropy


看到并

非常感谢@qmeeus,你为我指明了通往成功的道路
我不知道keras.loss.BinaryCrossentropy和keras.loss.binary_crossentropy之间的区别,但这是一个主要的区别

我是这样做的:

def custom_binary_crossentropy(y_true, y_pred):
    """
    Used to reequilibrate the data, as there is more black (0., articles),
    than white (255. (recalibrated to 1.), non-articles) on the pages.
    """
    # I put 0 so that the shape is (batch_size, 256, 256)
    # and not (batch_size, 256, 256, 1)
    is_white = y_true[:,:,:,0]>=0.5 
    white_error = 1.8*keras.losses.binary_crossentropy(y_true, y_pred)
    black_error = keras.losses.binary_crossentropy(y_true, y_pred)
    # Returns the right loss for each type of error.
    # We do make twice the calculation but I did not find a better way for now
    return tf.where(is_white, white_error, black_error)
我不知道tf.where的用法,但它非常有用。 我在Aurélien Géron的优秀著作《Keras和TensorFlow的机器学习》中看到了这篇教程

只需使用next:

# Compiling using this function
model.compile(optimizer="rmsprop", loss=custom_binary_crossentropy)
然后使用您的数据和喜爱的超参数来拟合您的模型,您就可以开始了