#!/usr/bin/env python # -*- coding:utf-8 -*- # @FileName :losses_cash.py # @Time :2025/6/11 15:31 # @Author :David # @Company: shenyang JY import tensorflow as tf from tensorflow.keras.losses import Loss from typeguard import typechecked tf.compat.v1.set_random_seed(1234) """ 两个细则结合现货交易损失函数 总体原则: 抑制负偏差,控制负偏差 """ class SouthLossCash(Loss): """南网新规则损失函数(支持完整序列化)""" @typechecked def __init__(self, cap: float, name: str = "south_cash_loss", penalty_coeff: float = 1.0, # 新增惩罚系数参数 reduction: str = "sum_over_batch_size"): # if not 0 <= cap <= 1: # raise ValueError("cap 必须为归一化后的值且位于 [0,1] 区间") super().__init__(name=name, reduction=reduction) # 序列化相关参数 self._raw_cap = cap self.penalty_coeff = penalty_coeff # 惩罚项系数 # 实际计算值(注意:这里的0.2是原代码中的缩放逻辑,保持不动) self.cap = tf.constant(cap * 0.2, dtype=tf.float32) def get_config(self): config = super().get_config() config.update({ "cap": self._raw_cap, "penalty_coeff": self.penalty_coeff, # 序列化新参数 "name": self.name, "reduction": self.reduction }) return config @classmethod def from_config(cls, config): return cls( cap=config["cap"], penalty_coeff=config.get("penalty_coeff", 1.0), # 带默认值以兼容旧配置 name=config["name"], reduction=config["reduction"] ) def call(self, y_true, y_pred): # 数值稳定化处理 y_true = tf.cast(y_true, tf.float32) y_pred = tf.cast(y_pred, tf.float32) diff = y_true - y_pred # 负值表示预测偏高,正值表示预测偏低 delta = y_true - self.cap # 基值计算逻辑(保持原样) logistic_input = tf.clip_by_value(10000.0 * delta, -50.0, 50.0) logistic_values = tf.sigmoid(logistic_input) base = logistic_values * y_true + (1 - logistic_values) * self.cap safe_base = tf.where(tf.equal(base, 0.0), 1e-7, base) # 原基础损失 base_loss = tf.reduce_mean(tf.square(diff / safe_base), axis=-1) ############### 新增惩罚项部分 ############### # 计算负偏差惩罚(预测值低于真实值时进行惩罚) negative_bias = tf.maximum(diff, 0.0) # 获取负偏差部分的绝对值 penalty = self.penalty_coeff * tf.reduce_mean(negative_bias, axis=-1) # 组合最终损失(可以尝试不同权重) total_loss = base_loss + penalty return total_loss if __name__ == "__main__": run_code = 0