Libraryless. Click here for Pure Java version (4122L/26K).
1 | // class is persistable |
2 | sclass Perceptron implements IPred<double[]> {
|
3 | srecord Example(double[] inputs, bool answer) {
|
4 | double getInput(int i) { ret i < inputs.length ? inputs[i] : 1; }
|
5 | } |
6 | |
7 | L<Example> examples = syncList(); |
8 | double c = 1; |
9 | bool randomizeC = true, startWithRandomWeights = false; |
10 | long trainingRound; |
11 | double error = -1; // -1 = not trained yet |
12 | double[] weights; |
13 | |
14 | *() {}
|
15 | *(L<Example> *examples) {}
|
16 | |
17 | ItIt<Double> trainingIterator() {
|
18 | if (empty(examples)) ret emptyItIt(); |
19 | int n = l(first(examples).inputs)+1; |
20 | if (weights == null) {
|
21 | weights = new double[n]; |
22 | if (startWithRandomWeights) |
23 | for i over weights: weights[i] = random(-1.0, 1.0); |
24 | } |
25 | ret iff(() -> {
|
26 | if (error == 0) ret endMarker(); |
27 | ++trainingRound; |
28 | double lastError = error; |
29 | trainARound(); |
30 | ret error != lastError ? error : null; |
31 | }); |
32 | } |
33 | |
34 | double trainARound() {
|
35 | double error = 0; |
36 | int n = l(examples); |
37 | if (n == 0) ret -1; |
38 | for (Example e : concIter(examples)) error += abs(trainAnExample(e)); |
39 | ret this.error = error/n; |
40 | } |
41 | |
42 | int feedForward(double[] inputs) {
|
43 | double sum = last(weights); |
44 | for i over inputs: sum += inputs[i] * weights[i]; |
45 | ret activate(sum); |
46 | } |
47 | |
48 | public Bool get(double[] inputs) {
|
49 | ret feedForward(inputs) > 0; |
50 | } |
51 | |
52 | int activate(double s) {
|
53 | return s > 0 ? 1 : -1; |
54 | } |
55 | |
56 | double recalcError() {
|
57 | double error = 0; |
58 | int n = l(examples); |
59 | if (n == 0) ret -1; |
60 | for (Example e : concIter(examples)) |
61 | error += abs(errorForExample(e)); |
62 | ret this.error = error/n; |
63 | } |
64 | |
65 | double errorForExample(Example e) {
|
66 | int guess = feedForward(e.inputs); |
67 | ret (e.answer ? 1 : -1) - guess; |
68 | } |
69 | |
70 | double trainAnExample(Example e) {
|
71 | double error = errorForExample(e); |
72 | if (error != 0) {
|
73 | double cc = c/l(examples); |
74 | for i over weights: |
75 | weights[i] += (randomizeC ? rand(cc) : cc) * error * e.getInput(i); |
76 | } |
77 | ret error; |
78 | } |
79 | |
80 | void printWithWeights {
|
81 | print("Error: " + error + ", round " + trainingRound + ", weights: " + sfu(weights));
|
82 | } |
83 | |
84 | // scaling the weights doesn't make a difference |
85 | // returns true if it worked (error did not increase) |
86 | bool scaleWeights(double factor) {
|
87 | for i over weights: |
88 | weights[i] *= factor; |
89 | double lastError = error; |
90 | if (recalcError() > lastError) |
91 | ret false with warn("Error increased from \*lastError*/ to \*error*/ during scale weight with factor \*factor*/");
|
92 | true; |
93 | } |
94 | |
95 | void addExample(double[] inputs, bool answer) {
|
96 | examples.add(new Example(inputs, answer)); |
97 | error = -1; |
98 | } |
99 | } |
Began life as a copy of #1026916
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
| Snippet ID: | #1026919 |
| Snippet name: | Perceptron |
| Eternal ID of this version: | #1026919/29 |
| Text MD5: | 0434286372a7b18bbdec746ba10d70c5 |
| Transpilation MD5: | a79007d898549c7551a569120a13c602 |
| Author: | stefan |
| Category: | javax |
| Type: | JavaX source code (Dynamic Module) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2020-02-02 21:06:57 |
| Source code size: | 2737 bytes / 99 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 559 / 1310 |
| Version history: | 28 change(s) |
| Referenced in: | [show references] |