Performance 如何减少tensorflow数据集输入管道主机设备(cpu)时间(目前约为40%)?

Performance 如何减少tensorflow数据集输入管道主机设备(cpu)时间(目前约为40%)?,performance,tensorflow,profiling,tensorboard,tensorflow-datasets,Performance,Tensorflow,Profiling,Tensorboard,Tensorflow Datasets,我试图复制resnet18论文。在磁盘上的完整Image Net数据集上运行此操作之前,我正在使用TFDS中公开的imagenette/320px数据集进行一些评估运行(imagenet的更小子集,有10个类,已经是.tfrecord格式)_ 注意:这里提供了用于进行培训和跟踪的完整笔记本:只需切换到GPU运行时并运行所有单元格。第二批中已经设置了tensorboard评测。(您也可以使用TPU,但一些keras.layers.experimental.preprocessing层尚不支持TPU

我试图复制resnet18论文。在磁盘上的完整Image Net数据集上运行此操作之前,我正在使用TFDS中公开的
imagenette/320px
数据集进行一些评估运行(imagenet的更小子集,有10个类,已经是
.tfrecord
格式)_

注意:这里提供了用于进行培训和跟踪的完整笔记本:只需切换到
GPU
运行时并运行所有单元格。第二批中已经设置了tensorboard评测。(您也可以使用TPU,但一些
keras.layers.experimental.preprocessing
层尚不支持TPU操作,您必须启用软设备放置。请使用GPU)

输入操作
  • 从输入数据集中读取图像。这些图像通常具有不同的维度,我们需要一些裁剪函数,因为输入张量可以而不是具有不同的维度进行批处理。因此,对于训练,我使用随机裁剪,对于测试/验证数据集,使用中心裁剪
  • random\u crop\u layer=keras.layers.experimental.preprocessing.RandomCrop(224224224)
    中心裁剪层=keras.layers.experimental.preprocessing.CenterCrop(224224)
    @函数(实验性的_松弛_形状=真)#避免回溯
    def系列作物fn(x,y):
    返回随机裁剪层(x),y
    @tf.函数(实验性松弛形状=真)
    def eval_crop_fn(x,y):
    返回中心\裁剪\图层(x),y
    
  • 对输入数据执行一些简单的预处理/增强。这些操作包括重新缩放到0-1,以及根据imagenet上rgb颜色的平均值和标准偏差进行缩放。此外,随机
  • rescaling\u layer=keras.layers.experimental.preprocessing.rescaling(1./255)
    列车预处理=整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备整备([
    重定标度
    ])
    #从https://github.com/tensorflow/models/blob/master/official/vision/image_classification/preprocessing.py
    #从ImageNet训练集计算
    平均值_RGB=(0.485,0.456,0.406)
    标准差分比值=(0.229,0.224,0.225)
    @功能
    def z_评分量表(x):
    回报率(x-平均值)/标准差
    @功能
    def序列预处理fn(x,y):
    返回z_分数量表(训练前(x)),y
    @功能
    def eval_prepoc_fn(x,y):
    返回z_评分量表(评估预处理(x)),y
    
    输入管道
    def get_input_pipeline(输入_ds、bs、裁剪_fn、增强_fn):
    ret_ds=(
    输入数据
    .批次(1)#预裁剪尺寸不同,无法进行批次
    .地图(作物),
    num_parallel_calls=tf.data.experimental.AUTOTUNE)
    .unbatch()
    .批次(bs)
    .map(增强),但增强可以批处理。
    num_parallel_calls=tf.data.experimental.AUTOTUNE)
    )
    退货退货
    #数据集加载
    def load_imagenette():
    列车ds,ds info=tfds.load('imagenette/320px',split='train',as_supervised=True,with_info=True)
    有效的\u ds=tfds.load('imagenette/320px',split='validation',如\u supervised=True)
    返回列车,有效列车,有效列车,有效列车信息。功能['label'].num\u类
    #管道建设
    训练、有效训练、测试、num\u classes=load\u imagenette()
    #用于培训的数据集(注意,我在这里使用预取)
    序列样本=获取输入管线(序列ds、BS、序列裁剪fn、序列预处理fn)。预取(tf.data.experimental.AUTOTUNE)
    有效样本=获取输入管道(有效数据、BS、评估作物、评估预处理)。预回迁(tf.data.experional.AUTOTUNE)
    测试样本=获取输入管道(测试数据、BS、评估作物、评估预处理)。预取(tf.data.experimental.AUTOTUNE)
    
    培训和概况介绍 我使用tensorboard profiler来检查第二批的大小,我得到一个警告,这是一个高输入限制,大约40%的处理浪费在输入上

    对于经典的resnet18型号,您可以将批量大小提高到768,而不会出现OOM错误,这正是我所使用的。使用bs 256的单个步骤大约需要2-3秒

    我还收到一条警告,与1s的批处理时间相比,列车上的批处理大小末端的
    速度较慢,约为1.5秒

    模型培训代码非常简单:

    model.fit(
    训练样本,
    验证数据=有效样本,
    纪元=100,
    批次大小=BS,
    使用多处理=真
    回调=[tensorboard\u回调、model\u checkpoint\u回调、early\u stop\u回调、reduce\u lr\u回调]
    )
    
    并且回调被指定为:

    log\u dir=os.path.join(os.getcwd(),'logs')
    tensorboard\u callback=tensorboard(log\u dir=log\u dir,update\u freq=“epoch”,profile\u batch=2)
    reduce\u lr\u callback=tf.keras.callbacks.reducelronplatform(监视器=val\u loss',因子=0.1,耐心=5,最小lr=0.001,详细=1)
    model_checkpoint_callback=tf.keras.callbacks.ModelCheckpoint(filepath='model.{epoch:02d}-{val_loss:.4f}.h5',
    监视器=“val_损失”,
    verbose=1,
    保存(仅限最佳值=真)
    提前停止回调=keras.callbacks.earlystoping(监视器=val\u loss',耐心=15)
    
    最后,这里是一些tensorboard评测屏幕截图示例。我不知道如何让它运行得更快: