【问题标题】:what is the best practices to train model on BIG dataset在 BIG 数据集上训练模型的最佳实践是什么
【发布时间】:2020-08-18 15:45:44
【问题描述】:

我需要在一个数据集上训练一个模型,该数据集需要比我的 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)中,我描述了一种解决问题的方法——还有其他更好的方法吗,或者它只是解决这个问题的一种方法?

【问题讨论】:

    标签: python tensorflow deep-learning tensorflow2.0 tensorflow2.x


    【解决方案1】:

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

    • 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 参数,但如this guide 所示,tfds 已经为您提供了拆分数据的功能。因此,您只需要获取测试拆分数据集,按上述方式对其进行转换并将其作为validation_data 传递给fit。

    【讨论】:

    • 我不能使用 lambda,因为我需要使用 train_labels = tf.keras.utils.to_categorical(train_labels) 并调整图像大小和其他转换 .... (((
    【解决方案2】:

    方法 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)
    

    【讨论】:

      猜你喜欢
      • 2019-11-30
      • 2016-09-19
      • 2016-11-08
      • 2020-10-16
      • 2015-12-21
      • 2019-07-21
      • 1970-01-01
      • 1970-01-01
      • 2013-06-16
      相关资源
      最近更新 更多