是否可以在循环中使用"model.fit()" "for"在每次迭代中更改训练数据



我有一个很大的数据集,它不适合内存。因此,在训练时,正在使用 SSD,并且纪元花费了太多时间。

我将我的数据集 9 保存.npz文件的一部分。我选择第一部分(第 0 部分(作为验证部分,我没有在训练中使用。

我使用下面的代码,accval_acc结果都很好。但我觉得我在某个地方犯了大错误。我没有看到任何这样的例子

for part in range(1,9):
X_Train, Y_Train = loadPart(part)
history = model.fit(X_Train, Y_Train, batch_size=128, epochs=1, verbose=1)

并且我还加载第 0 部分作为测试数据

val_loss, val_acc = model.evaluate(X_Test, Y_Test)

我试图在训练数据集的每个部分后检查val_acc,我观察到val_acc在增加。

您能否让我知道这种用法是合法还是非法,为什么?

编辑:

我尝试了fit_generator但它在训练期间仍然使用磁盘,预计到达时间约为 2,500 小时。(在整个数据集的 model.fit 中,每个纪元大约需要 30 分钟(我使用以下代码:

model.fit_generator(generate_batches()), steps_per_epoch=196000,epochs=10)
def generate_batches(): 
for part in range(1,9): 
x, y = loadPart(part) yield(x,y)
def loadPart(part): 
data = np.load('C:/FOLDER_PATH/'+str(part)+'.npz') 
return [data['x'], data['y']

X 数据形状为 (196000,1536,1(

编辑2: 我在 [github]( https://github.com/keras-team/keras/issues/4446(。它说多次调用model.fit()是可以的,但我仍然不确定后面会发生什么。多次调用model.fit()和对整个数据集调用一次有什么区别。

如果您的模型不适合 RAM,keras 文档建议如下(https://keras.io/getting-started/faq/#how-can-i-use-keras-with-datasets-that-don't-fit-in-memory(:

您可以使用 model.train_on_batch(x, y( 和 model.test_on_batch(x, y( 进行批量训练。请参阅模型文档。

或者,您可以编写一个生成器来生成成批的训练数据,并使用方法 model.fit_generator(data_generator、steps_per_epoch、epochs(。

这意味着您可以尝试在 SSD 上进一步将训练数据拆分为 128 个批次,然后执行以下操作:

import glob
import numpy as np
def generate_batches(data_folder):
while True:
batches_paths = glob.glob("%s/*.npz" % data_folder)
for batch_path in batches_paths:
with np.load(batch_path) as batch:
x, y = preprocess_batch(batch)
yield (x, y)

model.fit_generator(generate_batches("/your-data-folder"), steps_per_epoch=10000, epochs=10)

preprocess_batch函数将负责从每个 .npz 文件中提取 x 和 y,fit_generator 函数中的 steps_per_epoch 参数应该是数据样本数的舍入值除以批大小。

更多信息:

  • https://keras.io/models/sequential/#fit_generator
  • https://www.pyimagesearch.com/2018/12/24/how-to-use-keras-fit-and-fit_generator-a-hands-on-tutorial/

您也可以使用 dask,如果您有一个不适合 RAM 的集合,默认情况下会将数据分成更小的部分

如果您按照问题中的描述进行训练,并且在一个会话中进行了训练,则没有区别。但是,如果您在多个会话中进行训练并从以前的训练中继续,那么您应该在每个 epoch 之后保存您的模型(即,在 1 个 epoch 中通过 9 组进行训练(,或者在您的情况下,您可以在每组数据集之后保存(即,在 9 个数据集中的每 1 个之后(并在继续训练之前在每个会话中使用model.load_weights("path to model")加载权重。

您可以使用model.save("path to directory")在每个纪元后保存模型。

最新更新