You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Keras的带产品替代的多产品报童问题自定义损失函数优化问询

优化多产品带替代行为的报童问题Keras自定义损失函数

原损失函数效果差的核心问题如下:

  • 未满足需求计算逻辑完全错误:只有真实需求大于库存时才会产生缺货,原代码搞反了计算方向
  • 替代需求增量计算错误:循环覆盖变量未累加所有产品的转移需求,且未兼容批量数据处理
  • 硬编码产品数量,缺乏通用性

以下是优化后的实现方案:

import tensorflow as tf

def newsvendor_substitution_loss(u, o, alpha):
    # 嵌套包装适配Keras损失函数接口(仅接收y_true和y_pred)
    def loss(y_true, y_pred):
        # 转换为张量确保计算精度
        u_tensor = tf.convert_to_tensor(u, dtype=tf.float32)
        o_tensor = tf.convert_to_tensor(o, dtype=tf.float32)
        alpha_tensor = tf.convert_to_tensor(alpha, dtype=tf.float32)
        
        # 1. 计算每个产品的未满足需求:真实需求 > 库存时的缺货量
        unmet_demand = tf.maximum(0.0, y_true - y_pred)  # shape: (batch_size, num_products)
        
        # 2. 矩阵乘法实现向量化替代需求计算
        # alpha[i][j] 表示产品i缺货时,未满足需求流向产品j的比例
        demand_increase = tf.matmul(unmet_demand, alpha_tensor)  # shape: (batch_size, num_products)
        
        # 3. 计算每个产品的实际面临需求:原需求 + 替代转移需求
        adjusted_demand = y_true + demand_increase
        
        # 4. 拆分超储/缺货成本计算
        overage = tf.maximum(0.0, y_pred - adjusted_demand)  # 库存过剩部分
        underage = tf.maximum(0.0, adjusted_demand - y_pred)  # 缺货部分
        
        # 5. 批量均值作为总损失
        total_loss = tf.reduce_mean(o_tensor * overage + u_tensor * underage)
        return total_loss
    return loss

优化说明

  1. 修正核心逻辑:正确计算缺货导致的未满足需求,确保替代行为触发条件符合业务实际
  2. 向量化计算:用矩阵乘法替代循环,高效处理批量数据,同时正确计算所有产品间的需求转移
  3. 接口适配:通过嵌套函数包装外部参数(缺货成本、超储成本、替代矩阵),完全符合Keras损失函数要求
  4. 逻辑清晰:拆分超储/缺货成本计算,便于调试和业务逻辑验证

使用示例

# 假设产品数量为6
num_products = 6

# 定义各产品的缺货成本u、超储成本o
u = [2.0, 3.0, 1.5, 2.5, 1.8, 2.2]
o = [1.0, 0.8, 1.2, 0.9, 1.1, 1.0]

# 定义替代矩阵(每行和建议≤1,代表需求转移比例)
alpha = [
    [0.0, 0.3, 0.2, 0.0, 0.0, 0.5],
    [0.2, 0.0, 0.4, 0.1, 0.1, 0.2],
    [0.1, 0.3, 0.0, 0.2, 0.2, 0.2],
    [0.0, 0.0, 0.1, 0.0, 0.6, 0.3],
    [0.1, 0.2, 0.2, 0.3, 0.0, 0.2],
    [0.3, 0.1, 0.2, 0.1, 0.1, 0.0]
]

# 构建并编译模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(32, activation='relu', input_shape=(input_dim,)),
    tf.keras.layers.Dense(num_products, activation='relu')  # 输出非负库存决策
])

model.compile(optimizer='adam', loss=newsvendor_substitution_loss(u, o, alpha))

额外优化建议

  • 验证替代矩阵每行和≤1,避免需求转移逻辑矛盾
  • 输入数据做归一化处理,帮助模型更快收敛
  • 若目标为最大化利润,可将损失改为负利润(-tf.reduce_mean(u*underage - o*overage)),需匹配业务目标调整

内容的提问来源于stack exchange,提问作者wanted curve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 07:17:09