|
| 1 | +from lnn.regression import init_perceptron, print_perceptron, Perceptron, train_dataset |
| 2 | +from lnn.utils import normalize_input_vectors, normalize_output_vector |
| 3 | +from lpdraw import Line, Circle, Display, Clear |
| 4 | +from lpython import i32, f64, Const |
| 5 | +from numpy import empty, int32 |
| 6 | + |
| 7 | + |
| 8 | +def compute_decision_boundary(p: Perceptron, x: f64) -> f64: |
| 9 | + bias: f64 = p.weights[1] |
| 10 | + slope: f64 = p.weights[0] |
| 11 | + intercept: f64 = bias |
| 12 | + return slope * x + intercept |
| 13 | + |
| 14 | +def plot_graph(p: Perceptron, input_vectors: list[list[f64]], outputs: list[f64]): |
| 15 | + Width: Const[i32] = 500 # x-axis limits [0, 499] |
| 16 | + Height: Const[i32] = 500 # y-axis limits [0, 499] |
| 17 | + Screen: i32[Height, Width] = empty((Height, Width), dtype=int32) |
| 18 | + Clear(Height, Width, Screen) |
| 19 | + |
| 20 | + x1: f64 = 1.0 |
| 21 | + y1: f64 = compute_decision_boundary(p, x1) |
| 22 | + x2: f64 = -1.0 |
| 23 | + y2: f64 = compute_decision_boundary(p, x2) |
| 24 | + |
| 25 | + # center the graph using the following offset |
| 26 | + scale_offset: f64 = Width / 4 |
| 27 | + shift_offset: f64 = Width / 2 |
| 28 | + x1 *= scale_offset |
| 29 | + y1 *= scale_offset |
| 30 | + x2 *= scale_offset |
| 31 | + y2 *= scale_offset |
| 32 | + |
| 33 | + # print (x1, y1, x2, y2) |
| 34 | + Line(Height, Width, Screen, i32(int(x1 + shift_offset)), i32(int(y1 + shift_offset)), i32(int(x2 + shift_offset)), i32(int(y2 + shift_offset))) |
| 35 | + |
| 36 | + i: i32 |
| 37 | + point_size: i32 = 5 |
| 38 | + for i in range(len(input_vectors)): |
| 39 | + input_vectors[i][0] *= scale_offset |
| 40 | + input_vectors[i][0] += shift_offset |
| 41 | + outputs[i] *= scale_offset |
| 42 | + outputs[i] += shift_offset |
| 43 | + |
| 44 | + Circle(Height, Width, Screen, i32(int(input_vectors[i][0])), i32(int(outputs[i])), f64(point_size)) |
| 45 | + |
| 46 | + Display(Height, Width, Screen) |
| 47 | + |
| 48 | +def main0(): |
| 49 | + p: Perceptron = Perceptron(0, [0.0], 0.0, 0, 0.0, 0.0, 0) |
| 50 | + init_perceptron(p, 1, 0.0005, 10000, 1e-16) |
| 51 | + |
| 52 | + input_vectors: list[list[f64]] = [[1.1], [1.3], [1.5], [2.0], [2.2], [2.9], [3.0], [3.2], [3.2], [3.7], [3.9], [4.0], [4.0], [4.1], [4.5], [4.9], [5.1], [5.3], [5.9], [6.0], [6.8], [7.1], [7.9], [8.2], [8.7], [9.0], [9.5], [9.6], [10.3], [10.5], [11.2], [11.5], [12.3], [12.9], [13.5]] |
| 53 | + outputs: list[f64] = [39343.0, 46205.0, 37731.0, 43525.0, 39891.0, 56642.0, 60150.0, 54445.0, 64445.0, 57189.0, 63218.0, 55794.0, 56957.0, 57081.0, 61111.0, 67938.0, 66029.0, 83088.0, 81363.0, 93940.0, 91738.0, 98273.0, 101302.0, 113812.0, 109431.0, 105582.0, 116969.0, 112635.0, 122391.0, 121872.0, 127345.0, 126756.0, 128765.0, 135675.0, 139465.0] |
| 54 | + |
| 55 | + normalize_input_vectors(input_vectors) |
| 56 | + normalize_output_vector(outputs) |
| 57 | + |
| 58 | + train_dataset(p, input_vectors, outputs) |
| 59 | + print_perceptron(p) |
| 60 | + |
| 61 | + assert abs(p.weights[0] - (1.0640975812232145)) <= 1e-12 |
| 62 | + assert abs(p.weights[1] - (0.0786977829749839)) <= 1e-12 |
| 63 | + assert abs(p.err - (0.4735308448814293)) <= 1e-12 |
| 64 | + assert p.epochs_cnt == 4515 |
| 65 | + |
| 66 | + plot_graph(p, input_vectors, outputs) |
| 67 | + |
| 68 | +def main1(): |
| 69 | + p: Perceptron = Perceptron(0, [0.0], 0.0, 0, 0.0, 0.0, 0) |
| 70 | + init_perceptron(p, 1, 0.0005, 10000, 1e-16) |
| 71 | + |
| 72 | + input_vectors: list[list[f64]] = [[1.0], [3.0], [7.0]] |
| 73 | + outputs: list[f64] = [8.0, 4.0, -2.0] |
| 74 | + |
| 75 | + normalize_input_vectors(input_vectors) |
| 76 | + normalize_output_vector(outputs) |
| 77 | + |
| 78 | + train_dataset(p, input_vectors, outputs) |
| 79 | + print_perceptron(p) |
| 80 | + |
| 81 | + assert abs(p.weights[0] - (-0.9856542200697508)) <= 1e-12 |
| 82 | + assert abs(p.weights[1] - (-0.0428446744717655)) <= 1e-12 |
| 83 | + assert abs(p.err - 0.011428579012311327) <= 1e-12 |
| 84 | + assert p.epochs_cnt == 10000 |
| 85 | + |
| 86 | + plot_graph(p, input_vectors, outputs) |
| 87 | + |
| 88 | +main0() |
| 89 | +main1() |
0 commit comments