分配具有形状的张量时出现 OOM - 如何获得更多 GPU 内存

Oss*_*ssz 1 neural-network jupyter keras tensorflow jupyter-notebook

[在 Jupyter Lab 环境上运行] 在张量流上训练 CNN 时:

 history = model.fit(
        train_generator,
        steps_per_epoch=3,
        epochs=5,
        verbose = 1,
Run Code Online (Sandbox Code Playgroud)

'OOM when allocating tensor with shape'当我运行我的算法时,我得到了一个。

据我了解,这意味着我没有耗尽足够的 GPU 内存。如何连接 Jupyter 上的服务器以访问更多内存来运行我的训练神经网络?

我使用以下包和代码来加载图像:

from tensorflow.keras.preprocessing.image import ImageDataGenerator

# Conduct pre-processing on the data to read and feed the images from the directories into the CNN

# Re-scale data as pixels have value of 0-255
train_datagen = ImageDataGenerator(rescale=1/255)
validation_datagen = ImageDataGenerator(rescale=1/255)

# Feed training dataset images in via batches of 250
train_generator = train_datagen.flow_from_directory (
    'Users\cats-or-dogs\PetImages', # Directory with training set images
    target_size=(300, 300), # Re-size target images
    batch_size = 425, #mini-batch of 250 to make CNN more efficient
    class_mode = 'binary'
)
Run Code Online (Sandbox Code Playgroud)

M.I*_*nat 5

请告诉我它是否有效。通常我们可以在导入必要的包后启用混合精度,如下所示。它允许更快的计算并且消耗更少的 GPU 内存。因此我们也可以增加批量大小。但硬件应该支持这样的设施,所以请先检查它们。混合Keras 精度( mp ) API 在 中可用TensorFlow 2.x开个玩笑,如果你想获得更多 GPU 内存,那就添加更多 GPU。因此你可以进行多 GPU训练。但要搭配单 GPU,mp是技巧之一。否则,减小批量大小可能会解决 OOM 问题。

policy = tf.keras.mixed_precision.experimental.Policy('mixed_float16')
tf.keras.mixed_precision.experimental.set_policy(policy)
Run Code Online (Sandbox Code Playgroud)

引用自官方文档。在 GPU 上使用混合精度时的性能提示。

增加批量大小

如果不影响模型质量,请尝试在使用时以双倍的批量大小运行mixed-precision。由于float16张量使用一半的内存,这通常允许您将批量大小加倍而不会耗尽内存。增加批量大小通常会增加训练吞吐量,即模型每秒可以运行的训练元素数。


此外,我们还可以gc.collect()在每个 epoch 之后使用它来收集垃圾,这将释放一些内存空间,见下文。还有del未使用的大变量,可能会消耗合理的内存空间。

import tensorflow as tf
import gc

class RemoveGarbaseCallback(tf.keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs=None):
    gc.collect()
...
...
model.fit(train_generator, ...
callbacks=[RemoveGarbaseCallback()])
Run Code Online (Sandbox Code Playgroud)

但是,我们可以使用clear_session()while using tf.keras,这将清理所有内容。如果我们在循环内创建模型,建议这样做。因此,我们可以在每次迭代时使用以下代码片段。

for _ in range(no_of_iteration):
   # With `clear_session()` called at the beginning,
   # Keras starts with a blank state at each iteration
   # and memory consumption is constant over time.
   tf.keras.backend.clear_session() # Resets all state generated by Keras

   train_generator = ...
   valid_generator = ...
   
   model =  create_model()
   history = model.fit(.., callbacks=[RemoveGarbaseCallback()])

   # free up some memory space
   del model
   del train_set, valid_set
Run Code Online (Sandbox Code Playgroud)

更新

正如您所遇到的:

UnidentifiedImageError: 
cannot identify image file <_io.BytesIO object at 0x0000019F9BC1E950> 
Run Code Online (Sandbox Code Playgroud)

当训练目录中可能存在一些不受支持的文件时,就会发生这种情况。要检查文件格式,请运行以下函数:

UnidentifiedImageError: 
cannot identify image file <_io.BytesIO object at 0x0000019F9BC1E950> 
Run Code Online (Sandbox Code Playgroud)

在这种情况下,从侧面来看,它应该包含图像文件格式,即:jpgjpegpng。现在的问题是在jupyter环境上工作时,它会自动保存.ipynb检查点。因此,可能它与您的情况下的其他图像文件一起保存到训练目录中。这是不支持的。在这种情况下,您所要做的就是更改项目目录或更改保存位置。一些指针:1 , 2

如果您使用自定义数据生成器,我建议使用tryexcept绕过不支持的文件。同样,在flow_from_dataframe代替 中flow_from_directory,我们可以通过x_col="id"y_col="label"具体来说,在这种情况下我们可能不会遇到这样的问题。