【问题标题】:Fit tf.data.Dataset with from_generator用 from_generator 拟合 tf.data.Dataset
【发布时间】:2022-01-17 17:48:41
【问题描述】:

我正在训练一个神经网络来读取 4 个图像并预测接下来的 4 个图像。由于我有一个庞大的数据集,所以我编写了这个生成器:

def my_gen(array_passed):
    for i in range(len(array_passed)-8):
        x = arr_train_ids[i:i+4]
        x = obtain_data(x) #shape (4,480,480,1)

        y = arr_train_ids[i+4:i+8]
        y = obtain_data(y) #same shape as x
        yield x, y

obtain_data 只是打开文件,加载 4 个 480x480 矩阵并重塑为 (4, 480, 480, 1)。然后,按照这里的帖子,我这样做:

def my_input_fn(array_passed):
    dataset = tf.data.Dataset.from_generator(lambda: my_gen(array_passed),
                   output_types=(tf.float32, tf.float32),
                   ) #using TF2.3, output_signature not valid
    dataset = dataset.batch(1)
    #dataset = dataset.repeat(10)
    return dataset

train_dataset = my_input_fn(arr_train_ids)
val_dataset = my_input_fn(arr_val_ids)
test_dataset = my_input_fn(arr_test_ids)

我不确定是否有必要使用repeat...现在我的代码中已对此进行了注释。

模型,称为rnc,放在此处(为简洁起见,省略,涉及 ConvLSTM 和 Conv3D)。

model = rnc(input_shape=(4, 480, 480, 1))
model.compile(optimizer=tf.keras.optimizers.Adam(lr=3e-4),loss='mae')
history = model.fit(train_dataset, validation_data=val_dataset, epochs=100)

我想训练 1 批数据。理论上,1批数据应该是4个480x480的矩阵,1个通道,(4, 480, 480, 1)作为输入,(4, 480, 480, 1)作为输出。

但是我没有从培训中得到任何东西,我很怀疑。我想知道TF数据集的准备是否是我做的正确的事情。

【问题讨论】:

  • 您检查您的train_dataset 是否真的在生产批次?即,当你尝试input_batch, output_batch = next(iter(train_dataset)) 时,你得到了你所期待的东西吗?
  • 感谢您的回答。是的,我将input_batchoutput_batch 作为形状张量 (1, 4, 480, 480, 1) 获得,理论上应该是正确的。

标签: python tensorflow


【解决方案1】:

如果您从train_dataset 检查了生成的input_batchoutput_batch,它必须工作。
在我的简单生殖示例中,

import tensorflow as tf
import tensorflow.keras as keras

x = tf.random.normal((100, 4, 480, 480, 1)) # Say I have 100 data.
y = tf.random.normal((100, 4, 480, 480, 1))

train_ds = tf.data.Dataset.from_tensor_slices((x, y))
train_ds = train_ds.batch(batch_size=32, drop_remainder=True)

# check whether this dataset really produces the things I want
sample_input_batch, sample_output_batch = next(iter(train_ds))
print(sample_input_batch.shape) # (32, 4, 480, 480, 1)
print(sample_output_batch.shape) # (32, 4, 480, 480, 1)

simple_model = keras.Sequential([
    keras.layers.InputLayer(input_shape=(4, 480, 480, 1)),
    keras.layers.Dense(10, activation='relu'),
    keras.layers.Dense(1, activation='relu')
])

simple_model.compile(loss=keras.losses.MeanSquaredError(),
                    optimizer=keras.optimizers.Adam(),
                    metrics=['mse'])

# check whether the model really produces the thing I expect
sample_predicted_batch = simple_model(sample_input_batch)
print(sample_predicted_batch.shape) # (32, 4, 480, 480, 1)

simple_model.fit(train_ds)
# 3/3 [==============================] - 0s 24ms/step - loss: 1.1743 - mse: 1.1743
# Then it should work!

另外,如果你有一个巨大的数据集,你真的不需要使用tf.data.APIrepeat()方法。

此外,如果您使用repeat() 方法,则必须为某个数字指定steps_per_epoch 参数,否则意味着永远运行。您可以在here 中查看steps_per_epoch

【讨论】:

  • 谢谢,我认为你是对的。除了drop_remainder=True 之外,我的代码是相同的,我认为这是正确的并且我已将其添加到代码中。我想问题出在 NN 中,可能是 ConvLSTM,总是很难训练。我认为你的帖子回答了我的问题。
  • @David,另外,我怀疑数据集非常庞大,当然这取决于您的模型当前使用了多少参数。也许你会减少batch_size.. 即使模型没有训练,你也可以使用自定义训练循环来找出问题所在。
猜你喜欢
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2018-06-29
相关资源
最近更新 更多