【问题标题】:How do I predict on more than one batch from a Tensorflow Dataset, using .predict_on_batch?如何使用 .predict_on_batch 从 Tensorflow 数据集中预测多个批次?
【发布时间】:2020-04-24 12:49:51
【问题描述】:

正如问题所说,我只能使用 model.predict_on_batch() 从我的模型中进行预测。如果我使用 model.predict(),Keras 会尝试将所有内容连接在一起,但这不起作用。
对于我的应用程序(序列到序列模型),动态分组更快。但即使我在 Pandas 中完成了它,然后只使用 Dataset 填充批次,.predict() 仍然不应该工作?

如果我可以让 predict_on_batch 工作,那么这就是工作。但我只能预测第一批数据集。我如何获得其余的预测?我不能遍历数据集,我不能消费它......

这是一个较小的代码示例。该组与标签相同,但在现实世界中,它们显然是两个不同的东西。有 3 个类,一个序列中最多 2 个值,每批 2 行数据。有很多 cmets,我从 StackOverflow 的某个地方切掉了部分窗口。我希望它对大多数人来说是相当清晰的。

如果您对如何改进代码有任何其他建议,请发表评论。但是不,这根本不是我的模型的样子。所以对那部分的建议可能没有帮助。

编辑:Tensorflow 2.1.0 版

import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Bidirectional, Masking, Input, Dense, GRU
import random
import numpy as np

random.seed(100)
# input data
feature = list(range(3, 14))
# shuffle data
random.shuffle(feature)
# make label from feature data, +1 because we are padding with zero
label = [feat // 5 +1 for feat in feature]
group = label[:]
# random.shuffle(group)
max_group = 2
batch_size = 2

print('Data:')
print(*zip(group, feature, label), sep='\n')

# make dataset from data arrays
ds = tf.data.Dataset.zip((tf.data.Dataset.from_tensor_slices({'group': group, 'feature': feature}), 
                          tf.data.Dataset.from_tensor_slices({'label': label})))
# group by window
ds = ds.apply(tf.data.experimental.group_by_window(
    # use feature as key (you may have to use tf.reshape(x['group'], []) instead of tf.cast)
    key_func=lambda x, y: tf.cast(x['group'], tf.int64),
    # convert each window to a batch
    reduce_func=lambda _, window: window.batch(max_group),
    # use batch size as window size
    window_size=max_group))

# shuffle at most 100k rows, but commented out because we don't want to predict on shuffled data
# ds = ds.shuffle(int(1e5)) 
ds = ds.padded_batch(batch_size,
                     padded_shapes=({s: (None,) for s in ['group', 'feature']}, 
                                    {s: (None,) for s in ['label']}))
# show dataset contents
print('Result:')
for element in ds:
    print(element)

# Keras matches the name in the input to the tensor names in the first part of ds
inp = Input(shape=(None,), name='feature')
# RNNs require an additional rank, even if it is a degenerate dimension
duck = tf.expand_dims(inp, axis=-1)
rnn = GRU(32, return_sequences=True)(duck)
# again Keras matches names
out = Dense(max(label)+1, activation='softmax', name='label')(rnn)
model = Model(inputs=inp, outputs=out)
model.summary()
model.compile(loss='sparse_categorical_crossentropy', metrics=['accuracy'])

model.fit(ds, epochs=3)

model.predict_on_batch(ds)

【问题讨论】:

  • 您的问题自相矛盾。您可以向predict_on_batch 提供任意数量的样本。那么,为什么不做一个更大的批次呢?
  • 如果我将批量大小设为 200'000,那么每个序列都将被填充到最长序列的长度。这真的不可行。另外,我需要模型以某种方式以 200'000 的批量运行。 .predict() 的 Keras 默认值为 32。
  • 除非您拥有 GPU 集群,否则您永远无法运行如此大的批量。
  • 是的,我需要做多个预测。不,我真的无法想象有人会以如此大的批量运行任何模型。特别是对于批量大小完全不相关的推理。是的,我有几个 2080,但这还不够。现在我真的只能想象为每个批次制作一个新的数据集来预测,这绝对不是他们的重点。

标签: python tensorflow keras tensorflow-datasets seq2seq


【解决方案1】:

您可以像这样遍历数据集,记住典型符号中的“x”和“y”是什么:

for item in ds:
    xi, yi = item
    pi = model.predict_on_batch(xi)
    print(xi["group"].shape, pi.shape)

当然,这会单独预测每个元素。否则,您必须自己定义批次,将匹配的形状批处理在一起,因为批次大小本身是可变的。

【讨论】:

  • 非常感谢!我真的需要指出等效的 Python 循环不起作用:for ex in ds: pi = model.predict_on_batch([ex[0]]) print(ex[0]["group"].shape, pi.shape ) 我不了解 Dataset 或他们在用它做什么。作为 Spark 的替代品,这个想法非常非常好,但它需要发挥作用。
猜你喜欢
  • 1970-01-01
  • 2021-12-20
  • 2018-04-12
  • 2018-09-17
  • 1970-01-01
  • 1970-01-01
  • 2018-08-27
  • 2019-01-30
  • 1970-01-01
相关资源
最近更新 更多