从 Tensorflow PrefetchDataset 中提取目标

Extract target from Tensorflow PrefetchDataset

我仍在学习 tensorflow 和 keras,我怀疑这个问题有一个非常简单的答案,我只是由于不熟悉而错过了。

我有一个 PrefetchDataset 对象:

> print(tf_test)
$ <PrefetchDataset shapes: ((None, 99), (None,)), types: (tf.float32, tf.int64)>

...由特征和目标组成。我可以使用 for 循环对其进行迭代:

> for example in tf_test:
>     print(example[0].numpy())
>     print(example[1].numpy())
>     exit()
$ [[-0.31 -0.94 -1.12 ... 0.18 -0.27]
   [-0.22 -0.54 -0.14 ... 0.33 -0.55]
   [-0.60 -0.02 -1.41 ... 0.21 -0.63]
   ...
   [-0.03 -0.91 -0.12 ... 0.77 -0.23]
   [-0.76 -1.48 -0.15 ... 0.38 -0.35]
   [-0.55 -0.08 -0.69 ... 0.44 -0.36]]
  [0 0 1 0 1 0 0 0 1 0 1 1 0 1 0 0 0
   ...
   0 1 1 0]

但是,这很慢。我想做的是访问对应于 class 标签的张量,并将其转换为一个 numpy 数组、一个列表或任何可以输入 scikit-learn 的 class 的可迭代对象化验报告 and/or 混淆矩阵:

> y_pred = model.predict(tf_test)
> print(y_pred)
$ [[0.01]
   [0.14]
   [0.00]
   ...
   [0.32]
   [0.03]
   [0.00]]
> y_pred_list = [int(x[0]) for x in y_pred]             # assumes value >= 0.5 is positive prediction
> y_true = []                                           # what I need help with
> print(sklearn.metrics.confusion_matrix(y_true, y_pred_list)

...或访问数据,使其可用于 tensorflow 的混淆矩阵:

> labels = []                                           # what I need help with
> predictions = y_pred_list                             # could we just use a tensor?
> print(tf.math.confusion_matrix(labels, predictions)

在这两种情况下,以计算成本不高的方式从原始对象获取目标数据的一般能力将非常有帮助(并且可能有助于我对 tensorflow 和 keras 的基本直觉)。

如有任何建议,我们将不胜感激。

您可以使用 list(ds) 将其转换为列表,然后使用 tf.data.Dataset.from_tensor_slices(list(ds)) 将其重新编译为普通数据集。从那里你的噩梦又开始了,但至少这是其他人以前经历过的噩梦。

请注意,对于更复杂的数据集(例如嵌套字典),您将需要在调用 list(ds) 后进行更多预处理,但这应该适用于您询问的示例。

这远非令人满意的答案,但不幸的是,class 完全没有记录,标准数据集技巧的 none 有效。

您可以将每个 (input, label) 对的输入或标签的使用 map 转换为 select,并将其转换为列表:

import tensorflow as tf
import numpy as np

inputs = np.random.rand(100, 99)
targets = np.random.rand(100)

ds = tf.data.Dataset.from_tensor_slices((inputs, targets))

X_train = list(map(lambda x: x[0], ds))
y_train = list(map(lambda x: x[1], ds))

这是Dataset.prefetch()方法返回的class,是Dataset的subclass。

如果您通过将 ReadConfig 传递给构建器来设置 skip_prefetch=Ture,则返回的类型将改为 _OptionsDataset。

read_config = tfds.ReadConfig(skip_prefetch = True)
dataset_builder.as_dataset(
    ......,
    read_config = read_config,
)

https://www.tensorflow.org/api_docs/python/tf/data/Dataset#prefetch

如果您想保留批次或将所有标签提取为单个张量,您可以使用以下函数:


def get_labels_from_tfdataset(tfdataset, batched=False):

    labels = list(map(lambda x: x[1], tfdataset)) # Get labels 

    if not batched:
        return tf.concat(labels, axis=0) # concat the list of batched labels

    return labels

您可以通过循环 PrefetchDataset 来生成列表,在我的示例中是 train_dataset;

train_data = [(example.numpy(), label.numpy()) for example, label in train_dataset]

因此您可以使用索引分别访问每个示例和标签;

train_data[0][0]
train_data[0][1]

您还可以使用 pandas

将它们转换为具有 2 列的数据框
import pandas as pd
pd.DataFrame(train_data, columns=['example', 'label'])

然后,如果您想将列表转换回 PrefetchFataset,只需使用 ;

dataset = tf.data.Dataset.from_generator(
lambda: train_data, ( tf.string, tf.int32)) # you should define dtypes of yours

您可以检查它是否适用于此;

list(dataset.as_numpy_iterator())

您可以使用 map() 函数一次迭代
ratings.map(lambda x: x["feature name"])