簡體   English   中英

如何為使用附加參數的 tf.keras 創建自己的損失函數?

[英]How to create your own loss function for tf.keras that uses additional parameter?

我的需要:

我想通過添加樣本權重來修改神經網絡中的損失函數。 (我知道.fit 方法sample_weight參數)。

我的想法是為我的神經網絡創建額外的輸入,為每個訓練數據行預先計算權重,如下所示:

# Generating mock data
train_X = np.random.randn(100, 5)
train_Y = np.random.randn(100, 1)
train_sample_weights = np.random.randn(*train_Y.shape)

# Designing loss function that uses my pre-computed weights
def example_loss(y_true, y_pred, sample_weights_):
    return K.mean(K.sqrt(K.sum(K.pow(y_pred - y_true, 2), axis=-1)), axis=0) * sample_weights_

# Two inputs for neural network, one for data, one for weights
input_tensor = Input(shape=(train_X.shape[1],))
weights_tensor = Input(shape=(train_sample_weights.shape[1],))

# Model uses only 'input_tensor'
x = Dense(100, activation="relu")(input_tensor)
out = Dense(1)(x)

# The 'weight_tensor' is inserted into example_loss() functon
loss_function = partial(example_loss, sample_weights_=weights_tensor)

# Model takes as an input both data and weights
model = Model([input_tensor, weights_tensor], out)
model.compile("Adam", loss_function)
model.fit(x=[train_X, train_sample_weights], y=train_Y, epochs=10)

我的問題:

當我使用 Keras 2.2.4 導入來運行它時,以下代碼有效

import numpy as np
from functools import partial

import keras.backend as K
from keras.layers import Input, Dense
from keras.models import Model

當我使用 tf.keras 2.2.4-tf 導入來運行它時,以下代碼崩潰

import numpy as np
from functools import partial

import tensorflow.keras.backend as K
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model

出現以下錯誤:

類型錯誤:example_loss() 得到了一個意外的關鍵字參數“sample_weight”

我的問題:

  1. 為什么會發生這種情況?
  2. 我怎樣才能重寫代碼,這樣這樣的架構也可以在 2.2.4-tf 上工作?
  3. 適用於 Keras/tf.keras 框架的命題對我來說也是一個可以接受的答案。

錯誤很容易重現。 只需要復制代碼並運行即可。

您需要像這樣定義損失以便將新參數傳遞給它:

def custom_loss(sample_weights_):

    def example_loss(y_true, y_pred):
        return K.mean(K.sqrt(K.sum(K.pow(y_pred - y_true, 2), axis=-1)), axis=0) * sample_weights_

    return example_loss

並這樣稱呼它:

model.compile("Adam", custom_loss(weights_tensor))

你可以像這樣重寫你的損失:

# Designing loss function that uses my pre-computed weights
def example_loss(sample_weights_):
    def loss(y_true, y_pred):
        return K.mean(K.sqrt(K.sum(K.pow(y_pred - y_true, 2), axis=-1)), axis=0) * sample_weights_

如您所見,這里我們有一個函數接受樣本權重,並返回另一個函數(實際損失),其中嵌入了樣本權重。 您可以將其用作:

model.compile(optimizer="adam", loss=example_loss(weights_tensor))

暫無
暫無

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

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