libtorch:为什么我的张量在从一种方法返回到另一种方法时会更改值?

libtorch: Why does my Tensor change value when returned from a method into another method?

我正在调试这个错误:

Unhandled exception at 0x00007FFA0B7D3E49 in AudioPluginHost.exe: Microsoft C++ exception: c10::Error at memory location 0x00000044B4DABDB0.

我正在尝试训练神经网络,主要基于 this example

这是我正在做的事情:

torch::Tensor TrainingSample::getRatingTensor()
{
    c10::DeviceType deviceType;
    if (torch::cuda::is_available()) {
        deviceType = torch::kCUDA;
    }
    else {
        deviceType = torch::kCPU;
    }
    float ratingArray[1][3] = { {0} };
    ratingArray[0][(int)waveform.rating] = 1;

    ostringstream os0;
    for (int i = 0;i<(sizeof(ratingArray[0])/sizeof(ratingArray[0][0]));i++) {
        os0 << ratingArray[0][i];
        os0 << ",";
    }
    DBG("ratingArray: \n" + os0.str());

    auto options = torch::TensorOptions().dtype(torch::kFloat32).device(deviceType);
    torch::Tensor ratingTensor = torch::from_blob(ratingArray, { 1, 3 }, options);

    ostringstream os1;
    os1 << ratingTensor[0];
    DBG("ratingTensor: \n" + os1.str());

    return ratingTensor;
}

结果是:

ratingArray: 
1,0,0,
ratingTensor: 
 1
 0
 0
[ CPUFloatType{3} ]

所以,到目前为止一切都很好。我从同一个 class 中的另一个方法调用此方法。该方法具有以下代码:

...
        // Execute the model on the input data.
        auto prediction = net->forward(trainingSample.sampleTensor);
        auto target = trainingSample.getRatingTensor();

        std::ostringstream os_tensor0;
        os_tensor0 << target[0];
        DBG("target_val: \n" + os_tensor0.str());

        std::ostringstream os_tensor1;
        os_tensor1 << prediction[0];
        DBG("prediction_val: \n" + os_tensor1.str());

        // Compute a loss value to judge the prediction of our model.
        torch::Tensor loss = torch::nll_loss(prediction, target);
...

我在最后一行得到错误 (torch::Tensor loss = torch::nll_loss(prediction, target);)。

该代码在控制台中的输出是:

target_val: 
-4.0784e-07
 9.5288e-44
-3.3012e-34
[ CPUFloatType{3} ]
prediction_val: 
-4.2455e+17
-4.6908e+17
 0.0000e+00
[ CPUFloatType{3} ]
Exception thrown at 0x00007FFA0B7D3E49 in AudioPluginHost.exe: Microsoft C++ exception: c10::Error at memory location 0x00000044B4DABDB0.
Unhandled exception at 0x00007FFA0B7D3E49 in AudioPluginHost.exe: Microsoft C++ exception: c10::Error at memory location 0x00000044B4DABDB0.

因此,除了错误之外,我还看到目标的 Tensor 值在 getRatingTensor() 内部和返回值之后发生了变化。是什么导致了这种变化?我在想这可能与我得到的这个错误的原因有关。

我正在尝试从一个 JUCE 项目中 运行 这个,所以我正在链接 projucer 中的库并使用 Visual Studio 进行编译。我不确定这些错误是由于链接错误还是编码错误引起的。

我在 projucer 中的设置是:

外部图书馆 Link:

E:\Programming\Downloads\libtorch\lib\c10.lib
E:\Programming\Downloads\libtorch\lib\c10_cuda.lib
E:\Programming\Downloads\libtorch\lib\caffe2_nvrtc.lib
E:\Programming\Downloads\libtorch\lib\torch.lib
E:\Programming\Downloads\libtorch\lib\torch_cpu.lib
E:\Programming\Downloads\libtorch\lib\torch_cuda.lib

Header 搜索路径:

E:\Programming\Downloads\libtorch\include\
E:\Programming\Downloads\libtorch\include\torch\csrc\api\include

额外的库搜索路径:

E:\Programming\Downloads\libtorch\lib

我会说这是因为您使用了 torch::from_blob,但我不能确定,因为我目前没有电脑可以测试它。

基本上,torch::from_blob 不会取得您提供的基础数据的所有权。这意味着您必须确保数据至少与 from_blob 创建的张量一样长。在这里,当您返回 rating_tensor 时,您将离开函数,因此所有变量都被清除,因此 ratingArray(拥有 rating_tensor 的基础数据的所有权)被销毁。因此,您有一个 memory/pointer 错误。

这应该通过在返回之前简单地克隆 rating_tensor 来解决:

return rating_tensor.clone();