加速网络的指南

Minkowski 引擎需要在稀疏张量上进行卷积的两个主要组件:高效的内核映射管理和特征操作。内核映射是指定义输入特征中的哪一行映射到输出特征中的哪一行的映射。

在 Minkowski 引擎中,我们使用一个无序映射,其键是非零索引,对应的值是行索引。给定两个定义输入和输出张量的无序映射,我们可以找到输入特征中的哪一行映射到输出特征中的哪一行。

但是,在许多情况下,卷积网络由重复的操作块组成。例如,由具有相同内核大小的卷积组成的残差块。因此,我们最终会重用大量的内核映射,而不是每次都重新计算,而是缓存所有内核映射。

重用缓存的内核映射

正如我们在上一节中提到的,Minkowski 引擎缓存所有内核映射。如果网络有很多重复的层,例如卷积,网络将重用缓存的内核映射。

重用转置层的缓存内核映射

Minkowski 引擎可以通过交换内核映射的输入和输出来重用转置层的缓存内核映射。例如,如果在张量步长为 2 的稀疏张量上使用了步长为 2 的卷积,则张量步长为 4 且步长为 2 的转置卷积层可以重用在上一个步长为 2 的卷积上生成的相同内核映射。 尽可能多地重用重复的网络结构。

使用交叉形状或自定义内核的高维卷积

随着维度或内核大小的增加,如果我们使用超立方内核(体积内核),计算效率会迅速下降。 尝试使用交叉形状内核或其他自定义内核以减少负载。 在以下代码片段中,我们创建了一个用于卷积的交叉形状内核。

import MinkowskiEngine as ME

...

kernel_generator = ME.KernelGenerator(
      kernel_size,
      stride,
      dilation,
      region_type=ME.RegionType.HYPERCROSS,
      dimension=dimension)

conv = ME.MinkowskiConvolution(
      in_channels=in_channels,
      out_channels=out_channels,
      kernel_size=kernel_size,
      stride=stride,
      dilation=dilation,
      bias=bias,
      kernel_generator=kernel_generator,
      dimension=dimension)

高维空间的步进池化层

在极高维空间中,使用步进卷积非常昂贵。 使用交叉形状内核不是分层映射的好解决方案,因为在高维空间中一切都非常稀疏,并且交叉形状内核最终将是空的。 而是使用池化层来高效快速地创建内核映射。

如果使用内核大小 == 步长的池化层,MinkowskiEngine 将非常高效地生成内核映射,因为映射变得微不足道。