Subtensor add and division in libtorch

how can I translate this code to libtorch:

# x and tmp is tensor
x[ 3 : 5] += win_sq[:2]
tmp[:, :, approx_nonzero_indices] /= window[nonzero_indices]
1 Like

Hi,

You have access to the .select() and .narrow() functions in cpp that can be used for this.
You also have access to .index_select() and .index_copy_() to read and write given 1D indices
The python code equivalent to yours is:

x_slice = x.narrow(0, 3, 2)
x_slice.add_(win_sq.narrow(0, 0, 2))
new_val = tmp.index_select(-1, approx_nonzero_indices) / window.index_select(0, nonzero_indices)
tmp.index_copy_(-1, approx_nonzero_indices, new_val)
3 Likes

thank you for your attention :slight_smile:

@albanD @yf225
hi.
Can I ask you one question?
How do I convert the code below to C ++?

//for torchvision maskrcnnn

    def filter_proposals(self, proposals, objectness, image_shapes, num_anchors_per_level):
        num_images = proposals.shape[0]
        device = proposals.device
        # do not backprop throught objectness
        objectness = objectness.detach()
        objectness = objectness.reshape(num_images, -1)

        levels = [
            torch.full((n,), idx, dtype=torch.int64, device=device)
            for idx, n in enumerate(num_anchors_per_level)
        ]
        levels = torch.cat(levels, 0)
        levels = levels.reshape(1, -1).expand_as(objectness)

        # select top_n boxes independently per level before applying nms
        top_n_idx = self._get_top_n_idx(objectness, num_anchors_per_level)
        batch_idx = torch.arange(num_images, device=device)[:, None]
        
       //below code 
        objectness = objectness[batch_idx, top_n_idx]
        levels = levels[batch_idx, top_n_idx]
        proposals = proposals[batch_idx, top_n_idx]

thanks!

Hi,

//below code 
        objectness = objectness[batch_idx, top_n_idx]

I think, translate above line to cpp is

auto new_val0 = objectness.index_select(0, batch_idx);
auto new_val1 = objectness.index_select(1, top_n_idx);
objectness.index_copy_(0, batch_idx, new_val0);
objectness.index_copy_(1, top_n_idx, new_val1);

Thank you for your answer.
I think, the above code is different

batch_idx is Image count,

ex)
boxes =  Image * index * 4  
score =  Image * index

I think, something like the code below
Is this right?@albanD @yf225

int64_t num_images = proposals.size(0);
torch::Device device = proposals.device();

objectness = objectness.detach();
objectness = objectness.reshape({ num_images, -1 });

std::vector<torch::Tensor> levels;
for (int64_t index = 0; index < num_anchors_per_level.size(); index++)
{
	levels.push_back(torch::full(num_anchors_per_level[index], index, torch::TensorOptions().device(device).dtype(at::kFloat)));
}

auto tensorlevels = torch::cat(levels, 0);

tensorlevels = tensorlevels.reshape({ 1,-1 }).expand_as(objectness);

auto top_n_idx = get_top_n_idx(objectness, num_anchors_per_level);
auto batch_idx = torch::arange(num_images, torch::TensorOptions().device(device));

std::vector<torch::Tensor> final_boxes, final_scores;

for (int64_t index = 0; index < num_images; index++)
{
	auto proposal = proposals[index].index_select(0, top_n_idx[index]);
	auto obj	= objectness[index].index_select(0, top_n_idx[index]);
	auto lvl	= tensorlevels[index].index_select(0, top_n_idx[index]);

	auto boxes = clip_boxes_to_image(proposal, image_shapes[index]);
	auto keep = remove_small_boxes(boxes, min_size_);
}

Hope this would help

    cv::Mat img = cv::imread(img_file);
    at::Tensor tensor_image = torch::from_blob(img.data, {1, img.rows, img.cols, 3}, torch::kByte);
    tensor_image = tensor_image.permute({0, 3, 1, 2});
    tensor_image = tensor_image.toType(at::kFloat);

    tensor_image[0][0].sub_(123.675).div_(58.395); // subtract mean
    tensor_image[0][1].sub_(116.28).div_(57.12);  // divide variance
    tensor_image[0][2].sub_(103.53).div_(57.375);
2 Likes