as a minimal example, is this what you suggest?
struct Net : torch::nn::Module {
  Net() {
    fc1 = register_module("fc1", torch::nn::Linear(1, 3));
    fc2 = register_module("fc2", torch::nn::Linear(3, 4));
    fc3 = register_module("fc3", torch::nn::Linear(4, 2));
  }
    
  // Implement the Net's algorithm.
  torch::Tensor forward(torch::Tensor x) {
    x = torch::sigmoid(fc1->forward(x));
    x = torch::dropout(x, /*p=*/0.5, /*train=*/is_training());
    x = torch::sigmoid(fc2->forward(x));
    x = torch::log_softmax(fc3->forward(x), /*dim=*/1);
    return x;
  }
int main(){
      auto net = std::make_shared<Net>();
      torch::optim::SGD optimizer(net->parameters(), /*lr=*/0.01);
      for (int ii=0; ii<100; ii++) {
      optimizer.zero_grad();
      auto inputs = generate_data(); // doesnt matter the values
      torch::Tensor prediction = net->forward(inputs);
      torch::Tensor loss =calculate_loss(prediction); // e.g. loss = [1,0]
      for (auto item:loss){
          item.backward();
      }
      optimizer.step();
}