【发布时间】: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 您是否尝试过提供的解决方案,我认为使用
zipAPI 将是一个好主意。当您使用以下解决方案时,您会遇到什么样的错误?
标签: python pandas tensorflow keras lazy-evaluation