python - 当我使用较小的 float 时,为什么 sklearn 中的 KNN 实现速度会变慢?

标签 python numpy machine-learning scikit-learn knn

我在我的应用程序中使用 KNN 搜索。大数组会消耗大量内存,我正在尝试减小数组的大小。

在不影响结果的情况下减少维度对我来说太难了。因此,我希望通过使用较小的 dtype 来减小大小:

In [46]: features = np.random.random((500000, 128)).astype('float32')

In [47]: smaller = features.astype('float16')

In [48]: nbrs = NearestNeighbors(n_neighbors=20, algorithm='brute', metric='l2').fit(f
    ...: eatures)

In [49]: smaller_nbrs = NearestNeighbors(n_neighbors=20, algorithm='brute', metric='l2
    ...: ').fit(smaller)

In [50]: %timeit nbrs.kneighbors(features[3:4])
10 loops, best of 3: 61.7 ms per loop

In [51]: %timeit smaller_nbrs.kneighbors(smaller[3:4])
1 loop, best of 3: 526 ms per loop

如您所见,切换到 float16 会使 kneighbors 调用速度变慢约 10 倍。

为什么会出现这样的情况呢?我可以做些什么来让它运行得像使用 float32 时一样快吗?

最佳答案

32b 浮点比 16b 浮点工作得更快的原因是大多数现代 CPU 本身支持 32b 浮点,而 16b 浮点可能需要一些特殊处理(例如转换为 float32)。因此,当您节省 RAM 时,您在计算上的花费就会显着增加。 当使用正确的 CPU 指令时,这种情况可以得到缓解,但这里的情况可能并非如此(Intel 在 2012 年引入了特殊的半精度操作码;see)。需要注意的是,只有当您的数组大于 256K(这显然是您的情况)时,您才能实现任何明显的加速,但改进在 20% 到 40% 之间,这很容易因数组的非最佳遍历而丢失(缓存未命中)。

此外,另一个需要考虑的因素是内存数据对齐,通常在使用完整字时效果更好(对于许多 CPU:32b 或 64b)。有关内存对齐和缓存使用的影响的大量详细信息,您可以在 Scott Myers' presentation 中找到。 .

关于python - 当我使用较小的 float 时,为什么 sklearn 中的 KNN 实现速度会变慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44065954/

相关文章:

python - 将数据帧的第 0 行设置为标题

python - 来自二维概率 numpy 数组的样本?

python - sklearn中StratifiedKFold和StratifiedShuffleSplit的区别

python - 在python中更改数组的数据类型

python替换不受影响的空格

python - 查找具有重复值的元组列表中的最小行

tensorflow - 使用 tf extract_image_patches 作为 CNN 的输入?

python - 如何正确地将不平衡数据集拆分为训练集和测试集?

python - 如何从其他数组的不同起点对 2-D Numpy 数组的范围进行索引

python - 快速选择行,其中至少 N 许多列在 numpy/scipy 中成立