-
Notifications
You must be signed in to change notification settings - Fork 207
Expand file tree
/
Copy pathGradientNormReport.lpr
More file actions
115 lines (103 loc) · 3.03 KB
/
Copy pathGradientNormReport.lpr
File metadata and controls
115 lines (103 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
program GradientNormReport;
(*
GradientNormReport: builds a deep 12-layer ReLU MLP for a tiny hypotenuse-like
regression task, runs a single forward + backward pass on a probe batch, and
prints TNNet.GradientNormReport. Then rebuilds the SAME stack with a
TNNetLayerNorm inserted at the midpoint and prints the report again. The
contrast should show smoother gradient magnitudes (and fewer "vanishing"
flags / ratios closer to 1.0) with the norm layer.
Pure CPU, well under a minute.
Copyright (C) 2026 Joao Paulo Schwarz Schuler
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
any later version.
Coded by Claude (AI).
*)
{$mode objfpc}{$H+}
uses {$IFDEF UNIX} cthreads, {$ENDIF}
Classes, SysUtils, Math,
neuralnetwork,
neuralvolume;
const
cDepth = 12;
cWidth = 16;
cLearningRate = 0.01;
procedure BuildPlainMLP(out NN: TNNet);
var
I: integer;
begin
NN := TNNet.Create();
NN.AddLayer(TNNetInput.Create(2, 1, 1));
for I := 1 to cDepth do
NN.AddLayer(TNNetFullConnectReLU.Create(cWidth));
NN.AddLayer(TNNetFullConnectLinear.Create(1));
NN.SetLearningRate(cLearningRate, 0.9);
end;
procedure BuildNormMLP(out NN: TNNet);
// Same stack with a LayerNorm inserted at the midpoint.
var
I, MidPoint: integer;
begin
NN := TNNet.Create();
NN.AddLayer(TNNetInput.Create(2, 1, 1));
MidPoint := cDepth div 2;
for I := 1 to cDepth do
begin
NN.AddLayer(TNNetFullConnectReLU.Create(cWidth));
if I = MidPoint then
NN.AddLayer(TNNetLayerNorm.Create());
end;
NN.AddLayer(TNNetFullConnectLinear.Create(1));
NN.SetLearningRate(cLearningRate, 0.9);
end;
procedure MakeProbe(out X, Yt: TNNetVolume);
var
A, B: TNeuralFloat;
begin
A := 0.7;
B := 0.4;
X := TNNetVolume.Create(2, 1, 1);
X.FData[0] := A;
X.FData[1] := B;
Yt := TNNetVolume.Create(1, 1, 1);
Yt.FData[0] := Sqrt(A * A + B * B);
end;
procedure RunOne(const Title: string; UseNorm: boolean);
var
NN: TNNet;
X, Yt: TNNetVolume;
Report: string;
begin
RandSeed := 1234;
if UseNorm then
BuildNormMLP(NN)
else
BuildPlainMLP(NN);
MakeProbe(X, Yt);
try
WriteLn;
WriteLn(StringOfChar('=', 92));
WriteLn(Title);
WriteLn(StringOfChar('=', 92));
WriteLn('Architecture:');
NN.PrintSummary();
WriteLn;
Report := TNNet.GradientNormReport(NN, X, Yt);
Write(Report);
finally
X.Free;
Yt.Free;
NN.Free;
end;
end;
begin
WriteLn('GradientNormReport demo: ', cDepth,
'-layer ReLU MLP, with and without midpoint LayerNorm.');
RunOne('Plain ReLU MLP (no normalization)', False);
RunOne('ReLU MLP with midpoint TNNetLayerNorm', True);
WriteLn;
WriteLn(
'Expect: the norm variant tightens the log10(||dL/dx_in||) spread and ' +
'pulls per-layer ratios closer to 1.0 versus the plain stack.');
end.