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

TensorFlow含激活函数的LSTM固定随机种子后无法复现结果求助

带激活函数的LSTM模型结果无法复现问题

我是深度学习入门者,接触DL仅一个月。在学习LSTM模型时,尝试通过固定随机种子保证结果可复现,但在Google Colab CPU环境(TensorFlow 2.13.0)中,重启运行时后仍无法得到相同结果。排查发现,仅当LSTM模型添加激活函数时会出现不可复现,移除激活函数则正常。


带激活函数的固定种子LSTM代码(不可复现)

import os
os.environ["PYTHONHASHSEED"] = '0'
os.environ['TF_DETERMINISTIC_OPS'] = '1'
os.environ['TF_CUDNN_DETERMINISTIC'] = '1'
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = ""

import numpy as np
import random as rn
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout, Activation
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.optimizers import Adam


def seed_everything(seed=42):
    np.random.seed(seed)
    tf.random.set_seed(seed)
    rn.seed(seed)
    tf.keras.utils.set_random_seed(seed)

    tf.config.experimental.enable_op_determinism()
    config = tf.compat.v1.ConfigProto(
        intra_op_parallelism_threads=1,
        inter_op_parallelism_threads=1
    )
    session = tf.compat.v1.Session(config=config)
    tf.compat.v1.keras.backend.set_session(session)


def create_lstm_model():
    seed_everything()

    model = tf.keras.Sequential([
        tf.keras.layers.LSTM(63, input_shape=(3, 1),
                            kernel_initializer='glorot_uniform', recurrent_initializer='glorot_uniform',
                             dropout=0.11, activation='relu', return_sequences=True),
        tf.keras.layers.LSTM(63, input_shape=(3, 1), kernel_initializer='glorot_uniform', recurrent_initializer='glorot_uniform',
                             dropout=0.11,  activation='relu'),
        tf.keras.layers.Dense(1, kernel_initializer='glorot_uniform')
    ])

    return model


seed_everything()

input_data = np.random.rand(100, 3, 1)
target_data = np.random.rand(100, 1)

for i in range(4):
    print(f"Case {i + 1}:")

    model = create_lstm_model()

    indices = np.arange(len(input_data))
    np.random.shuffle(indices)
    input_data_shuffled = input_data[indices]
    target_data_shuffled = target_data[indices]

    optimizer = tf.keras.optimizers.Adam(learning_rate=0.002)
    model.compile(optimizer=optimizer, loss='mse')

    early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)

    model.fit(input_data_shuffled, target_data_shuffled, epochs=100, batch_size=32, verbose=0, validation_split=0.2, callbacks=[early_stopping])

    loss = model.evaluate(input_data, target_data, verbose=0)
    print(f"Loss: {loss}")

移除激活函数的可复现代码

def create_lstm_model():
    seed_everything()

    model = tf.keras.Sequential([
        tf.keras.layers.LSTM(63, input_shape=(3, 1),
                            kernel_initializer='glorot_uniform', recurrent_initializer='glorot_uniform',
                             dropout=0.11, return_sequences=True),
        tf.keras.layers.LSTM(63, input_shape=(3, 1), kernel_initializer='glorot_uniform', recurrent_initializer='glorot_uniform',
                             dropout=0.11),
        tf.keras.layers.Dense(1, kernel_initializer='glorot_uniform')
    ])

    return model

尝试的外部方法(可复现但性能骤降)

seed_everything()

model = tf.keras.Sequential([
    tf.keras.layers.LSTM(63, input_shape=(3, 1),
                        kernel_initializer='glorot_uniform', recurrent_initializer='glorot_uniform',
                         dropout=0.11, return_sequences=True),
    tf.keras.layers.ReLU(),
    tf.keras.layers.LSTM(63, input_shape=(3, 1), kernel_initializer=GlorotUniform(seed=42), recurrent_initializer=GlorotUniform(seed=42),
                         dropout=0.11),
    tf.keras.layers.ReLU(),
    tf.keras.layers.Dense(1, kernel_initializer=GlorotUniform(seed=42))
])

return model

问题原因与解决办法

  1. 核心原因:TensorFlow中LSTM层内置激活函数时,CPU环境下部分并行运算的确定性控制未完全覆盖;而拆分激活函数为独立层时,重复设置种子导致初始化逻辑混乱,进而大幅影响模型性能。

  2. 正确复现方案:

    • 种子初始化全局仅执行一次,不要在模型创建函数内重复调用
    • 保持LSTM层内置激活函数,强化确定性配置的顺序与完整性
    • 彻底限制TensorFlow线程数,避免并行运算引入随机性
  3. 修正后的代码示例

# 先设置环境变量,再导入任何TensorFlow相关库
import os
os.environ["PYTHONHASHSEED"] = '0'
os.environ['TF_DETERMINISTIC_OPS'] = '1'
os.environ['TF_CUDNN_DETERMINISTIC'] = '1'
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = ""

import numpy as np
import random as rn
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.optimizers import Adam

# 全局仅初始化一次种子
def seed_everything(seed=42):
    np.random.seed(seed)
    rn.seed(seed)
    tf.keras.utils.set_random_seed(seed)
    tf.config.experimental.enable_op_determinism()
    # 强制单线程运行,彻底消除并行随机性
    tf.config.threading.set_intra_op_parallelism_threads(1)
    tf.config.threading.set_inter_op_parallelism_threads(1)

seed_everything()

def create_lstm_model():
    # 此处不再重复初始化种子
    model = tf.keras.Sequential([
        tf.keras.layers.LSTM(63, input_shape=(3, 1),
                            kernel_initializer='glorot_uniform', recurrent_initializer='glorot_uniform',
                             dropout=0.11, activation='relu', return_sequences=True),
        tf.keras.layers.LSTM(63, kernel_initializer='glorot_uniform', recurrent_initializer='glorot_uniform',
                             dropout=0.11, activation='relu'),
        tf.keras.layers.Dense(1, kernel_initializer='glorot_uniform')
    ])
    return model

# 全局生成数据,避免循环内重复生成引入随机性
input_data = np.random.rand(100, 3, 1)
target_data = np.random.rand(100, 1)

for i in range(4):
    print(f"Case {i + 1}:")
    model = create_lstm_model()
    
    indices = np.arange(len(input_data))
    np.random.shuffle(indices)
    input_data_shuffled = input_data[indices]
    target_data_shuffled = target_data[indices]

    optimizer = tf.keras.optimizers.Adam(learning_rate=0.002)
    model.compile(optimizer=optimizer, loss='mse')

    early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
    model.fit(input_data_shuffled, target_data_shuffled, epochs=100, batch_size=32, verbose=0, validation_split=0.2, callbacks=[early_stopping])

    loss = model.evaluate(input_data, target_data, verbose=0)
    print(f"Loss: {loss}")
  1. 关键注意事项
    • 环境变量必须在导入TensorFlow前设置,否则不生效
    • 不要手动给每个初始化器单独设种子,tf.keras.utils.set_random_seed会统一管理所有内置初始化器的种子
    • CPU环境下必须限制线程数为1,这是消除并行随机性的核心步骤

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:54:59