在自定义Keras损失函数中使用类似的np.where函数

问题描述 投票:0回答:1

我正在尝试创建一个自定义损失函数,根据预测、比赛的实际结果以及主队获胜的赔率来计算赢得的总金额。

目前,我已经做到了:

    # Custom loss function to minimize money lost
def custom_loss(odds):
    def loss_func(y_true, y_pred):
        bet_amount = 100  # Constant bet amount (100 euros per game)

        # Money lost or gained calculation
        # If home team won (y_true == 1) and the prediction was correct
        money_lost = tf.where(
            y_true == 1,  # If home team won
            (1 - y_pred) * (odds - 1) * bet_amount,  # Profit (if correct prediction)
            y_pred * bet_amount  # Full loss (if wrong prediction)
        )

        # Return the average loss
        return tf.reduce_mean(money_lost)
    return loss_func

def build_model(input_shape_features):
    # Input for game features
    input_features = Input(shape=input_shape_features, name="game_features")
    
    # Input for odds
    input_odds = Input(shape=(1,), name="odds")

    # Neural network to process game features
    x = layers.Dense(64, activation='relu')(input_features)
    x = layers.Dense(32, activation='relu')(x)
    output_prob = layers.Dense(1, activation='sigmoid')(x)  # Output: probability of home team win
    
    # Add a Lambda layer to pass the odds into the custom loss function
    model = Model(inputs=[input_features, input_odds], outputs=output_prob)

    # Compile the model using a custom loss function
    model.compile(optimizer='adam', loss=custom_loss(odds=input_odds))

    return model

# Train the model with two inputs
def train_model(X_train_features, X_train_odds, y_train):
    # Build the model
    model = build_model(input_shape_features=(X_train_features.shape[1],))
    
    # Train the model
    model.fit([X_train_features, X_train_odds], y_train, epochs=10, batch_size=32)
    
    return model

但是,如果我适合这个模型,我会收到以下错误:

    ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[66], line 1
----> 1 model = train_model(X_train_features, X_train_odds, y_train)

Cell In[64], line 44
     41 model = build_model(input_shape_features=(X_train_features.shape[1],))
     43 # Train the model
---> 44 model.fit([X_train_features, X_train_odds], y_train, epochs=10, batch_size=32)
     46 return model

File /usr/local/lib/python3.11/site-packages/keras/src/utils/traceback_utils.py:122, in filter_traceback.<locals>.error_handler(*args, **kwargs)
    119     filtered_tb = _process_traceback_frames(e.__traceback__)
    120     # To get the full stack trace, call:
    121     # `keras.config.disable_traceback_filtering()`
--> 122     raise e.with_traceback(filtered_tb) from None
    123 finally:
    124     del filtered_tb

Cell In[64], line 8
      4 bet_amount = 100  # Constant bet amount (100 euros per game)
      6 # Money lost or gained calculation
      7 # If home team won (y_true == 1) and the prediction was correct
----> 8 money_lost = tf.where(
      9     y_true == 1,  # If home team won
     10     (1 - y_pred) * (odds - 1) * bet_amount,  # Profit (if correct prediction)
     11     y_pred * bet_amount  # Full loss (if wrong prediction)
     12 )
     14 # Return the average loss
     15 return tf.reduce_mean(money_lost)

ValueError: Tried to convert 't' to a tensor and failed. Error: A KerasTensor cannot be used as input to a TensorFlow function. A KerasTensor is a symbolic placeholder for a shape and dtype, used when constructing Keras Functional models or Keras Functions. You can only use it as input to a Keras layer or a Keras operation (from the namespaces `keras.layers` and `keras.operations`). You are likely doing something like:

```
x = Input(...)
...
tf_fn(x)  # Invalid.
```

What you should do instead is wrap `tf_fn` in a layer:

```
class MyLayer(Layer):
    def call(self, x):
        return tf_fn(x)

x = MyLayer()(x)
```

如果我理解正确的话,不可能像我现在使用的方式使用

tf.where()
。但我仍然有点迷失如何实现这一目标。基本上,如果预测正确,我想将所有赢得的钱加起来;如果预测不正确,我想将所有损失(-100)加起来。

欢迎任何建议!

python tensorflow keras
1个回答
0
投票

Keras 3 文档中描述了您遇到的错误:使用 KerasTensor 调用 TF 操作

在函数模型构建过程中,不允许在 Keras 张量上使用 TF 操作:“KerasTensor 不能用作 TensorFlow 函数的输入”。

以下代码片段将重现该错误:

input = keras.layers.Input([2, 2, 1]) 
tf.squeeze(input)

如何修复它:使用

keras.ops
中的等效操作。

 input = keras.layers.Input([2, 2, 1]) 
 keras.ops.squeeze(input)

在您的情况下,您应该能够透明地使用

keras.ops.where
代替
tf.where
,并且类似地,使用
keras.ops.mean
代替
tf.reduce_mean

© www.soinside.com 2019 - 2024. All rights reserved.