losses_cash.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. # @FileName :losses_cash.py
  4. # @Time :2025/6/11 15:31
  5. # @Author :David
  6. # @Company: shenyang JY
  7. import tensorflow as tf
  8. from tensorflow.keras.losses import Loss
  9. from typeguard import typechecked
  10. tf.compat.v1.set_random_seed(1234)
  11. """
  12. 两个细则结合现货交易损失函数
  13. 总体原则:
  14. 抑制负偏差,控制负偏差
  15. """
  16. class SouthLossCash(Loss):
  17. """南网新规则损失函数(支持完整序列化)"""
  18. @typechecked
  19. def __init__(self,
  20. cap: float,
  21. name: str = "south_cash_loss",
  22. penalty_coeff: float = 1.0, # 新增惩罚系数参数
  23. reduction: str = "sum_over_batch_size"):
  24. # if not 0 <= cap <= 1:
  25. # raise ValueError("cap 必须为归一化后的值且位于 [0,1] 区间")
  26. super().__init__(name=name, reduction=reduction)
  27. # 序列化相关参数
  28. self._raw_cap = cap
  29. self.penalty_coeff = penalty_coeff # 惩罚项系数
  30. # 实际计算值(注意:这里的0.2是原代码中的缩放逻辑,保持不动)
  31. self.cap = tf.constant(cap * 0.2, dtype=tf.float32)
  32. def get_config(self):
  33. config = super().get_config()
  34. config.update({
  35. "cap": self._raw_cap,
  36. "penalty_coeff": self.penalty_coeff, # 序列化新参数
  37. "name": self.name,
  38. "reduction": self.reduction
  39. })
  40. return config
  41. @classmethod
  42. def from_config(cls, config):
  43. return cls(
  44. cap=config["cap"],
  45. penalty_coeff=config.get("penalty_coeff", 1.0), # 带默认值以兼容旧配置
  46. name=config["name"],
  47. reduction=config["reduction"]
  48. )
  49. def call(self, y_true, y_pred):
  50. # 数值稳定化处理
  51. y_true = tf.cast(y_true, tf.float32)
  52. y_pred = tf.cast(y_pred, tf.float32)
  53. diff = y_true - y_pred # 负值表示预测偏高,正值表示预测偏低
  54. delta = y_true - self.cap
  55. # 基值计算逻辑(保持原样)
  56. logistic_input = tf.clip_by_value(10000.0 * delta, -50.0, 50.0)
  57. logistic_values = tf.sigmoid(logistic_input)
  58. base = logistic_values * y_true + (1 - logistic_values) * self.cap
  59. safe_base = tf.where(tf.equal(base, 0.0), 1e-7, base)
  60. # 原基础损失
  61. base_loss = tf.reduce_mean(tf.square(diff / safe_base), axis=-1)
  62. ############### 新增惩罚项部分 ###############
  63. # 计算负偏差惩罚(预测值低于真实值时进行惩罚)
  64. negative_bias = tf.maximum(diff, 0.0) # 获取负偏差部分的绝对值
  65. penalty = self.penalty_coeff * tf.reduce_mean(negative_bias, axis=-1)
  66. # 组合最终损失(可以尝试不同权重)
  67. total_loss = base_loss + penalty
  68. return total_loss
  69. if __name__ == "__main__":
  70. run_code = 0