-4

我正在使用 Tensorflow Datasets 的tfds.load函数来加载我的数据:

import tensorflow_datasets as tfds
import tensorflow as tf

(raw_train, raw_validation, raw_test), metadata = tfds.load(
    'cats_vs_dogs',
    split=['train[:80%]', 'train[80%:90%]', 'train[90%:]'],
    with_info=True,
    as_supervised=True,
)

现在,我在本地电脑上多了一些猫和狗的图片(例如Cat1.jpg)。我想将它们添加到这些数据中。我怎样才能做到这一点?

请注意,我不仅有一个文件,而且还有很多,而且这只是一个二进制分类示例;同样的问题也适用于多类分类,所以最好也有一个解决方案。

更新:我尝试了不同的方法,比如尝试使用 tf-nightly 和 tf.keras.preprocessing.image_dataset_from_directory 读取图像,但是,不幸的是,这并不容易。存在很多问题,例如生成的数据集处于不同的 dtype 中,无法与原始数据集合并。我没有解决这个问题的办法。我为此付出了很多,因为我真的需要详细的代码,一个可行的解决方案,而不仅仅是一些在理论上如何实现这一点的一般想法。我不需要 image_dataset_from_directory 的解决方案,如果有人有任何解决方案,详细的代码可以工作,我很好。

我不想发布任何代码,因为我认为有更好的方法来解决这个问题。但是,请找到我在这里尝试的方式(在 colab 中):

!pip install tf-nightly
#!pip uninstall tf-nightly

import tensorflow as tf
print(tf.__version__)

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    '/tmp/Test/',
    image_size = (224,224),
    batch_size = 32,
    # label_mode = 'int'
)

tmp 中有一个 Test 文件夹。一个子文件夹 cat 和另一只狗。包括一些来自搜索猫和狗的随机图片。

结果 train_ds 是一个<BatchDataset shapes: ((None, 224, 224, 3), (None,)), types: (tf.float32, tf.int32)>

import os
import shutil

os.listdir("/tmp/Test") #First find where the ".ipynb_checkpoints" is located.

shutil.rmtree("/tmp/Test/.ipynb_checkpoints")

import tensorflow_datasets as tfds
(raw_train, raw_validation, raw_test), metadata = tfds.load(
    'cats_vs_dogs',
    split=['train[:80%]', 'train[80%:90%]', 'train[90%:]'],
    with_info=True,
    as_supervised=True,
)

例如 raw_train 是一个<DatasetV1Adapter shapes: ((None, None, 3), ()), types: (tf.uint8, tf.int64)>.

  def _normalize_img(img, label):
  img = tf.cast(img, tf.float32) / 255.
  img = tf.image.resize(img, (224,224))
  label = tf.cast(label, tf.int64)
  img = tf.cast(img, tf.uint8)
  return (img, label)
  # ds = tfds.load('mnist', split='train', as_supervised=True)
  ds = raw_train.map(_normalize_img)

ds 现在是<DatasetV1Adapter shapes: ((224, 224, 3), ()), types: (tf.uint8, tf.int64)>

test=ds.concatenate(raw_train)

不能解决它,因为数据没有正确匹配/连接。此外,在多类情况下,我无法控制检查标签的匹配。

所以我不需要任何关于如何在理论上实现这一点的一般想法。我需要一个详细的工作解决方案,详细的代码。不仅如此示例中的二进制文件,我还需要它来处理多类问题,因为我也有这个问题。那么如何在多类情况下将“读入标签”与 tfds.load 产生的标签匹配。没有匹配错误,例如混合课程左右。例如,猫变成了马(在猫、狗和马的情况下)。

第二种方式:我还尝试将 ImageDataGenerator 直接指向 raw_train 数据集。如果这可行,我通常可以继续使用 ImageDataGenerator,尽管我实际上并不想要这个。所以我只想将图像添加到 raw_train 数据集。我试过这个:

from tensorflow.keras.preprocessing.image import ImageDataGenerator
train_image_generator = ImageDataGenerator(
    rescale=1./255,
)

train_datagen = train_image_generator.flow_from_directory(
  directory=raw_train,
  target_size=(224, 224),
  shuffle=True,
  batch_size=128,
  class_mode='binary'
)

然后匹配/连接这些数据生成器的结果。但不可能只在 raw_train 上指出这一点,它会给出错误。

4

1 回答 1

-3

返回的对象tfds.load是 的实例tf.data.Dataset。因此,您可以构建tf.data.Dataset本地图像的新实例,然后使用concatenate方法将它们连接在一起。要从磁盘上的图像构建这样的数据集,至少有三种不同的方法:

  • 您可以使用新添加的tf.keras.preprocessing.image_dataset_from_directory功能。目前,这仅适用于tf-nightly. 您可以在此处找到使用此函数的示例。

  • 或者,您可以使用tf.dataAPI 来更好地控制加载过程以及对图像及其标签的进一步转换。是有关如何实现此目的的示例示例。

  • 或者,您可以首先使用任何库/方法作为 Numpy 数组加载图像,并构造另一个与其标签相对应的数组。然后你可以tf.data.Dataset使用方法创建一个实例from_tensor_slices你可以在这里找到一个例子。请注意,如果您有大量图像,则不建议使用此方法(这反过来意味着构造的 Numpy 数组的大小会非常大,因此会浪费数据管道内存或无法构建)。

于 2020-07-18T21:22:36.383 回答