【问题标题】:Extract data from tensorflow dataset (e.g. to numpy)从 tensorflow 数据集中提取数据(例如到 numpy)
【发布时间】:2021-12-30 19:02:53
【问题描述】:

我正在通过

加载图片
data = keras.preprocessing.image_dataset_from_directory(
  './data', 
  labels='inferred', 
  label_mode='binary', 
  validation_split=0.2, 
  subset="training", 
  image_size=(img_height, img_width), 
  batch_size=sz_batch, 
  crop_to_aspect_ratio=True
)

我也想在非张量流例程中使用获得的数据。因此,我想提取数据,例如到 numpy 数组。我怎样才能做到这一点?我不能使用tfds

【问题讨论】:

    标签: python tensorflow keras tensorflow-datasets


    【解决方案1】:

    我建议取消批处理您的数据集并使用tf.data.Dataset.map:

    import numpy as np
    import tensorflow as tf
    
    dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
    data_dir = tf.keras.utils.get_file('flower_photos', origin=dataset_url, untar=True)
    data_dir = pathlib.Path(data_dir)
    batch_size = 32
    
    train_ds = tf.keras.utils.image_dataset_from_directory(
      data_dir,
      validation_split=0.2,
      subset="training",
      seed=123,
      image_size=(180, 180),
      batch_size=batch_size,
      shuffle=False)
    
    train_ds = train_ds.unbatch()
    images = np.asarray(list(train_ds.map(lambda x, y: x)))
    labels = np.asarray(list(train_ds.map(lambda x, y: y)))
    

    或者按照 cmets 中的建议,您也可以尝试只处理批次并在之后将它们连接起来:

    images = np.concatenate(list(train_ds.map(lambda x, y: x)))
    labels = np.concatenate(list(train_ds.map(lambda x, y: y)))
    

    或者设置shuffle=True并使用tf.TensorArray

    images = tf.TensorArray(dtype=tf.float32, size=0, dynamic_size=True)
    labels = tf.TensorArray(dtype=tf.int32, size=0, dynamic_size=True)
    
    for x, y in train_ds.unbatch():
      images = images.write(images.size(), x)
      labels = labels.write(labels.size(), y)
    
    images = tf.stack(images.stack(), axis=0)
    labels = tf.stack(labels.stack(), axis=0)
    

    【讨论】:

    • 我认为迭代批次并最终将它们连接起来会是一种更快的方法。
    • 是的,当然也是一种选择!
    • 如果我禁用洗牌,下面的答案已经可以了。我想避免这种情况,因为之后我必须对数据进行洗牌。
    【解决方案2】:

    因为tf.keras.utils.image_dataset_from_directory 返回一个Dataset 对象,所以使用tf.data.Dataset.as_numpy_iterator。例如:

    for elem in data.as_numpy_iterator():
      print(elem)
    

    最后,使用tf.data.Dataset 可能是一个更好的主意,因为它更有效。您可以找到更多信息here

    【讨论】:

    • 因此,我必须遍历所有批次,而且我还必须自己将 numpy 张量堆叠在一起 - 听起来很麻烦?没有更简单的方法吗?
    • @Steradiant -- 你总是可以使用np.array(data.as_numpy_iterator()) 来获取你的numpy数组;虽然它不如使用生成器高效。这实际上取决于您使用它的目的;使用普通的tf.data.Dataset 可能有更好的方法。
    • np.array(data.as_numpy_iterator()) 并没有真正起作用。我需要 x 和 y 数据(X_train 和 Y_train)作为 numpy 张量和数组,以便在 tensorflow 之外的算法(例如 sklearn)中使用数据。
    • @Steradiant -- 啊,我明白了。您的X 将是np.concatenate([x for x, y in data], axis=0),您的y 将是np.concatenate([y for x, y in data], axis=0)。您可能需要考虑删除 validation_split=0.2,改用 scikit-learn 中的 test_train_split
    • 非常感谢,这就是我要找的。我更喜欢这种方式,image_dataset_from_directory 已经进行了拆分,因为那时我对 sklearn 和(如果我想实现它)tensorflow NN 有相同的拆分。
    猜你喜欢
    • 2019-10-07
    • 1970-01-01
    • 2016-03-25
    • 2020-11-10
    • 2014-12-21
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 2020-08-18
    相关资源
    最近更新 更多