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

带种子的TensorFlow层权重初始化在不同层及实例中生成相同值

问题描述

我定义了一个包含两个不同形状权重的自定义层:

import tensorflow as tf

class SimpleDense(tf.keras.layers.Layer):
    def __init__(self):
        super(SimpleDense, self).__init__()

    def build(self):
        self.w1 = self.add_weight(shape=(5, 5),
                               initializer=tf.keras.initializers.truncated_normal(seed=1234),
                               trainable=True)
        self.w2 = self.add_weight(shape=(5,6),
                               initializer=tf.keras.initializers.truncated_normal(seed=1234),
                               trainable=True)
    def call(self, inputs):
        pass

权重w1和w2的前25个浮点值完全相同,同一组浮点向量被复用。此外,该层的不同实例也拥有完全相同的权重:

sd1 = SimpleDense()
sd1.build()

sd2 = SimpleDense()
sd2.build()

sd1.w1
# 输出:
<tf.Variable 'Variable:0' shape=(5, 5) dtype=float32, numpy=
array([[-0.00682165,  0.03804878, -0.08698365,  0.02000416, -0.0379169 ],
   [-0.04041002,  0.00349349, -0.04125977, -0.04460358,  0.06052992],
   [ 0.09549459,  0.06161878, -0.02399441,  0.07976086,  0.05028958],
   [-0.00204308, -0.09973445, -0.07213714,  0.0325163 , -0.09121864],
   [-0.07422495, -0.04935479, -0.03293147,  0.01593254,  0.03643443]],
  dtype=float32)>

sd1.w2
# 输出:
<tf.Variable 'Variable:0' shape=(5, 6) dtype=float32, numpy=
array([[-0.00682165,  0.03804878, -0.08698365,  0.02000416, -0.0379169 ,
    -0.04041002],
   [ 0.00349349, -0.04125977, -0.04460358,  0.06052992,  0.09549459,
     0.06161878],
   [-0.02399441,  0.07976086,  0.05028958, -0.00204308, -0.09973445,
    -0.07213714],
   [ 0.0325163 , -0.09121864, -0.07422495, -0.04935479, -0.03293147,
     0.01593254],
   [ 0.03643443,  0.04764059,  0.00034371, -0.0784961 , -0.01348116,
    -0.05637978]], dtype=float32)>

sd2.w2
# 输出:
<tf.Variable 'Variable:0' shape=(5, 6) dtype=float32, numpy=
array([[-0.00682165,  0.03804878, -0.08698365,  0.02000416, -0.0379169 ,
    -0.04041002],
   [ 0.00349349, -0.04125977, -0.04460358,  0.06052992,  0.09549459,
     0.06161878],
   [-0.02399441,  0.07976086,  0.05028958, -0.00204308, -0.09973445,
    -0.07213714],
   [ 0.0325163 , -0.09121864, -0.07422495, -0.04935479, -0.03293147,
     0.01593254],
   [ 0.03643443,  0.04764059,  0.00034371, -0.0784961 , -0.01348116,
    -0.05637978]], dtype=float32)>

原本预期不同层及不同实例的权重值应该不同,请问这是什么原因?

原因分析与解决方案

原因

你给两个权重的初始化器都设置了相同的固定seed值1234。TensorFlow的截断正态初始化器在使用相同seed时,会生成完全一致的随机数序列:

  • 初始化w1时,用该seed生成了25个随机数;初始化w2时,会接着这个序列继续生成后续数值,因此w2的前25个值和w1完全重合。
  • 不同层实例的初始化器也用了相同的固定seed,所以每个实例初始化权重时都会生成一模一样的随机数序列,导致所有实例的权重完全相同。

解决方案

方案1:不设置固定seed(推荐)

让TensorFlow自动使用随机seed,这样每次初始化都会生成不同的随机数:

import tensorflow as tf

class SimpleDense(tf.keras.layers.Layer):
    def __init__(self):
        super(SimpleDense, self).__init__()

    def build(self):
        self.w1 = self.add_weight(shape=(5, 5),
                               initializer=tf.keras.initializers.truncated_normal(),
                               trainable=True)
        self.w2 = self.add_weight(shape=(5,6),
                               initializer=tf.keras.initializers.truncated_normal(),
                               trainable=True)
    def call(self, inputs):
        pass

方案2:给不同权重/实例分配不同seed

如果需要可复现的初始化,但又要不同权重、不同实例的数值不同,可以在层初始化时分配不同的seed:

import tensorflow as tf

class SimpleDense(tf.keras.layers.Layer):
    def __init__(self, base_seed=None):
        super(SimpleDense, self).__init__()
        # 自动生成随机base_seed,或使用传入的seed
        self.base_seed = base_seed if base_seed is not None else tf.random.uniform(shape=(), maxval=10000, dtype=tf.int32).numpy()

    def build(self):
        # 给w1和w2设置不同的seed偏移量
        self.w1 = self.add_weight(shape=(5, 5),
                               initializer=tf.keras.initializers.truncated_normal(seed=self.base_seed),
                               trainable=True)
        self.w2 = self.add_weight(shape=(5,6),
                               initializer=tf.keras.initializers.truncated_normal(seed=self.base_seed + 1),
                               trainable=True)
    def call(self, inputs):
        pass

这样每个实例可以传入不同的base_seed,或者自动生成随机seed,同时w1和w2用不同的seed保证数值不重复。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:03:09