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();
我正在调试这个错误:
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();