libtorch:为什么我的Tensor从一个方法返回另一个方法时会更改值?

问题描述

我正在调试此错误

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,ratingTensor: 
 1
 0
 0
[ cpuFloatType{3} ]

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

...
        // 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.

因此,除了错误之外,我还看到目标的张量值在getratingTensor()内部和返回值之间进行了更改。是什么引起了这种变化?我以为这可能与我收到此错误的原因有关。

我试图从JUCE项目中运行它,因此我将链接到projucer中的库并使用Visual Studio进行编译。我不确定错误是由于链接错误还是编码错误引起的。

我在projucer中的设置是:

链接的外部库:

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

标题搜索路径:

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的基础数据的所有权)。因此,您遇到了内存/指针错误。

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

return rating_tensor.clone();

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...