簡體   English   中英

Keras自定義丟失功能,每個示例具有不同的權重

[英]Keras custom loss function with different weights per example

我正在嘗試在Keras中實現一個自定義丟失函數,其中每個單獨的示例(不是類)具有不同的權重。

確切地說,給定通常的y_true (例如<1,1,0>)和y_pred (例如<1,0.2,0.8>),我正在嘗試創建權重 (例如<0.81,0.9,1.0>)和將這些與binary_crossentropy損失函數一起使用。 我試過了:

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_binary_crossentropy, ...)一起使用時,我收到以下錯誤: TypeError: range() integer end argument expected, got NoneType

我嘗試了一些事情。 我用K_shape替換了K.int_shape並且現在得到: TypeError: range() integer end argument expected, got Tensor. 我再次被替換范圍()K.arange()現在越來越: TypeError: Tensor objects are not iterable when eager execution is not enabled. To iterate over this tensor use tf.map_fn TypeError: Tensor objects are not iterable when eager execution is not enabled. To iterate over this tensor use tf.map_fn

有人可以幫我嗎? 我錯過了什么? 非常感謝!

K.pow可以將一系列指數作為參數。 因此,您可以首先計算指數,作為張量( [num_examples - 1, num_examples - 2, ..., 0] ),然后將此張量提供給K.pow 這里num_examples基本上只是K.shape(y_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_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...]

由於舍入誤差,數字不准確。 forgetting_factors (后打印的第一行model.evaluate )確實的0.9的權力。 您還可以驗證返回的損失值是否衰減0.9( 0.623832464 = 0.693147182 * 0.90.56144917 = 0.693147182 * 0.9 ** 2等)。

在張量流中,您首先在運行之前使用張量預定義圖形。 因此,使用numpy數組的函數不能與tensorflow一起使用是很常見的。 在您的情況下,num_examples是問題所在。

想象一下,在張量流中,每次需要時都不會調用此損失函數,而是在模型訓練時,此損失函數將構建用於計算圖形內部損失函數的圖形。

所以當keras想要嘗試在tensorflow中構建你的損失函數時,你的y_true是一個抽象張量,你的第一個形狀很可能會有None,因為batch_size還沒有定義。

你必須以一種你不依賴於batch_size =>刪除變量num_examples的方式重寫你的損失函數

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM