C++ Error passing DataLoader batch into model

My task is to convert a working Pytorch neural network from Python to C++, but I’m not well versed in C++ so I’m learning as I go. I’m having an issue passing my DataLoader batch data into the model. Like examples show https://pytorch.org/cppdocs/frontend.html I’m attempting to pass my batch data, “batch” into the model like so:

for (size_t epoch = 0; epoch <= num_epochs; ++epoch)
{
// Initialize running metrics
double loss1 = 0.0;

  for (auto& batch: *train_dataloader1)
  {
  	//std::cout << batch << "\n";

  	optimizer.zero_grad();

  	// Forward pass
  	auto outputs = model->forward(batch.data); // Error here
  }

}

The errors I get when I try to build are “E1866 attribute does not apply to any entity” and “C3867 ‘std::vector<SingleExample,std::allocator<_Ty>>::data’: non-standard syntax; use ‘&’ to create a pointer to member.” From these errors I’ve gathered (possibly incorrectly) that I need to pass in model->forward(batch.data()), but then I have three errors: “E1866 attribute does not apply to any entity”, "E0415 no suitable constructor exists to convert from “torch::data::TensorExample *” to “at::Tensor”, and finally “C2664 ‘at::Tensor Autoencoder1Impl::forward(at::Tensor)’: cannot convert argument 1 from ‘_Ty *’ to ‘at::Tensor’”

So I’m stuck because every example I’ve found is passing in the batch data like above, but the error instructs (to my best knowledge) to pass in the data differently. Any help is greatly appreciated!

Here is my model:

#include <torch/torch.h>
#include “Models.h”

Autoencoder1Impl::Autoencoder1Impl(int64_t num_vars, int64_t layer_size)
: encoder(num_vars, layer_size), decoder(layer_size, num_vars)
{
register_module(“encoder”, encoder);
register_module(“decoder”, decoder);
}

torch::Tensor Autoencoder1Impl::forward(torch::Tensor x)
{
x = torch::sigmoid(encoder->forward(x));
x = decoder->forward(x);
return x;
}

This isn’t helpful, but this is very similar to the question I asked a few hours ago. The problem is there are no examples or on the web that use datasets that return more than one in a batch. (They’re all image dataloaders). You’re not getting a tensor to pass through to the model, you’re getting a std::vector (C++'s way of spelling “list”) of examples, which are whatever’s returned by the get() function in your dataset class… which is probably type Example.

The only way I’ve been able to make progress so far is manually converting my “list of examples” into a tensor is manually for each batch, which has to be wildly inefficient. In my case, each example from my dataset is a 2D tensor. the model expects a 3D tensor, so I was able to do this:

  		for (auto& batch : *data_loader) {
			std::vector<torch::Tensor> Xs_list, Ys_list;
		    std::transform(batch.begin(), batch.end(), std::back_inserter(Xs_list), [](auto &e) {return e.data;});
		    std::transform(batch.begin(), batch.end(), std::back_inserter(Ys_list), [](auto &e) {return e.target;});
			torch::Tensor X = torch::stack(Xs_list);
			torch::Tensor Y = torch::stack(Ys_list);

            optimizer.zero_grad();
      		torch::Tensor prediction = model->forward(X);

Maybe that will help point you towards an answer.

EDIT: After more poking, I finally got my network to train. The above code is wrong, in that the torch::from_blob lines should be replaces with torch::stack(Xs_list). I’m editing the code now to reflect that.

1 Like

Thanks for the input. This snippet of code you provided got me through my error. Unfortunately I’m running into another error. If you have the the time to briefly look at it, the next error is an Unhandled Exception which occurs in my model here:

x = torch::sigmoid(encoder->forward(x))

Unhandled exception at 0x00007FF8AAE8A799 in NeuralNetwork_cpp.exe: Microsoft C++ exception: c10::Error at memory location 0x0000007A173CB3A0. occurred.

Thanks again