为何model.fit比循环调用model.train_on_batch训练数据集更快?
关于model.fit与train_on_batch训练速度差异的疑问
使用model.fit训练一个epoch的速度比循环调用model.train_on_batch快2-3倍,我对此感到困惑——一直以来都被告知二者功能相同,但两种方法的GPU使用率一致,找不到额外耗时的来源。
编辑补充:当模型规模增大时,二者的速度差异会消失,这表明差异源于内存管理。模型越大,加载下一批数据的时间占比越低;而示例中的小型网络因前向/反向传播几乎瞬间完成,内存分配占据了总耗时的较大比例。model.fit可一次性获取全部数据,或许只需通过指针遍历?
以下是测试两种方式的极简代码:
from tensorflow.keras.models import Model from tensorflow.keras.optimizers import Adam from tensorflow.keras.layers import Input, Conv2D, Flatten, Dense import numpy as np import time import tensorflow as tf def makeNet(): img = Input(shape=(28, 28, 1)) x = Conv2D(128, 3, activation="relu", strides=2, padding="same")(img) x = Conv2D(64, 3, activation="relu", strides=2, padding="same")(x) x = Conv2D(32, 3, activation="relu", strides=2, padding="same")(x) x = Flatten()(x) x = Dense(10, activation="sigmoid")(x) model = Model(img, x) opt = Adam() model.compile(loss='mse', optimizer=opt) return model (digits, labels), (_, _) = tf.keras.datasets.mnist.load_data() labels = labels.astype("float32") / 10 digits = np.expand_dims(digits, -1).astype("float32") / 255 bs = 128 model = makeNet() while True: st = time.perf_counter() model.fit(digits, labels, batch_size = bs, epochs=1) # remove the above line and uncomment lines below to test the train on batch version # for i in range(len(digits) // bs): # x = digits[i * bs : i * bs + bs] # y = labels[i * bs : i * bs + bs] #model.train_on_batch(x, y) print('time =', time.perf_counter() - st)
我已尝试两种不同模型,结果一致。曾查看fit()的源码,但代码结构复杂难以理解。
我的困境在于,由于数据集无法全部放入内存,且我希望以比每个epoch更高的频率可视化结果,因此一直使用train_on_batch。是否可以让逐批次训练达到与fit()相同的速度?是什么让fit()如此高效?
内容的提问来源于stack exchange,提问作者Frobot
相关产品推荐
相关产品推荐

