分割概率图取决于 CPU 或 GPU

Posted

技术标签:

【中文标题】分割概率图取决于 CPU 或 GPU【英文标题】:Segmentation probablity maps depend on CPU or GPU 【发布时间】:2021-09-28 23:08:47 【问题描述】:

我在 tensorflow 中编写了一个语义分割模型。该模型在 CPU 中进行训练,并且预测也在 CPU 中完成。 一段时间后,我在 GPU 机器上再次运行预测,我注意到概率图有一些非常小的差异(附图)。 另外,我想检查一下batch size是否影响预测分布(我最初以为没有影响)。

我做了一个描述这四种情况的小实验:

A1) 在 CPU 中训练的模型和在 CPU 中运行的预测 --> Batch Size = 1

A2) 在 CPU 中训练的模型和在 CPU 中运行的预测 --> Batch Size = 64

B1) 在 CPU 中训练的模型和在 GPU 中运行的预测 --> Batch Size = 1

B2) 在 CPU 中训练的模型和在 GPU 中运行的预测 --> Batch Size = 64

我已经总结了附图中测试集中其中一张图像的一部分的结果。

我们可以观察到:

    无论批次大小如何,训练模型并在 CPU 中运行预测都会提供相同的结果。 在 CPU 中训练模型并在 GPU 中运行预测时,批量大小会产生影响(尽管很小) CPU 和 GPU 提供的预测不匹配(差异非常小)。如果截止阈值设置为 0.55,这可能是相关的,然后根据附图,CPU 会将其分类为背景像素 (0.5498570.55)如果图像是较大批次的一部分。 再次运行 GPU 预测,提供不同的概率(再次非常小的差异),而 CPU 始终提供相同的概率。

这里是colab 的链接以重现该功能。

所以我的主要问题是:

这种行为是否正常且预期会发生? 为什么会发生这种行为(文档)? 如何避免这种情况发生?这样在 GPU 中运行的预测始终提供与 CPU 相同的概率)并且无论批量大小如何?

【问题讨论】:

你能把所有东西都做成float32,让它更像苹果对苹果吗?我无法运行您的模型,因为我没有权重。只是来自您拥有的任何模型的随机权重应该没问题(不需要加载权重),但如果您只想输入用于构建/编译模型的代码,您应该设置一个种子。 您好,感谢您的回答!你能给我一个电子邮件地址吗?我可以把权重文件和一个小数据集发给你,这样你就可以试一试了?如果你愿意,当然可以。此外,你知道我是否可以选择直接作为 float32 给出的预测?对于方法 A,我将它们作为 float32,但对于方法 B,它们是 float64,我不知道为什么...我会尽快应用您的建议。再次感谢! 我刚刚添加了您的建议(播种并将概率图转换为 float32)。我在原帖中提到的差异仍然存在。有什么想法吗? 嗯,不确定。百分比差异很小,但据说它不应该存在。如果我有时间,我会看看我是否可以复制其他案例。您也可以向 tensorflow 提交错误报告(您必须让您的示例自行运行,并且更加独立),这是值得做的最后一步(只需使用随机初始化构建您的模型)。 您好,刚刚在 Keras 文档中找到了这个资源:keras.io/getting_started/faq/… 值得一读,因为它实际上说 GPU 会产生非确定性的输出,因此建议在 CPU 中运行代码以获得始终同样的结果。我认为这些信息对于这个问题至关重要。无论如何,我已经向 Keras 报告了这个错误。 【参考方案1】:

分段取决于 RAM。当进程在 RAM 中换入和换出时,会使用不同类型的算法。分割依赖于内存,因此 GPU 直接在页框的不同块上进行分割。

【讨论】:

你的意思是,我得到的差异是在使用 GPU 进行图像分割时可以预料到的? 你有任何代码或其他来源来支持这个断言吗?【参考方案2】:

此问题已发布在Keras' github,Keras 团队对此进行了相应回答。

可以提出以下关键点:

    在 GPU 中运行模型会产生不确定的结果(它会在每次运行模型时提供不同的输出,即使差异非常小 CPU 产生确定性结果(总是相同的结果) 有计划使 GPU 预测具有确定性,但它们与 CPU 结果仍然略有不同。 在 TF>2.5 中使用环境变量 TF_DETERMINISTIC_OPS=1 有助于解决非确定性行为。

【讨论】:

以上是关于分割概率图取决于 CPU 或 GPU的主要内容,如果未能解决你的问题,请参考以下文章

1. 概率图模型

概率图模型

概率图模型-贝叶斯网络

概率图模型基础

概率图模型:贝叶斯网络与朴素贝叶斯网络

HMM及CRF