Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.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_Loss Function - Fatal编程技术网

Python Keras自定义损失函数,每个示例具有不同的权重

Python Keras自定义损失函数,每个示例具有不同的权重,python,tensorflow,keras,loss-function,Python,Tensorflow,Keras,Loss Function,我试图在Keras中实现一个自定义损失函数,其中每个示例(不是类)都有不同的权重 准确地说,考虑到通常的y_-true(例如)和y_-pred(例如),我试图创建权重(例如),并将其与二进制交叉熵损失函数一起使用。我试过: import numpy as np from keras import backend as K def my_binary_crossentropy(y_true, y_pred): base_factor = 0.9 num_examples = K.

我试图在Keras中实现一个自定义损失函数,其中每个示例(不是类)都有不同的权重

准确地说,考虑到通常的y_-true(例如)和y_-pred(例如),我试图创建权重(例如),并将其与二进制交叉熵损失函数一起使用。我试过:

import numpy as np
from keras import backend as K

def my_binary_crossentropy(y_true, y_pred):
    base_factor = 0.9
    num_examples = K.int_shape(y_true)[0]

    out = [ K.pow(base_factor, num_examples - i - 1) for i in range(num_examples) ]
    forgetting_factors = K.stack(out)

    return K.mean(
        forgetting_factors * K.binary_crossentropy(y_true, y_pred),
        axis=-1
    )
这个简单的例子很好用:

y_true = K.variable( np.array([1,1,0]) )
y_pred = K.variable( np.array([1,0.2,0.8]) )
print K.eval(my_binary_crossentropy(y_true, y_pred))
但是,当我将它与
model.compile(loss=my\u binary\u crossentropy,…)
一起使用时,我得到了以下错误:
TypeError:range()预期的整数结束参数,得到了NoneType

我试过一些东西。我用K_形状替换了K.int_形状,现在得到:
TypeError:range()应为整数结束参数,得到了张量。
我进一步用K.arange()替换了range(),现在得到:
TypeError:Tensor对象在未启用急切执行时不可用。要在这个张量上迭代,请使用tf.map\u fn


有人能帮我吗?我错过了什么?非常感谢

在tensorflow中,首先使用张量预定义图形,然后再运行它。因此,使用numpy数组的函数不使用tensorflow是很常见的。在您的案例中,num_示例就是问题所在

假设在tensorflow中,此损失函数不会在每次需要时调用,而是在训练模型时,此损失函数将在图形中构建用于计算损失函数的图形

因此,当keras想要在tensorflow中构建损失函数时,你的y_真是一个抽象的张量,它很可能对你的第一个形状没有任何影响,因为批量大小还没有定义


您必须以一种不依赖于批大小的方式重写损失函数=>删除变量num\u示例

K.pow
可以使用一系列指数作为参数。所以你可以先计算指数,作为一个张量(
[num\u examples-1,num\u examples-2,…,0]
),然后将这个张量输入到
K.pow
。这里的
num\u示例
基本上就是
K.shape(y\u pred)[0]
,这也是一个张量

def my_binary_crossentropy(y_true, y_pred):
    base_factor = 0.9
    num_examples = K.cast(K.shape(y_pred)[0], K.floatx())
    exponents = num_examples - K.arange(num_examples) - 1
    forgetting_factors = K.pow(base_factor, exponents)
    forgetting_factors = K.expand_dims(forgetting_factors, axis=-1)
    forgetting_factors = K.print_tensor(forgetting_factors)  # only for debugging

    loss = K.mean(
        forgetting_factors * K.binary_crossentropy(y_true, y_pred),
        axis=-1
    )
    loss = K.print_tensor(loss)  # only for debugging
    return loss
例如,由两个
K.print\u tensor
语句打印的输出如下:

model = Sequential()
model.add(Dense(1, activation='sigmoid', input_shape=(100,)))
model.compile(loss=my_binary_crossentropy, optimizer='adam')

model.evaluate(np.zeros((3, 100)), np.ones(3), verbose=0)
[[0.809999943][0.9][1]]
[0.56144917 0.623832464 0.693147182]

model.evaluate(np.zeros((6, 100)), np.ones(6), verbose=0)
[[0.590489924][0.656099916][0.728999913]...]
[0.409296423 0.454773813 0.505304217...]

由于四舍五入错误,数字不准确。
遗忘因子
(在
model.evaluate
之后打印的第一行)实际上是0.9的幂。您还可以验证返回的损耗值衰减系数为0.9(
0.623832464=0.693147182*0.9
0.56144917=0.693147182*0.9**2
等)。

非常感谢!您能否解释一下,为什么它会返回一个列表(model.evaluate后面的第二行),而不是一个数字,即损失?据我所知,最终答案是,损失是此列表中的最后一个数字,是否正确?打印和返回的
loss
变量包含样本损失值。Keras损失函数返回样本损失,然后在内部对其进行平均(并乘以样本权重)。例如,在第一个
model.evaluate()
中,传入一个包含3个样本的批次,因此
loss
变量将是大小为3.5的1D张量。我问这个问题的原因是因为我试图做一个简单的测试来验证代码。考虑到我的原始帖子中的示例,使用原始的
二进制交叉熵得出1.0729587。使用
my_binary_crossentropy
base_factor=1.0
给出[1.0729587 1.0729587 1.0729587]。但是设置
base\u factor=0.9
会给出[0.8690965 0.9656628 1.0729587],而我期望的是1.019311。嗯,也许我遗漏了一些东西,但为什么是1.019311?您希望权重为
[0.81,0.9,1.0]
还是
[0.9,0.95,1.0]