Tensorflow2.0:GPU 在超参数调整循环期间内存不足

2024-01-24

我正在尝试对使用 GPU 扩展的 Tensorflow 2.0 编写的卷积神经网络进行一些超参数调整。

我的系统设置是:

  • Windows 10 64 位
  • GeForce RTX2070,8GB
  • 张量流 2.0-测试版
  • CUDA 10.0正确安装(我希望deviceQuery.exe和bandwidthTest.exe顺利通过)

我的神经网络有 75.572.574 个参数,我正在 3777 个样本上对其进行训练。在一次运行中,我训练 CNN 没有任何问题。

下一步,我想调整 CNN 的两个超参数。为此,我创建了一个 for 循环(迭代 20 个步骤),在其中每次创建新模型时都会构建和编译,并在每次循环迭代时更改超参数。 代码的要点(这是notMWE)如下

import tensorflow as tf
from tensorflow import keras

def build_model(input_shape, output_shape, lr=0.01, dropout=0, summary=True):
    model = keras.models.Sequential(name="CNN")
    model.add(keras.layers.Conv2D(32, (7, 7), activation='relu', input_shape=input_shape, padding="same"))
    model.add(keras.layers.BatchNormalization())
    model.add(keras.layers.MaxPooling2D((2, 2)))
    model.add(keras.layers.Dropout(dropout))
    model.add(keras.layers.Conv2D(128, (3, 3), activation='relu', padding="same"))
    model.add(keras.layers.BatchNormalization())
    model.add(keras.layers.MaxPooling2D((2, 2)))
    model.add(keras.layers.Dropout(dropout))
    model.add(keras.layers.Flatten())
    model.add(keras.layers.Dense(1024, activation='relu'))
    model.add(keras.layers.BatchNormalization())
    model.add(keras.layers.Dense(output_shape, activation='linear'))
    model.build()
    model.compile(optimizer=keras.optimizers.Adam(learning_rate=lr),
                  loss="mse",
                  metrics=[RMSE])
    if summary:
        print(model.summary())
    return model

...

    for run_id in range(25):
        lr = learning_rate.max_value + (learning_rate.min_value - learning_rate.max_value) * np.random.rand(1)
        dropout = dropout.min_value + (dropout.max_value -
                                                 dropout.min_value) * np.random.rand(1)
        print("%=== Run #{0}".format(run_id))
        run_dir = hparamdir + "\\run{0}".format(run_id)
        model0 = build_model(IMG_SHAPE, Ytrain.shape[1], lr=lr, dropout=dropout)
        model0_history = model0.fit(Xtrain,
                                    Ytrain,
                                    validation_split=0.3,
                                    epochs=2,
                                    verbose=2)

我遇到的问题是,经过几(6)次循环后,程序停止返回错误

tensorflow.python.framework.errors_impl.ResourceExhaustedError: OOM when allocating tensor with shape[73728,1024] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc [Op:Add] name: dense_12/kernel/Initializer/random_uniform/

Process finished with exit code 1.

我认为问题在于 GPU 不会在 for 循环的每次迭代之间释放内存,一段时间后,它会饱和并崩溃。

我已经深入研究并尝试了类似帖子中建议的不同解决方案(post1 https://stackoverflow.com/questions/51005147/keras-release-memory-after-finish-training-process, post2 https://stackoverflow.com/questions/55793768/gpu-oom-hyperparameter-tuning-loop-with-varying-models)

  1. 尝试在 for 循环的每次迭代结束时使用 Keras 后端释放内存
from keras import backend as K
K.clear_session()
  1. 尝试使用 Numba 和 CUDA 清除 GPU
from numba import cuda
cuda.select_device(0)
cuda.close()
  1. 我尝试使用删除图表del model0但这也不起作用。

  2. 我无法尝试使用tf.reset_default_graph()因为 TF2.0 的编程风格不再有默认图(据我所知),因此我还没有找到在运行时杀死/删除图的方法。

解决方案 1. 和 3. 返回相同的内存不足错误,而解决方案 2. 在 for 循环的第二次迭代期间返回以下错误,同时在build_model()call:

2019-07-24 19:51:31.909377: F .\tensorflow/core/kernels/random_op_gpu.h:227] Non-OK-status: GpuLaunchKernel(FillPhiloxRandomKernelLaunch<Distribution>, num_blocks, block_size, 0, d.stream(), gen, data, size, dist) status: Internal: invalid resource handle

Process finished with exit code -1073740791 (0xC0000409)

我试着环顾四周,但我不太明白最后一个错误,我猜想 GPU 没有正确关闭/被占用/Python 再也看不到了。

无论如何,除了对每个要测试的超参数手动运行训练之外,我找不到任何解决此问题的方法。

有人知道如何解决这个问题吗? 或者超参数调整的解决方法? 我是否应该在 TF2.0 Github 问题跟踪器中提出问题(它本身似乎不是 TensorFlow 问题,因为他们声明不想释放 GPU 以避免分段问题)?


这是由于 TF 处理内存的方式造成的。

如果您在迭代训练 TF 模型时监控系统,您将观察到内存消耗呈线性增加。此外,如果您watch -n 0.1 nvidia-smi您会注意到该进程的 PID 在迭代时保持不变。在控制内存的 PID 被杀死之前,TF 不会完全释放已使用的内存。此外,Numba 文档指出cuda.close()如果你想重置 GPU,则没有用(尽管当我发现它时,我确实花了一段时间试图让它工作!)。

最简单的解决方案是使用迭代Ray https://ray.readthedocs.io/en/latest/python 包以及类似以下内容:

import ray

@ray.remote(
    num_gpus=1 # or however many you want to use (e.g., 0.5, 1, 2)
)
class RayNetWrapper:

    def __init__(self, net):
        self.net = net

    def train(self):
        return self.net.train()

ray.init()
actors = [RayNetWrapper.remote(model) for _ in range(25)]
results = ray.get([actor.train.remote() for actor in actors]

然后您应该注意到 GPU 进程每次都会使用新的 PID 循环打开/关闭,并且您的系统内存将不再增加。或者,您可以将模型训练代码放入新的 python 脚本中,并使用 python 迭代调用subprocess模块。现在,当模型关闭和新模型启动时,您还会注意到一些延迟,但这是预期的,因为 GPU 正在重新启动。雷还有一个实验性的我已经取得了一些成功的异步框架,并且可以实现 GPU 的部分共享(模型大小允许)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Tensorflow2.0:GPU 在超参数调整循环期间内存不足 的相关文章

随机推荐

  • mod_rewrite 和 mod_userdir 的问题

    我正在尝试获取其他人组装的正在运行的网站的本地副本 该网站已部署并正常运行 我正在尝试在我的 public html 目录下设置开发版本 该站点使用 mod rewrite 通过执行各种初始化步骤的网关脚本重定向所有流量 我有一个奇怪的问题
  • Altair:如何在烛台图(即:分层图)上使用区间选择

    我正在尝试复制以下堆叠图表 可以通过与底部图表交互来选择顶部图表的域 但使用烛台图 这是一个分层图表 example code for below is here https altair viz github io gallery int
  • 函数向全局变量返回 2 个值

    鉴于这个帖子 https stackoverflow com questions 61217589 set 2 series at once我想问为什么下面的脚本适用于 a b 但不适合 c d 找不到任何文档来解释为什么这不起作用 此示例
  • 如何检查日期(来自日期选择器)是否在其他两个日期之间?目标-c

    我正在尝试从 UIDatePicker MM dd 格式 获取日期并检查它是否在其他两个日期的范围内 我尝试过很多不同的方式 但我想我的想法已经走得太远了 有人可以帮我做得尽可能简单吗 这是我最后一次尝试的代码 NSDateFormatte
  • 如何在没有窗口的情况下使用 Swift 检测 macOS 上的 Caps Lock 状态?

    我努力了KeyDown and NSEvent 但他们需要一个NSWindow对象处于活动状态 我希望我可以在状态栏上放置一个应用程序 并在按下时提醒用户CapsLock 即使用户在任何其他应用程序中 我的应用程序创意没有用于设置或其他任何
  • Mojolicious 基本登录

    我正在 Mojolicious 中寻找身份验证 我有 2 个页面 momcorp1 和 momcorp2 但我不能 在页面之间 有人知道如何做到这一点 我正在阅读有关 under 的内容 但我不知道如何做到这一点 另一种形式是使用 Mojo
  • 如何限制 NSTokenField 中的令牌数量?

    我有一个 NSTokenField 其中的令牌是在按 Enter 键时创建的 我想限制该字段中的令牌数量 举例来说 应该只允许用户依次输入 2 个令牌 之后 既不应该允许用户设置Token 也不应该允许用户进一步搜索 简而言之 用户应该在
  • 为什么通过 goto 向后移动时会调用析构函数[重复]

    这个问题在这里已经有答案了 可能的重复 会使用goto泄漏变量 https stackoverflow com questions 7334952 will using goto leak variables 在下面的例子中 当goto被称
  • 如何在 ASP.Net MVC 5 站点中设置 NameClaimType?

    我使用 Microsoft 的 本地 组织帐户身份验证机制创建了一个 ASP Net MVC 5 站点 这最终配置为指向我公司的 ADFS 基础设施 我正在取回所有配置的声明 但是 在运行时 ClaimsIdentity Name 为空 这
  • jquery .map 不适用于 IE 10

    我有这个 jquery 代码 tf zoom live click function var n tf thumbs find img attr src var modelid n substr 43 post models get gal
  • Dialogflow 实现 webhook url 支持自签名证书吗?

    我正在使用 Dialogflow 履行网络钩子来处理天气 Dialogflow 显示 启用 Google Assistant 集成后 您只能在履行网址中使用 https 所以 我尝试了 https url 的自签名证书 但我无法获得 web
  • 为 Telnet 会话创建脚本?

    有谁知道创建一个可以连接到 telnet 服务器的脚本的简单方法 执行一些常见的 telnet 操作 然后注销 我正在与不熟悉 telnet 及其需要运行的命令的用户打交道 我想要的只是让他们双击脚本 然后让该脚本自动为他们执行命令 您可能
  • 我可以在命令行上通过 xbuild 将参数传递给 msc 吗?

    xbuild 有没有办法通过命令行或构建脚本将附加参数传递给编译器 具体来说 我想通过 mcs debug 1获取堆栈跟踪内部编译器错误 https travis ci org libgit2 libgit2sharp builds 106
  • 如何将 SOAP 消息解析为 Jaxb 类

    我有一个 SOAPMessage 对象 我想将其解析并转换为一组 Jaxb 类 如何将消息转换为 Jaxb 可以解组的格式 javax xml bind Unmarshaller unmarshal SOAP 消息的正文包含实际数据及其要解
  • 如何在 CoreOS 的 Vagrant 虚拟机实例上运行 python?

    如何在 CoreOS 的 Vagrant 虚拟机实例上运行 python 我想访问 python 解释器 谢谢 您还可以安装python在 CoreOS 上使用下面的脚本 我们称之为install python sh bin bash e
  • PHP 联系表单在查看页面时发送空白电子邮件

    谁能帮助我阻止每次查看页面时发送空白电子邮件 这是我正在使用的代码
  • 指针减法不指向同一数组的不同元素在 C 中有效吗?

    指针减法不指向同一数组的不同元素在 C 中有效吗 下面的东西是否能保证按照 C 标准工作 我依稀记得读到这是无效的 int a int b a int 100 b int 200 printf d n b a 这会给我25吗 来自 C 规范
  • 剧作家按钮的点击效果不可预测

    我至少有三个选项可以单击按钮 await page Locator button new HasText ClickAsync await page GetByRole AriaRole Button new Name ClickAsync
  • jquery sortable 不能拖到手风琴之外

    我有 2 个相连的可排序列表 一个在手风琴里面 当我尝试从手风琴中的可排序项中拖动项目时 一旦我离开手风琴 助手就会消失 我可以拖放到其他连接的可排序项之一 该项目将显示 但在我拖动时它不会显示 如果我向下拖动项目 手风琴也会向下滚动 我可
  • Tensorflow2.0:GPU 在超参数调整循环期间内存不足

    我正在尝试对使用 GPU 扩展的 Tensorflow 2 0 编写的卷积神经网络进行一些超参数调整 我的系统设置是 Windows 10 64 位 GeForce RTX2070 8GB 张量流 2 0 测试版 CUDA 10 0正确安装