@@ -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