设置tf.keras.NonNeg约束后Embedding层权重仍为负的问题咨询
Embedding层非负权重约束配置及负值问题解决
你配置的embeddings_constraint = tf.keras.constraints.NonNeg()本身是正确的,出现负值的核心原因是权重约束的生效时机限制:
- Keras的层权重约束仅会在每次反向传播更新权重之后触发,对更新后的权重做裁剪修正,不会修改初始化阶段生成的权重
- 你当前打印的是Embedding层的默认初始化权重,默认初始化策略为取值范围
[-0.05, 0.05]的均匀分布,本身就包含负值,还没有经过训练步骤触发约束逻辑,因此会出现你看到的输出结果。
对应解决方法
方法1:指定非负的权重初始化策略
如果希望权重从初始化阶段就全部为非负,可以手动指定embeddings_initializer参数为非负范围的初始化器,示例代码如下:
from tensorflow.keras.initializers import RandomUniform Embedding(embed_input_dim, self.embed_output, input_length=embed_input_length, # 初始化权重范围设为0到0.05,全程无负值 embeddings_initializer = RandomUniform(minval=0, maxval=0.05), embeddings_constraint = tf.keras.constraints.NonNeg(), name = 'Embed_Request')(state_input)
方法2:手动触发一次约束裁剪
如果已经完成模型初始化,不想修改初始化逻辑,可以手动调用约束对象修正当前权重再赋值回层:
embed_layer = self.model.get_layer('Embed_Request') non_neg_constraint = tf.keras.constraints.NonNeg() # 用非负约束裁剪当前权重 corrected_embed_weights = non_neg_constraint(embed_layer.get_weights()[0]) embed_layer.set_weights([corrected_embed_weights])
验证说明
在完成至少一轮model.fit()训练后再打印该层权重,就不会出现负值,此时每次权重更新后都会自动触发NonNeg约束做裁剪,保证权重全程非负。
内容的提问来源于stack exchange,提问作者prakash gawas
相关产品推荐
相关产品推荐

