【问题标题】:How to create your own loss function for tf.keras that uses additional parameter?如何为使用附加参数的 tf.keras 创建自己的损失函数?
【发布时间】:2020-06-03 12:06:28
【问题描述】:

我的需要:

我想通过添加样本权重来修改神经网络中的损失函数。 (我知道.fit methodsample_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

出现以下错误:

TypeError: example_loss() 得到了一个意外的关键字参数 '样品重量'

我的问题:

  1. 为什么会这样?
  2. 我如何重写代码以便这样的架构也可以在 2.2.4-tf 上运行?
  3. 适用于 Keras/tf.keras 框架的提议对我来说也是一个可以接受的答案。

错误很容易重现。只需复制代码并运行即可。

【问题讨论】:

    标签: python tensorflow keras neural-network loss-function


    【解决方案1】:

    你需要像这样定义你的损失,以便将新参数传递给它:

    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))
    

    【讨论】:

      【解决方案2】:

      你可以这样重写你的损失:

      # 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))
      

      【讨论】:

        猜你喜欢
        • 2019-10-29
        • 2020-04-06
        • 2021-05-29
        • 2019-10-23
        • 2020-12-03
        • 2018-10-11
        • 2020-04-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多