【问题标题】:Tensorflow 2.0 Create a Dataset to feed a model with multiple inputs of different shapes on lazy evaluationTensorflow 2.0 创建一个数据集以在惰性评估中为模型提供不同形状的多个输入
【发布时间】:2020-11-16 04:45:53
【问题描述】:

我有一个带有两个不同形状输入的 keras 模型。一方面采用少量分类特征,而另一种采用长度为PAST_HISTORY 的多个时间序列。输出也是多个时间序列:

# Categorical data input
input_ct = keras.Input(shape=(len(categ_cols),),
                       name='categorical_input')

# Timeseries input
input_ts = keras.Input(shape=(PAST_HISTORY, len(series_cols)),
                       name='timeseries_input')

...

model = keras.models.Model(inputs=[input_ct, input_ts], outputs=outputs)

我使用 pandas DataFrame 和一些 tf.data.Dataset 操作为每个输入和输出创建了一个数据集。

df_ts = df[series_cols][:-FUTURE_TARGET]
ts_batch = lambda window: window.batch(PAST_HISTORY)
time_series_data = tf.data.Dataset.from_tensor_slices(df_ts)\
    .window(PAST_HISTORY, 1, 1, True)\
    .flat_map(ts_batch)

df_cat = df[categ_cols][PAST_HISTORY - 1:-FUTURE_TARGET]
date_data = tf.data.Dataset.from_tensor_slices(df_cat)

df_target = df[target_cols][PAST_HISTORY:]
target_batch = lambda window: window.batch(FUTURE_TARGET)
target_data = tf.data.Dataset.from_tensor_slices(df_target)\
    .window(FUTURE_TARGET, 1, 1, True)\
    .flat_map(target_batch)

为了创建最终的数据集,我使用了一个生成器:

def generator():
    for d1, d2, t in zip(date_data, time_series_data, target_data):
        yield {"categorical_input": d1, "timeseries_input": d2}, tf.transpose(t)

dataset = tf.data.Dataset.from_generator(generator,
    output_types=(
        {'categorical_input': tf.int64, 'timeseries_input': tf.float64},
        tf.float64),
    output_shapes=(
        {'categorical_input': (len(categ_cols),),'timeseries_input': (PAST_HISTORY, len(series_cols))},
        (len(target_cols), FUTURE_TARGET),))

这很奏效,我设法通过调用model.fit 训练了一个急切执行模型。然而,现在我试图从这个模型创建一个Estimator,数据集的创建不再起作用,因为它隐式地使用了在惰性评估中不允许的__iterator__ 函数。具体问题在于生成器上的zip 操作。

我尝试使用以下代码在没有生成器的情况下创建相同的数据集:

dataset = tf.data.Dataset.from_tensors(
        ({'categorical_input': date_data, 'timeseries_input': time_series_data}, target_data)
)

当我尝试调用 estimator.train 时,这会导致我出现以下错误:

TypeError: Failed to convert object of type <class 'tensorflow.python.data.ops.dataset_ops._NestedVariant'> to Tensor.
Contents: <tensorflow.python.data.ops.dataset_ops._NestedVariant object at 0x7f5bf84a97f0>.
Consider casting elements to a supported type.

解决这个错误的方法是什么?或者有没有另一种方法来构造这个数据集,而不必在数据集上调用迭代器?

另外,我尝试转换数据集并在窗口化数据集上收到以下错误:

TypeError: Failed to convert object of type <class 'tensorflow.python.data.ops.dataset_ops.FlatMapDataset'> to Tensor.
Contents: <FlatMapDataset shapes: (None, 2), types: tf.float64>.
Consider casting elements to a supported type.

虚拟数据:

df = pd.DataFrame(data={
        'ts_1': np.random.rand(10000),
        'ts_2': np.random.rand(10000),
        'ts_objective': np.random.rand(10000),
        'cat_1': np.random.randint(1, 10 + 1, 10000),
        'cat_2': np.random.randint(1, 25 + 1, 10000),
        'cat_3': np.random.randint(1, 30 + 1, 10000),
        'cat_4': np.random.randint(1, 50 + 1, 10000)})

categ_cols = ['cat_1', 'cat_2', 'cat_3', 'cat_4']
series_cols = ['ts_1', 'ts_2']
target_cols = ['ts_objective']

PAST_HISTORY = 24
FUTURE_TARGET = 8

【问题讨论】:

  • 能否提供您在 google colab 上的代码供我调试?我对如何解决有一些想法,但必须先进行测试。
  • @PrateekBhatt 抱歉,我使用的数据是机密的,所以我无法提供 google colab 链接
  • 我明白这一点,但即使是使用np.random 的虚拟数据。只是为了了解您到底在处理什么。因为只有这么多的代码,每个人都可以猜测可能是什么解决方案,但几乎没有人能肯定地说出来。所以这就是我要求分享一些东西的原因,以便我们可以调试您的解决方案。我希望我对你有意义。谢谢
  • 至少提供一个输入的小例子,以便我们可以运行和调试代码。否则仅通过检查代码很难找到错误。
  • @HeladioAmaya 您是否尝试过提供的解决方案,我认为使用zip API 将是一个好主意。当您使用以下解决方案时,您会遇到什么样的错误?

标签: python pandas tensorflow keras lazy-evaluation


【解决方案1】:

您可以在不使用生成器的情况下构建所需的数据集(而且速度更快),仅使用 Dataset 操作:

import tensorflow as tf

date_data = ...
time_series_data = ...
target_data = ...

def data_tx(d1, d2, t):
    return {"categorical_input": d1, "timeseries_input": d2}, tf.transpose(t)
dataset = tf.data.Dataset.zip((date_data, time_series_data, target_data)).map(data_tx)

【讨论】:

  • 效果很好!只需要删除tf.transpose 操作,我觉得这很奇怪,因为它在使用生成器时需要它,但显然通过这种方式这样做是没有必要的。非常感谢!
猜你喜欢
  • 2019-10-14
  • 2016-02-13
  • 2021-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多