Machine Learning Tutorial
cds.ml ships a small, dependency-free multilayer perceptron (MLP) built on a
stack of Layer objects. Training uses the Adam optimizer from
cds.optimization, so the whole pipeline — forward
pass, backprop, and the optimizer step — is pure Python.
1. Build and inspect a network
Construct a layer with (in_features, out_features, activation). Supported
activations are relu, sigmoid, and tanh. Stack them into an MLP.
from cds.ml import MLP, Layer
# 2 inputs -> 4 hidden (ReLU) -> 1 output (Sigmoid)
net = MLP([
Layer(2, 4, activation="relu"),
Layer(4, 1, activation="sigmoid"),
])
2. Predict before training
predict takes a feature vector and returns the network's output.
X = [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]] # OR-gate inputs
y = [[0.0], [1.0], [1.0], [1.0]]
for xi in X:
print(f" In: {xi} -> Out: {net.predict(xi)[0]:.4f}")
# Untrained network outputs ≈ 0.5 everywhere:
# In: [0.0, 0.0] -> Out: 0.5000
# In: [0.0, 1.0] -> Out: 0.5159
# In: [1.0, 0.0] -> Out: 0.4839
# In: [1.0, 1.0] -> Out: 0.5249
3. Train with Adam
train runs Adam for epochs iterations over the dataset and returns a history
dict with the final loss, iteration count, and convergence flag.
history = net.train(X, y, epochs=200, lr=0.1)
print(history)
# {'final_loss': 0.000403..., 'iterations': 200, 'converged': False}
for xi in X:
print(f" In: {xi} -> Out: {net.predict(xi)[0]:.4f}")
# After training the network has learned the OR function:
# In: [0.0, 0.0] -> Out: 0.0394
# In: [0.0, 1.0] -> Out: 0.9967
# In: [1.0, 0.0] -> Out: 0.9927
# In: [1.0, 1.0] -> Out: 1.0000
4. Resumable optimizer state
Internally, train stores Adam's moment estimates on the MLP instance
(net.optimizer_state). Calling train again resumes from that checkpoint
rather than restarting, so you can train in stages or lower the learning rate
between phases.
Run the full demo with python examples/ml_and_viz_demo.py.