You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

LibTorch中np.delete等效功能的实现与优化技术咨询

在LibTorch中模拟np.delete的行为(附NMS场景示例)

你的实现方案完全合理且正确,从测试代码的输出一致就能证明这一点。本质上,np.delete的核心逻辑就是「保留不需要删除的元素」,你通过筛选overlap < overlap_threshold的索引来保留对应元素,和原Python代码的np.delete逻辑是完全等价的——原代码删除last位置(当前最高分框)和重叠超标的元素,而你的代码只保留ids[:last]中重叠不超标的元素,正好自动剔除了last和超标项,逻辑严丝合缝。

为什么你的方案没问题?

原Python代码的关键行:

ids = np.delete( ids, np.concatenate([[last], np.where(overlap > overlap_threshold)[0]] ) )

是明确指定要删除的索引:last + 重叠超标的索引。而你的改写:

auto neg = torch::where(overlap < overlap_threshold)[0];
ids = ids.index({neg});

是反向筛选要保留的索引(ids[:last]中不超标的),最终得到的ids和原代码完全一致——因为last位置的元素本来就不在overlap的计算范围内(你用的是ids[:last]和当前框计算重叠),所以新的ids自然不会包含last,完美匹配原逻辑。

其他模拟np.delete的高效方式

根据不同场景,你还可以选择这些方法:

1. 掩码(Mask)方式(适合任意删除索引集合)

如果需要删除的是任意指定的索引集合(而非通过条件筛选),可以用全True掩码标记保留项,再把要删除的位置设为False:

// 假设delete_indices是要删除的索引张量
auto mask = torch::ones(ids.sizes(), torch::kBool);
mask.index_put_(delete_indices, false);
ids = ids.index({mask});

这种方式在删除索引分散、数量较少时更直观,避免额外创建保留索引张量。

2. 使用torch::index_select

和你用的ids.index({neg})等价,写法不同而已:

ids = torch::index_select(ids, 0, neg);

两者底层实现一致,性能没有差异,选你习惯的写法即可。

3. 注意GPU张量的效率

如果你的代码运行在GPU上,确保所有张量都在GPU设备上(避免CPU/GPU来回拷贝),LibTorch的where、索引操作都对GPU做了充分优化,性能和numpy在CPU上的表现相当。

效率对比

在你这个NMS场景下,你的方案是最贴合业务逻辑的——因为你本来就需要基于overlap条件筛选,直接用where得到保留索引,一步到位,不需要额外处理删除索引的拼接,代码更简洁。

如果是删除大量元素、保留少数元素的场景,这种筛选保留的方式效率更高;反之,如果删除的元素极少,掩码方式可能略优(因为不需要生成新的索引张量),但差异可以忽略不计。

总结

你的实现没有遗漏,逻辑完全正确,是NMS场景下模拟np.delete的最优写法之一。其他方法可以根据具体的删除需求灵活选择,但核心思路都是「保留需要的元素」——这也是np.delete的本质。

内容的提问来源于stack exchange,提问作者Hossein

火山引擎 最新活动