Your first model
Explicit backward with an executable MLP.
From the implementationinclude/nexus_model/containers/sequential.hpp
01A network in three steps#
This complete C++ example maps [32,784] to [32,10]. GELU is an activation; Linear is a learnable layer. It uses L=sum(y) to demonstrate the mechanism; supply your actual loss gradient for classification.
#include <nexus_model/nexus_model.hpp>#include <iostream>#include <memory>using namespace nexus_model;int main() { init::manual_seed(42); Sequential model({ std::make_shared<Linear>(784, 256), std::make_shared<GELU>(), std::make_shared<Linear>(256, 10) }); auto x = Tensor::full({32, 784}, 0.1f); model.zero_grad(); auto y = model.forward(x); // Example objective: L = sum(y). dL/dy = 1. auto dy = Tensor::full({32, 10}, 1.0f); auto dx = model.backward(dy); std::cout << y.size(0) << " x " << y.size(1) << "\n"; return dx.same_shape(x) ? 0 : 1;}02Follow the shapes#
The first Linear maps the last axis from 784 to 256; GELU preserves it; the second Linear produces 10 logits. backward input must exactly match output shape. dx has the same shape as x. Parameter gradients are in model.parameters().
03203530 learnable values#
Sequential uses numeric names: 0.weight [256,784], 0.bias [256], 2.weight [10,256], 2.bias [10]. GELU has no parameters. There is no optimizer step in this example; add weight updates using the training guide.
for (const auto& [name, p] : model.named_parameters()) { std::cout << name << ": " << p->data.numel() << "\n";}◆Read alongside the source. API behavior reflects the current implementation.