【问题标题】:Speeding up numpy加速 numpy
【发布时间】:2021-03-22 16:02:09
【问题描述】:

有没有办法加快下面的代码sn-p?这是一个接受激光雷达点并将其转换为范围视图图像的功能任何建议将不胜感激。我尝试使用 numba,但没有得到太大改善。

def lidar_rv_projection(points, proj_H=32, proj_W=2048, proj_fov_up=10, proj_fov_down=-30.0):

    v_fov_up = proj_fov_up / 180.0 * np.pi  
    v_fov_down = proj_fov_down / 180.0 * np.pi  
    v_fov_total = abs(v_fov_down) + abs(v_fov_up)  

    depth = np.linalg.norm(points[:, :3], 2, axis=1)

    x_points = points[:, 0]
    y_points = points[:, 1]
    z_points = points[:, 2]

    x_img = np.arctan2(y_points, x_points) * -1
    y_img = np.arcsin(z_points / depth)

    proj_x = 0.5 * (x_img / np.pi + 1.0)
    proj_y = 1.0 + (y_img + abs(v_fov_down)) * -1 / v_fov_total

    proj_x *= proj_W  
    proj_y *= proj_H  

    proj_x = np.floor(proj_x)
    proj_x = np.minimum(proj_W - 1, proj_x)
    proj_x = np.maximum(0, proj_x).astype(np.int32)  # in [0,W-1]

    proj_y = np.floor(proj_y)
    proj_y = np.minimum(proj_H - 1, proj_y)
    proj_y = np.maximum(0, proj_y).astype(np.int32)  # in [0,H-1]

    order = np.argsort(depth)[::-1]
    depth = depth[order]
    points = points[order]
    proj_y = proj_y[order]
    proj_x = proj_x[order]
    
    proj_rv_img = np.full((4, proj_H, proj_W), -1,dtype=np.float64)
    proj_rv_img[0, proj_y, proj_x] = depth  # range
    proj_rv_img[1, proj_y, proj_x] = points[:, 2]  # height z
    proj_rv_img[2, proj_y, proj_x] = points[:, 3]  # intensity r
    proj_rv_img[3, proj_y, proj_x] = 1  # binary mask

    return proj_rv_img, proj_x, proj_y, points

【问题讨论】:

  • 你能提供一个有效输入的例子吗?您能否还指定您的数据有多大?
  • 如果你提供一个可复现的工作案例有可能准确地识别每段代码的性能,从而看看它是全部慢还是只有几行代码受到影响
  • 输入“点”的形状为 (4, 50000)。此函数在整个数据集的 for 循环中调用。
  • 好的,(4, 50000) 很小,这个函数应该很快。并行化包含 for 循环而不是这个函数可能是一个好主意。
  • 我明白了。有关如何并行化 for 循环的任何建议?

标签: python performance numpy time numba


【解决方案1】:

如果您正在考虑其他数值包,使用 torchtensorflow(尤其是如果您可以使用 GPU)可能会有很大帮助。幸运的是,大多数torchtensorflow 函数的实现方式与numpy 类似,因此您可能不必更改太多函数。

如果您的数据集相当大,切换到 torchtensorflow 可能有助于加快这些操作,例如> 5000 点(而且,由于您使用的是激光雷达回波,我猜想在 3 到 6 维之间)。

此外,我注意到您将一些变量转换为 np.int32np.float32。如果可以将其转换为精简表示,这也可能会有所帮助。例如

  1. np.int16:限于 [-32768, 32767]。 16 位有符号表示。
  2. np.uint16:限制为 [0, 65535]。 16 位无符号表示。
  3. np.int8:限于 [-128, 127]。 8 位有符号表示。
  4. np.uint8:限制为 [0, 255]。 8 位无符号表示

您还可以尝试降低浮点运算的精度,例如半精度 (np.float16) 而不是单精度 (np.float32)。请注意,这将导致错误增加,尽管程度取决于数据的规模和执行的操作。有关 NumPy 数据类型的更多信息,请参阅此链接here

【讨论】:

    【解决方案2】:

    我假设您有一个庞大的输入数据集。

    如果你有一个 Nvidia GPU,神奇的解决方案是使用包 cupyGPU 上完成工作,如果你有一个。您不必更改任何代码行:只需添加import cupy as np,您的代码应该会神奇地快得多。在我的机器上(使用中档 GPU 和良好的 CPU),输入 5,000,000 点,这个解决方案的速度快了 17 倍

    如果您有 AMD/Intel/Nvidia GPU,您可以尝试使用包 clpy(使用 OpenCL 而不是 CUDA)。

    如果你没有(强大的)GPU,那么你可以使用pnumpy 包,它可以让你的代码稍微快一些(主要是加快速度很慢的排序)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-23
      • 1970-01-01
      • 2013-08-14
      • 2020-05-02
      • 2012-05-12
      • 1970-01-01
      • 1970-01-01
      • 2018-04-21
      相关资源
      最近更新 更多