libtorch 中 np.delete 的等价物是什么?

What's the equivalent of np.delete in libtorch?

似乎我们在 libtorch 中还没有 np.delete 等效项,那么我们如何模拟它的行为呢?例如,我正在尝试在 libtorch 中重写以下代码:

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

我该怎么办?我考虑过切片,但我不确定是否涉及我不知道的含义。这是我想出的:

neg = torch.where(overlap < overlap_threshold)[0]
ids = ids[neg].clone()

libtorch:

auto neg = torch::where(overlap <over_threshold)[0];
ids.index_put_({Slice()}, ids.index({neg}));
//or simply
ids = ids.index({neg}).clone();

这是一个示例演示,用于测试它们的结果是否相同:

x1 = np.asarray([125.,152., 155., 155., 202.])
y1 = np.asarray( [52., 72., 92., 95., 95.])
x2 = np.asarray( [145., 172., 175., 175., 222.])
y2 = np.asarray( [ 72.,  92., 112., 115., 115.])
score = np.asarray([0.60711509, 0.63444906, 0.85604602, 0.60021192, 0.70115328])
area = (x2 - x1 + 1.0) * (y2 - y1 + 1.0)
ids = np.argsort(score)
overlap_threshold = 0.5
mode = 'union'
while len(ids) > 0:
    # grab index of the largest value
    last = len(ids) - 1
    i = ids[last]

    # left top corner of intersection boxes
    ix1 = np.maximum(x1[i], x1[ids[:last]])
    iy1 = np.maximum(y1[i], y1[ids[:last]])

    # right bottom corner of intersection boxes
    ix2 = np.minimum(x2[i], x2[ids[:last]])
    iy2 = np.minimum(y2[i], y2[ids[:last]])

    # width and height of intersection boxes
    w = np.maximum(0.0, ix2 - ix1 + 1.0)
    h = np.maximum(0.0, iy2 - iy1 + 1.0)

    # intersections' areas
    inter = w * h
    if mode == 'min':
        overlap = inter / np.minimum(area[i], area[ids[:last]])
    elif mode == 'union':
        # intersection over union (IoU)
        overlap = inter / (area[i] + area[ids[:last]] - inter)

    # delete all boxes where overlap is too big
    # ids = np.delete(ids,np.concatenate([[last], np.where(overlap > overlap_threshold)[0]]))
    neg = np.where(overlap <= overlap_threshold)[0]
    ids = ids[neg]
    print(f'ids: {ids}')

这里是 libtorch 中的 cpp 计数器部分:

void test5()
{
    auto x1 = torch::tensor({ 125., 152., 155., 155., 202. });
    auto y1 = torch::tensor({ 52., 72., 92., 95., 95. });
    auto x2 = torch::tensor({ 145., 172., 175., 175., 222. });
    auto y2 = torch::tensor({ 72., 92., 112., 115., 115. });
    auto score = torch::tensor({ 0.60711509, 0.63444906, 0.85604602, 0.60021192, 0.70115328 });
    auto area = (x2 - x1 + 1.0) * (y2 - y1 + 1.0);
    auto ids = torch::argsort(score);
    auto overlap_threshold = 0.5;
    auto mode = "union";
    while (ids.sizes()[0] > 0)
    {
        //# grab index of the largest value
        auto last = ids.sizes()[0] - 1;
        auto i = ids[last];

        //# left top corner of intersection boxes
        auto ix1 = torch::max(x1[i], x1.index({ ids.index({ Slice(None,last) }) }));
        auto iy1 = torch::max(y1[i], y1.index({ ids.index({ Slice(None,last) }) }));

        //# right bottom corner of intersection boxes
        auto ix2 = torch::min(x2[i], x2.index({ ids.index({Slice(None,last)}) }));
        auto iy2 = torch::min(y2[i], y2.index({ ids.index({Slice(None,last)}) }));

        //# width and height of intersection boxes
        auto w = torch::max(torch::tensor(0.0), ix2 - ix1 + 1.0);
        auto h = torch::max(torch::tensor(0.0), iy2 - iy1 + 1.0);

        //# intersections' areas
        auto inter = w * h;
        torch::Tensor overlap;
        if (mode == "min")
        {
            overlap = inter / torch::min(area[i], area.index({ ids.index({Slice(None,last)}) }));
        }
        else if (mode == "union")
        { //# intersection over union (IoU)
            overlap = inter / (area[i] + area.index({ ids.index({Slice(None,last)}) }) - inter);
        }
        //# delete all boxes where overlap is too big
        //# ids = np.delete(ids, np.concatenate([[last], np.where(overlap > overlap_threshold)[0]] ))
        auto neg = torch::where(overlap < overlap_threshold)[0];
        ids = ids.index({ neg });
        std::cout << "ids: " << ids << std::endl;
    }
}

它们都打印相同的输出,所以我在这里遗漏了什么,或者这实际上是在 libtorch 中实现删除的合理方法?

我还有哪些其他可能更有效的方法 implement/emulate np.delete()

这似乎是评论中指出的合理做法。也就是把条件反转,只根据新的条件过滤掉。
我还想修复我原来 post 中的一个小问题。 相当于 Python 的正确形式:

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

将是:

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

注意<=