Skip to content

Commit bd04163

Browse files
committed
Training script
1 parent 5f0eb5f commit bd04163

File tree

1 file changed

+46
-26
lines changed

1 file changed

+46
-26
lines changed

examples/train.zig

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,39 +29,59 @@ pub fn main() !void {
2929
var sizes = [_]usize{ 3, 2, 1 };
3030

3131
// Initialize the neural network
32-
const mlp = MLPType.new(sizes.len - 1, sizes[0..]);
32+
const model = MLPType.new(sizes.len - 1, sizes[0..]);
3333

34-
const inputs = [_][3]*ValueType{
35-
[_]*ValueType{ ValueType.new(2), ValueType.new(3), ValueType.new(-1) },
36-
[_]*ValueType{ ValueType.new(3), ValueType.new(-1), ValueType.new(0.5) },
37-
[_]*ValueType{ ValueType.new(0.5), ValueType.new(1), ValueType.new(1) },
38-
[_]*ValueType{ ValueType.new(1), ValueType.new(2), ValueType.new(3) },
34+
// dataset
35+
const X = [_][3]f64{
36+
.{ 2.0, 3.0, -1.0 },
37+
.{ 3.0, -1.0, 0.5 },
38+
.{ 0.5, 1.0, 1.0 },
39+
.{ 1.0, 1.0, -1.0 },
3940
};
41+
const y = [_]f64{ 1.0, -1.0, -1.0, 1.0 };
4042

41-
mlp.draw_graph("assets/img/mlp");
43+
const lr = 1e-2;
44+
const epochs: usize = 100;
4245

43-
var output: []*ValueType = undefined;
44-
for (inputs) |in| {
45-
// Forward pass through the layer
46-
output = mlp.forward(@constCast(&in));
47-
std.debug.print("Layer output: {d:7.4}\n", .{output[0].data});
48-
for (output) |o| {
49-
_ = o.draw_graph("assets/img/perceptron");
50-
}
51-
}
46+
// training loop
47+
for (0..epochs) |epoch| {
48+
// Zero out the gradients
49+
model.zero_grad();
50+
51+
// Accumulate loss across all samples (like the reference implementation)
52+
var loss: ?*ValueType = null;
53+
var first = true;
54+
55+
var i: usize = 0;
56+
while (i < X.len) : (i += 1) {
57+
var inputs: [X[i].len]*ValueType = undefined;
58+
for (&inputs, 0..) |*input, j| {
59+
input.* = ValueType.new(X[i][j]);
60+
}
5261

53-
const t1 = TensorType.new(&[_]f64{ 1, 2, 3, 4 });
54-
std.debug.print("t1: {d:.4}\n", .{t1.data[0].data});
62+
const z = model.forward(&inputs);
63+
const ypred = z[0];
5564

56-
// outputs now contains 1 ValueType pointer (final layer has 1 neuron)
57-
const final_output = output[0];
58-
std.debug.print("Layer output: {d:.4}\n", .{final_output.data});
65+
const ygt = ValueType.new(y[i]);
66+
const diff = ypred.sub(ygt);
67+
const sq = diff.mul(diff);
5968

60-
std.debug.print("output.data: {d:.4}\n", .{final_output.data});
61-
std.debug.print("output.grad: {d:.4}\n", .{final_output.grad});
69+
if (first) {
70+
loss = sq;
71+
first = false;
72+
} else {
73+
loss = loss.?.add(sq);
74+
}
75+
}
76+
77+
const total_loss = loss.?.data;
6278

63-
final_output.backwardPass(alloc);
79+
// Single backward pass on accumulated loss
80+
loss.?.backwardPass(alloc);
6481

65-
std.debug.print("output.data: {d:.4}\n", .{final_output.data});
66-
std.debug.print("output.grad: {d:.4}\n", .{final_output.grad});
82+
// Update parameters with SGD
83+
model.update_parameters(lr);
84+
85+
std.debug.print("Epoch={d:4} loss={d:.6}\n", .{ epoch, total_loss });
86+
}
6787
}

0 commit comments

Comments
 (0)