You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:31:22