了解在 GPU 上训练分类器时的硬件使用情况

Understanding the Hardware usage when training a Classifier on a GPU

我正在使用 TF 2.0GPU 上借助迁移学习训练猫狗分类器。我使用 Keras ImageDataGenerator 执行数据扩充。在训练模型时,我监控了 GPU、磁盘 (HDD) 和 CPU 的使用情况,并注意到以下内容:-

  1. 对于第一个时期,磁盘使用率保持不变 20-25%。 然而,在纪元结束时,在验证阶段,它飙升至 40-50%。对于随后的时期,磁盘使用情况是 奇怪的是
  2. CPU 利用率在整个时期内处于 ~60%,除了 当它达到 100% 时结束。
  3. 当我加载 任何 Keras 模型(如 VGG16、Xception、InceptionResNetV2 等)时,它们都占用了大约 6.5 gigs 的 VRAM .
  4. 几乎整个 GPU 使用率都保持在 29-30% 不变 一个纪元,预计在结束时达到 70%.

根据这些观察,我做出以下推论:-

  1. 在第一个时期,图像从 HDD 加载到 RAM 8 个批次(batch_size=8),一旦加载了一个批次, CPU 对批次执行数据扩充并将扩充后的批次发送到 GPU 为了训练。现在,当验证阶段到来时,因为有 没有对验证数据执行数据扩充,CPU 可以直接将一批图像从 RAM 传递到 GPU 而无需任何 预处理。因此,开销减少了,所有 3 个即, 磁盘、CPU 和 GPU 以更高的速度工作,因此使用率更高 所有这些都发生在一个纪元结束时。
  2. 对于后续的epochs,因为所有的图像(training+validation) 已经加载到 RAM 中,无需从中获取它 磁盘,因此磁盘使用率保持为零。

然而,有几件事我无法理解:-

  1. Keras Appplications Page中,VGG19尺寸最大 内存占用量(549 MB),我不明白怎么能 这继续消耗大约 6.5 GB 的 VRAM?
  2. 为什么所有型号在运行时都占用相同数量的 VRAM 加载,即使它们在大小方面有很大的不同(两者 总层数和内存占用)?

以下是一些代码片段:-

train_datagen = ImageDataGenerator(rotation_range = 30,
                                   width_shift_range = 0.4,
                                   height_shift_range = 0.4,
                                   shear_range = 0.4,
                                   zoom_range = 0.25,
                                   horizontal_flip = True,
                                   brightness_range = [0.5, 1.5],
                                   preprocessing_function = preprocess_input) 

valid_datagen = ImageDataGenerator(preprocessing_function = preprocess_input)

train_generator = train_datagen.flow_from_dataframe(train_data,
                                                    directory = 'train/',
                                                    x_col = 'Photo',
                                                    y_col = 'Class',
                                                    target_size = (299,299),
                                                    class_mode = 'binary',
                                                    seed = 42,
                                                    batch_size = 8)

validation_generator = valid_datagen.flow_from_dataframe(valid_data,
                                                    directory = 'train/',
                                                    x_col = 'Photo',
                                                    y_col = 'Class',
                                                    target_size = (299,299),
                                                    class_mode = 'binary',
                                                    seed = 42,
                                                    batch_size = 8)

inception_resnet_v2 = InceptionResNetV2(include_top = False,
                                    weights = 'imagenet',
                                    input_shape = (299, 299, 3),
                                    pooling = 'avg',
                                    classes = 2)
inception_resnet_v2.trainable = False

out = Dense(1, activation = 'sigmoid')(inception_resnet_v2.output)

model = Model(inputs = inception_resnet_v2.inputs, outputs = out)

checkpoint = ModelCheckpoint('model.h5',
                             monitor = 'val_accuracy',
                             verbose = 0,
                             save_best_only = True,
                             save_weights_only = False, 
                             mode = 'max',
                             period = 1)

optim = tf.keras.optimizers.Adam(lr = 0.0001)
model.compile(optimizer = optim, loss = 'binary_crossentropy', metrics = ['accuracy'])

hist = model.fit_generator(train_generator,
                           steps_per_epoch = len(train_generator),
                           epochs = 10,
                           callbacks = [checkpoint],
                           validation_data = validation_generator,
                           verbose = 1,
                           validation_steps = len(validation_generator),
                           validation_freq = 1)

如果有人能回答我的问题并指出我的推论是正确的还是错误的,我将不胜感激。

谢谢。

默认情况下,TensorFlow 将几乎所有 GPU 的所有 GPU 内存(受 CUDA_VISIBLE_DEVICES 约束)映射到进程可见。

你可以限制相同的使用,

import tensorflow as tf
from keras import backend as k

config = tf.ConfigProto() # TensorFlow wizardry
config.gpu_options.allow_growth = True # Don't pre-allocate memory; allocate as-needed
config.gpu_options.per_process_gpu_memory_fraction = 0.95 # Only allow a total fraction the GPU memory to be allocated
k.tensorflow_backend.set_session(tf.Session(config=config)) # Create a session with the above options specified.

您也可以查看此以获取更多信息:https://www.tensorflow.org/guide/gpu