为啥使用 Faster RCNN 在 GPU 上进行自定义对象检测的预测率 25 - 40 [sec/1] 如此之低?
Posted
技术标签:
【中文标题】为啥使用 Faster RCNN 在 GPU 上进行自定义对象检测的预测率 25 - 40 [sec/1] 如此之低?【英文标题】:Why so low Prediction Rate 25 - 40 [sec/1] using Faster RCNN for custom object detection on GPU?为什么使用 Faster RCNN 在 GPU 上进行自定义对象检测的预测率 25 - 40 [sec/1] 如此之低? 【发布时间】:2018-11-13 13:13:23 【问题描述】:我已经为自定义对象检测训练了一个faster_rcnn_inception_resnet_v2_atrous_coco
模型(可用here)。
对于预测,我在图像上使用了对象检测演示 jupyter notebook file。还检查了每个步骤所消耗的时间,发现 sess.run
一直在占用时间。
但在 GPU 上预测 (3000 x 2000) 像素大小(大约 1-2 [MB] )的图像大约需要 25-40 [秒]。
谁能解决这里的问题?
我已经进行了分析,下载链接profiling file
链接到完整的profiling
系统信息: 使用 NVIDIA Tesla M60 GPU
在 Azure 门户 中使用 Standard_NV6(详情 here)创建的虚拟机上的训练和预测 操作系统平台和分发 - Windows 10 TensorFlow 安装自 - 使用 pippip3 install --upgrade tensorflow-gpu
TensorFlow 版本 - 1.8.0
Python 版本 - 3.6.5
GPU/CPU - GPU
CUDA/cuDNN 版本 - CUDA 9/cuDNN 7
【问题讨论】:
没问题,你的图片比平时使用的大很多(300x300到600x600左右)。所以自然会慢一些。 嗨 Matias Valdenegro,我也尝试过使用较小的图像(小于 600*600,从几 Kb 到最大 100 KB 大小),但预测大约需要 20 秒 即使在大图像上预测也应该非常快,因为在这里您只需应用函数(模型)。有两件事要检查:(1)确认 tensorflow 实际上是在使用 GPU(2)配置 tensorflow,遵循例如towardsdatascience.com/howto-profile-tensorflow-1a49fb18073d 顺便说一句,正如docs.microsoft.com/en-us/azure/virtual-machines/windows/… 所证明的,VM 默认没有安装驱动程序和 CUDA,所以除非你完成了这些步骤,否则你的 tensorflow 将在 CPU 上运行——它需要比在 CPU 上运行的时间长得多GPU。 这就是我们所需要的。分析信息清楚地表明您正在使用 GPU ......并且需要 1.5 秒 - 这是合理的。自己看看:drive.google.com/open?id=1CsrV6YkIyQ9KYtgoS6YLePxTgPXOxGmM 如果您转到 chrome://tracing/(假设您有 Chrome)并加载文件(您可能已经完成),您可以获得相同的图像。无论如何,阻止你的不是 tensorflow,或者至少数据是这样说的。我建议将其重构为脚本并运行分析:python -m cProfile yourscript.py
【参考方案1】:
大图像需要更多时间是很自然的。即使在 400*400 等较低分辨率下,Tensorflow 对象检测也表现良好。
获取原始图像的副本,将其调整为较低的分辨率以执行对象检测。 您将获得边界框坐标。现在计算原始更高分辨率图像的相应边界框坐标。在原始图像上绘制边界框。
即
假设你有一个 3000*2000 的图像, 复制它并将其调整为 300*200。 对调整大小的图像进行对象检测,检测到一个带有边界框的对象 (50,100,150,150),即 (ymin, xmin, ymax, xmax)
现在较大的原始图像对应的框坐标将为(500,1000,1500,1500)。在其上绘制矩形。
对小图像进行检测,然后在原始图像上绘制边界框。 性能将大大提高。
注意:TensorFlow 支持标准化坐标。
即,如果您有一个高度为 100 且 ymin = 50 的图像,则归一化 ymin 为 0.5。 只需分别乘以 y 和 x 坐标的高度或宽度,即可将标准化坐标映射到任意维度的图像。
我建议使用 OpenCV (cv2) 进行所有图像处理。
【讨论】:
嗨@Sreeragh A R,感谢您的投入。早些时候,我尝试过您对 (3000*3000) 图像的建议,并将相同图像的大小调整为 (300*300) 和 (400*400),因为这个较小的图像检测大约需要 15-20 秒,而原始图像需要 20 多秒.但我担心的是为什么我无法达到更接近声称的here 的速度。我无法弄清楚这里缺少什么。 您是否收到过这样的警告?Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA
如果是,请关注github.com/lakshayg/tensorflow-build
@Sreeragh A R,不,我没有收到任何警告,因为我的模型是在 GPU 中创建的,并且预测也在 GPU 上,因此没有关于 CPU 编译的警告【参考方案2】:
正如网站所说,图像尺寸应为 600x600,并且代码在 Nvidia GeForce GTX TITAN X 卡上运行。但首先请确保您的代码实际上是在 GPU 上运行而不是在 CPU 上。我建议运行您的代码并打开另一个窗口,使用下面的命令查看 GPU 利用率,看看是否有任何变化。
watch nvidia-smi
【讨论】:
跟踪显示 OP 正在使用 GPU。此外,实际预测需要大约 1.5 秒,这与 OP 声明有些矛盾。因此请求完整的分析,【参考方案3】:谁能在这里找出问题?
很抱歉在这里被残酷地开放和直接公平观察到的性能问题的根本原因是:
对于这种计算密集型(性能-和-吞吐量驱动)任务,人们无法从 Azure 产品组合中找到更差的 VM 设置。只是不能 - 菜单上没有“更少”装备的选项。
Azure NV6 专门为 虚拟桌面用户 进行营销,其中 NVidia GRID(R) 驱动程序提供了一个软件层用于图像/视频(桌面图形像素,最大 SP 编码)的“共享”部分的服务,在用户团队之间共享,无论他们的终端设备如何(然而,每个板载的任何一个最多 15 个用户GPU,它在 Azure 上被明确地宣传和推广为它的主要卖点。NVidia 甚至成为继父,明确地为 (cit.) Office 用户推广此设备强>)。
M60 缺乏(显然, 已被定义为非常不同的细分市场)任何智能 AI / ML / DL / Tensor-processing 功能,比AI / ML / DL / Tensor-processing 专用计算GPU设备~20x低 DP 性能。
如果我可以引用,
...“GRID”是覆盖一组给定 Tesla(目前 M10、M6、 >M60)(以及之前的 Quadro (K1 / K2))GPU。 GRID 软件在其最基本的形式中(如果你可以这样称呼它),目前用于创建 FrameBuffer 配置文件在“图形”模式下使用 GPU 时,它允许用户共享一部分 GPU访问同一个物理 GPU 时的 FrameBuffer。
和
不,M10、M6 和 M60不特别适合 AI。但是,它们会工作,只是不如其他 GPU 高效。 NVIDIA 为特定工作负载和行业(技术)使用领域创建特定的 GPU,因为每个领域都有不同的要求。(学分转到 BJones)
接下来, 如果真的愿意花精力在这个先验已知的最差选择上:
确保两个 GPU都处于“计算”模式,不是“图形”(如果您正在使用 AI)。您可以使用 Linux 启动实用程序执行此操作,注册评估后,您将获得正确的 M60 驱动程序包。 (学分再次归于 BJones)
对于非 Linux / Azure 操作的虚拟化访问设备,显然没有这样的选项。
简历:
如果努力提高性能-和-吞吐量,最好选择另一个,配备 AI / ML / DL / Tensor-processing 的 GPU 设备,这两个问题-放置了特定的计算硬件资源,并且没有软件层(没有 GRID,或者至少是一个容易获得的禁用选项),在任何意义上 阻止 实现如此高级的 GPU 处理性能。
【讨论】:
关于 VM 的一切都是正确的,但根据在 chrome 跟踪中查看的profiling file 显示,该过程大约需要 1500 毫秒。【参考方案4】:TensorFlow 的初始设置需要很长时间。 (别担心。这只是一个一次性的过程)。
加载图表是一个繁重的过程。我在我的 CPU 中执行了这段代码。完成程序花了将近 40 秒。
加载图表等初始设置所需的时间为 37 秒。
执行对象检测的实际时间为 3 秒,即每张图像 1.5 秒。
如果我给了 100 张图片,那么总耗时将是 37 + 1.5 * 100。我不必加载图表 100 次。
因此,在您的情况下,如果这需要 25 [s],那么初始设置将需要 ~ 23-24 [s]。实际时间应该是 ~ 1-2 [s]。
您可以在代码中进行验证。可以在python中使用time
模块:
import time # used to obtain time stamps
for image_path in TEST_IMAGE_PATHS: # iteration of images for detection
# ------------------------------ # begins here
start = time.time() # saving current timestamp
...
...
...
plt.imshow( image_np )
# ------------------------------ # processing one image ends here
print( 'Time taken',
time.time() - start # calculating the time it has taken
)
【讨论】:
嗨 Sreeragh A R,加载图表在这里不是问题(消耗的时间约为 1 秒);正如问题中提到的那样,sess.run
消耗了 90% 以上的时间。以上是关于为啥使用 Faster RCNN 在 GPU 上进行自定义对象检测的预测率 25 - 40 [sec/1] 如此之低?的主要内容,如果未能解决你的问题,请参考以下文章