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

如何在Keras Sequential模型中约束权重之和及非负性?

解决TensorFlow中权重非负且总和固定的约束问题

可以实现,但Keras内置的约束无法同时满足「非负」和「总和等于预算值」这两个条件,给你两种实用的解决方案:

方案一:自定义权重约束

直接继承tf.keras.constraints.Constraint类,实现自己的约束逻辑——先将权重截断为非负值,再归一化到目标总和。

import tensorflow as tf

class NonNegSumConstraint(tf.keras.constraints.Constraint):
    def __init__(self, target_sum=1.0):
        self.target_sum = target_sum  # 目标总和,比如1代表100%,100代表绝对预算值

    def __call__(self, w):
        # 第一步:将权重限制为非负
        w_non_neg = tf.maximum(w, 0.0)
        # 第二步:计算当前权重总和,避免除以0的极端情况
        current_sum = tf.maximum(tf.reduce_sum(w_non_neg), 1e-8)
        # 第三步:缩放权重,让总和等于目标值
        return w_non_neg * (self.target_sum / current_sum)

# 示例使用:假设要分配到5个选项,输入特征维度为input_dim
model.add(tf.keras.layers.Dense(5, input_shape=[input_dim], activation='linear',
            kernel_constraint=NonNegSumConstraint(target_sum=1.0)))

这个约束会在每次权重更新后自动生效,确保权重始终满足非负且总和固定的要求。

方案二:Softmax激活+缩放(更推荐)

利用Softmax激活的天然特性:输出值非负且总和为1,只需在输出后乘以预算值,就能得到总和等于预算的分配结果。这种方法无需自定义约束,训练时数值稳定性更好。

import tensorflow as tf

# 构建模型
input_layer = tf.keras.layers.Input(shape=[input_dim])
# 全连接层不设置激活函数
dense_layer = tf.keras.layers.Dense(5)(input_layer)
# Softmax确保输出非负且总和为1
softmax_output = tf.keras.layers.Softmax()(dense_layer)
# 乘以预算值,比如100代表总和为100的绝对预算
budget_output = tf.keras.layers.Lambda(lambda x: x * 100)(softmax_output)

model = tf.keras.Model(inputs=input_layer, outputs=budget_output)

两种方案的适用场景

  • 若你需要层的权重本身满足非负且总和固定,选方案一;
  • 若你只需要模型输出的分配结果满足条件,方案二更简洁高效,也是预算分配场景的常用做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:13:13