Tensor.std(0) returns a scalar instead of a vector

I’m a bit new to the C++ API, and I haven’t seen documentation for this behavior anywhere. Here is a minimal example to reproduce.

float data[] = { 1, 2, 3,
                       4, 5, 6 };
torch::Tensor f = torch::from_blob(data, {2, 3});
std::cout << f.mean(0) << std::endl;
// yields a 1-d tensor as expected.
// 2.5000
// 3.5000
// 4.5000
// [ CPUFloatType{3} ]
std::cout << f.std(0) << std::endl;
// yields a scalar, unexpected.
// 1.70783
// [ CPUFloatType{} ]

The argument will be interpreted as the unbiased argument, if a single argument is passed, which is not intuitive.
You could use f.std(0, true) as a workaround.
Could you also create an issue on GitHub and report it there, so that this behavior might be improved or at least the documentation added? :slight_smile:

Hi @ptrblck thanks for the answer. Here is the issue: https://github.com/pytorch/pytorch/issues/40287. Let me know if it needs to be revised, it is my first time creating one.

I also noticed that f.std(true, 0) collapses dimension 1, which is unintuitive, and also f.std(true, 1) collapses dimension 1 still but uses Bessel correction. All in all kinda weird behavior.

I’m actually not blocked on this as it’s a pretty easy to implement function (for my specific case), just pointing it out in case it is interesting to you guys.

Thanks for creating the issue! I’ve answered and it seems it worked for you. :slight_smile:
Just for the sake of completeness, I had a typo in my previous code, so posting the code snippet here again:

from torch.utils import cpp_extension


cpp_source = """
void my_fun(torch::Tensor x)
{
    std::cout << "x.std(0) " << x.std(0) << ", x.std(0, true) " << x.std(0, true) << std::endl;
    std::cout << "at::std(x, 0) " << at::std(x, 0) << ", at::std(x, 0, true) " << at::std(x, 0, true) << std::endl;
    return;
}
"""

module = torch.utils.cpp_extension.load_inline(
    name="std_test_extension",
    cpp_sources=cpp_source,
    functions="my_fun",
    verbose=True,
)

x = torch.randn(2, 3)
module.my_fun(x)

print('python ', x.std(0))
1 Like