2

我需要在需要比我的 GPU 更多内存的数据集上训练模型。将数据集提供给模型的最佳做法是什么?

这是我的步骤:

  1. 首先,我使用 batch_size 加载数据集
BATCH_SIZE=32

builder = tfds.builder('mnist')
builder.download_and_prepare()
datasets  = builder.as_dataset(batch_size=BATCH_SIZE)
  1. 第二步我准备数据
for record in raw_train_ds.take(1):
    train_images, train_labels = record['image'],  record['label']
    print(train_images.shape)
    train_images  = train_images.numpy().astype(np.float32) / 255.0
    train_labels = tf.keras.utils.to_categorical(train_labels)
  1. 然后我将数据提供给模型
history = model.fit(train_images,train_labels, epochs=NUM_EPOCHS, validation_split=0.2)

但是在第 2 步,我为第一批准备了数据而错过了其余批次,因为 model.fit 超出了循环范围(据我所知,它仅适用于第一批)。
另一方面,我无法删除 take(1) 并在循环下移动 model.fit 方法。因为是的,在这种情况下,我将处理所有批次,但同时 model.fill 将在每次迭代结束时调用,在这种情况下,它也无法正常工作

那么,我应该如何更改我的代码才能使用 model.fit 与大数据集正常工作?你能指出文章,任何文件,或者只是建议如何处理它?谢谢

更新 在我下面的帖子(方法 1)中,我描述了一种解决问题的方法——还有其他更好的方法,还是只有一种方法可以解决这个问题?

4

2 回答 2

2

您可以将整个数据集传递给fit进行训练。正如您在文档中看到的,第一个参数的一个可能值是:

  • 一个tf.data数据集。应该返回一个(inputs, targets)或的元组(inputs, targets, sample_weights)

因此,您只需要将数据集转换为该格式(带有输入和目标的元组)并将其传递给fit

BATCH_SIZE=32

builder = tfds.builder('mnist')
builder.download_and_prepare()
datasets = builder.as_dataset(batch_size=BATCH_SIZE)
raw_train_ds = datasets['train']
train_dataset_fit = raw_train_ds.map(
    lambda x: (tf.cast.dtypes(x['image'], tf.float32) / 255.0, x['label']))
history = model.fit(train_dataset_fit, epochs=NUM_EPOCHS)

这样做的一个问题是它不支持validation_split参数,但是如本指南所示,它tfds已经为您提供了拆分数据的功能。因此,您只需要获取测试拆分数据集,按上述方式对其进行转换并将其传递validation_datafit.

于 2020-05-04T09:43:57.610 回答
1

方法一

感谢@jdehesa 我更改了我的代码:

  1. 加载数据集 - 实际上,它不会将数据加载到内存中,直到从数据集迭代器第一次调用“下一个”。即便如此,我认为迭代器将加载一部分数据(批次),其大小等于 BATCH_SIZE
raw_train_ds, raw_validation_ds = builder.as_dataset(split=["train[:90%]", "train[10%:]"], batch_size=BATCH_SIZE)
  1. 将所有需要的转换收集到一种方法中
def prepare_data(x):
    train_images, train_labels = x['image'],  x['label']
# TODO: resize image
    train_images = tf.cast(train_images,tf.float32)/ 255.0 
    # train_labels = tf.keras.utils.to_categorical(train_labels,num_classes=NUM_CLASSES) 
    train_labels = tf.one_hot(train_labels,NUM_CLASSES) 
    return (train_images, train_labels)
  1. 使用方法td.data.Dataset.map将这些转换应用于批处理(数据集)中的每个元素
train_dataset_fit = raw_train_ds.map(prepare_data)
  1. 然后将此数据集输入 model.fit - 据我了解,model.fit 将遍历数据集中的所有批次。
train_dataset_fit = raw_train_ds.map(prepare_data)
history = model.fit(train_dataset_fit, epochs=NUM_EPOCHS)
于 2020-05-05T06:59:47.453 回答