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

使用Keras Tuner时遇TensorFlow错误:迭代器图与数据集创建图不一致

Keras Tuner搭配TensorFlow Dataset时的图不匹配错误解决

问题描述

使用Keras Tuner进行超参数调优,以TensorFlow BatchDataset作为输入时,触发以下错误:

ValueError: The graph of the iterator is different from the graph the dataset: Tensor("PrefetchDataset:0", shape=(), dtype=variant) was created in. If you are using the Estimator API, make sure that no part of the dataset returned by the "input_fn" function is defined outside the "input_fn" function. Otherwise, make sure that the dataset is created in the same graph as the iterator.

错误触发于tuner.search(train_data, epochs=100, shuffle=False, validation_data=val_data)行,且不使用Keras Tuner时,相同模型与数据集可正常运行。

原代码

batch_size = 5
train_data = keras.utils.timeseries_dataset_from_array(
    x_train_scaled,
    y_train_scaled,
    1,
    batch_size=batch_size,
    shuffle=False
)

val_data = keras.utils.timeseries_dataset_from_array(
    x_val_scaled,
    y_val_scaled,
    1,
    batch_size=batch_size,
    shuffle=False
)

test_data = keras.utils.timeseries_dataset_from_array(
    x_test_scaled,
    y_test_scaled,
    1,
    batch_size=batch_size,
    shuffle=False
)

# design network
def build_model(hp):
    model = keras.Sequential()
    model.add(keras.layers.LSTM(hp.Choice('units', [8, 16]), activation='relu', return_sequences=True, input_shape=(x_train.shape[1], x_train.shape[2])))
    model.add(keras.layers.LSTM(hp.Choice('units', [8, 16]), activation='relu', return_sequences=True))
    model.add(keras.layers.LSTM(hp.Choice('units', [8, 16]), activation='relu'))
    model.add(keras.layers.Dense(1))
    model.compile(loss='mae', optimizer='adam')
    return model

tuner  = keras_tuner.RandomSearch(
    build_model,
    objective='val_loss',
    max_trials=100)

tuner.search(train_data, epochs=100, shuffle=False, validation_data=val_data)
best_model = tuner.get_best_models()[0]

错误原因

TensorFlow的图上下文不一致导致:全局上下文创建的Dataset对象,与Keras Tuner每个trial中构建模型/迭代器的新图上下文不匹配,引发迭代器与数据集的图冲突。

解决方案

方案一:将Dataset转换为Numpy数组

把BatchDataset转换为numpy数组,Keras Tuner对numpy数组的处理不存在图上下文问题:

import numpy as np

# 转换训练集
x_train_list = []
y_train_list = []
for x_batch, y_batch in train_data:
    x_train_list.append(x_batch.numpy())
    y_train_list.append(y_batch.numpy())
x_train_final = np.concatenate(x_train_list, axis=0)
y_train_final = np.concatenate(y_train_list, axis=0)

# 转换验证集
x_val_list = []
y_val_list = []
for x_batch, y_batch in val_data:
    x_val_list.append(x_batch.numpy())
    y_val_list.append(y_batch.numpy())
x_val_final = np.concatenate(x_val_list, axis=0)
y_val_final = np.concatenate(y_val_list, axis=0)

# 执行超参搜索
tuner.search(x_train_final, y_train_final, epochs=100, shuffle=False, validation_data=(x_val_final, y_val_final))

方案二:在搜索时动态创建Dataset

将数据集的创建逻辑封装为函数,在tuner.search时调用函数生成Dataset,保证数据集与迭代器处于同一图上下文:

def create_train_dataset():
    return keras.utils.timeseries_dataset_from_array(
        x_train_scaled,
        y_train_scaled,
        sequence_length=1,
        batch_size=batch_size,
        shuffle=False
    )

def create_val_dataset():
    return keras.utils.timeseries_dataset_from_array(
        x_val_scaled,
        y_val_scaled,
        sequence_length=1,
        batch_size=batch_size,
        shuffle=False
    )

# 执行超参搜索
tuner.search(create_train_dataset(), epochs=100, shuffle=False, validation_data=create_val_dataset())

方案三:禁用即时执行(不推荐)

通过禁用TensorFlow的即时执行,强制使用静态图模式,避免图上下文冲突:

import tensorflow as tf
tf.compat.v1.disable_eager_execution()

# 后续原代码保持不变...

此方法可能影响其他依赖即时执行的代码逻辑,仅作为备选方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:59:56