Course work (4th semester). A feedforward neural network that approximates solutions to simple differential equations. Scientific director: Kasatkin A.A.
The project is a C++ implementation built with clang and C++17, following the Google C++ Style Guide. Network configuration and training data are read from text files in the repository root.
The network is a fully connected multilayer perceptron:
- Input layer — training samples (e.g. coordinates or parameters).
- Hidden layers — optional; count and size are defined in
Nodes.txt. - Output layer — target values the network should predict.
Each layer is a vector of neuron activations. Connections between adjacent layers are stored as weight matrices (NetMatrix). Forward propagation:
next_layer = sigmoid(weights * current_layer)
The sigmoid activation function maps values to the range (0, 1).
When training is enabled via --train, the network:
- Runs forward pass for one training example.
- Computes output error:
target - output. - Propagates errors backward through hidden layers.
- Updates weights with gradient descent:
weights -= learning_rate * gradient.
The learning rate is set via set_learn_coef().
For a single output neuron with two inputs, the loss is:
E = ½·(O₁ − T₁)²
where O₁ = sigmoid(I₁·W₁₁ + I₂·W₂₁). Differentiating with respect to W₁₁:
∂E/∂W₁₁ = (O₁ − T₁) · O₁·(1 − O₁) · I₁
The gradient descent update becomes:
W₁₁ ← W₁₁ − lr · (O₁ − T₁) · O₁·(1 − O₁) · I₁
In code (neural_network.cc, train()), errors = target − output = T − O, so:
gradient = (O − 1) * (T − O) * O * lr // = O·(1−O)·(O−T)·lr
weights -= gradient ⊗ prev_layer // equivalent to the formula aboveUsing ½·(O−T)² as the loss eliminates the factor of 2 that would appear with (O−T)²; the result is numerically equivalent — the constant is absorbed into the learning rate.
In query mode (default), the network loads saved weights, runs forward pass for each input example, prints results to the console, and writes the last result to output_layer.txt.
.
├── include/
│ ├── neural_net.h # Abstract interface for neural networks
│ ├── neural_network.h # Neural network class declarations
│ ├── layer.h # Layer class declarations
│ └── net_matrix.h # Matrix class declarations
├── src/
│ ├── main.cc # Entry point: load data, train or query
│ ├── layer.cc # Layer implementations
│ ├── net_matrix.cc # Matrix implementations
│ └── neural_network.cc # Neural network implementations
├── Makefile # Build with clang++
├── Nodes.txt # Layer sizes (input ... hidden ... output)
├── input_layer.txt # Training/query inputs
├── targets.txt # Expected outputs (used for training)
├── weights.txt # Saved weight matrices
└── output_layer.txt # Last inference result (generated)
Space-separated neuron counts per layer, left to right:
3 1
Example above: 3 inputs, 1 output (no hidden layer). A deeper network might look like 10 20 10 2.
Values grouped by input layer size. For 3 inputs, every 3 lines form one example:
0
0
1
Blank lines between groups are allowed.
One target value per line for each training example (size = output layer size). For a single output neuron:
0
0.1
0.2
Weight matrices between layers, row by row. Each row contains num_cols() values; matrices are separated by blank lines. Loaded with sync_weights(); saved with save_weights() after training.
Requirements: clang with C++17 support (macOS Xcode CLI tools or LLVM).
From the repository root:
make
./neuralnet --inferenceOr run in one step:
make run./neuralnet --inference # run inference (default)
./neuralnet --train # train with default 1000 epochs
./neuralnet --train --epochs 10000| Option | Description |
|---|---|
--inference |
Load weights, run forward pass on all inputs, print and save output (default) |
--train |
Train the network and save updated weights to weights.txt |
--epochs N |
Number of training iterations (default: 1000; only used with --train) |
Manual build:
clang++ -std=c++17 -Wall -Wextra -O2 -Iinclude -o neuralnet \
src/main.cc src/layer.cc src/net_matrix.cc src/neural_network.ccClean build artifacts:
make cleanRun the binary from the repository root so relative paths to data files resolve correctly.
- Edit
Nodes.txtto define network topology. - Prepare
input_layer.txtandtargets.txtwith matching example counts. - Train:
./neuralnet --train --epochs 10000 - Evaluate:
./neuralnet --inference
| Class | Role |
|---|---|
NeuralNet |
Virtual interface: weights init, input/target loading, query |
NeuralNetwork |
Concrete network: sigmoid, backprop, file I/O |
Layer |
Neuron values with +, -, * operations for training math |
NetMatrix |
Dense matrix: random init, multiply, transpose, element access |
The codebase follows Google C++ conventions:
- 2-space indentation, 80-column-friendly formatting
snake_casefor functions and variables,PascalCasefor types- Trailing underscore for member variables (
learn_coef_,query_mode_) constexprconstants instead of macros- Include guards (
#ifndef/#define) in headers - Declarations in
include/, implementations insrc/ constcorrectness and explicit constructors where appropriate