-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathperceptron_test.go
122 lines (114 loc) · 2.81 KB
/
perceptron_test.go
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
116
117
118
119
120
121
122
package neural
import (
"testing"
)
type percpInput struct {
A, B, Out float64
}
type percpTestCase struct {
Desc string
Weights []float64
Threshold float64
Activation ActivationFunction
InputSets []percpInput
}
var percpTestCases = []percpTestCase{
percpTestCase{
Desc: "OR",
Weights: []float64{0, 1, 1},
Threshold: 1,
Activation: PerceptronActivation,
InputSets: []percpInput{
percpInput{A: 0, B: 0, Out: 0},
percpInput{A: 1, B: 0, Out: 1},
percpInput{A: 0, B: 1, Out: 1},
percpInput{A: 1, B: 1, Out: 1},
},
},
percpTestCase{
Desc: "AND",
Weights: []float64{0, 0.5, 0.5},
Threshold: 1,
Activation: PerceptronActivation,
InputSets: []percpInput{
percpInput{A: 0, B: 0, Out: 0},
percpInput{A: 1, B: 0, Out: 0},
percpInput{A: 0, B: 1, Out: 0},
percpInput{A: 1, B: 1, Out: 1},
},
},
percpTestCase{
Desc: "A AND NOT B",
Weights: []float64{0, 1, -1},
Threshold: 1,
Activation: PerceptronActivation,
InputSets: []percpInput{
percpInput{A: 0, B: 0, Out: 0},
percpInput{A: 1, B: 0, Out: 1},
percpInput{A: 0, B: 1, Out: 0},
percpInput{A: 1, B: 1, Out: 0},
},
},
}
func TestPerceptron(t *testing.T) {
for i, c := range percpTestCases {
p := buildPerceptron(c.Weights, c.Threshold, c.Activation)
for j, in := range c.InputSets {
p.Inputs[1] = in.A
p.Inputs[2] = in.B
if o := p.Compute(); o != in.Out {
t.Errorf("Unexpected output of case[%d] %s for input[%d](%f.%f) got: %f, expected %f",
i, c.Desc, j, in.A, in.B, o, in.Out)
}
}
}
}
func TestPerceptronXOR(t *testing.T) {
p1 := buildPerceptron([]float64{0, 0.5, 0.5}, 1, PerceptronActivation)
p2 := buildPerceptron([]float64{0, 1, 1, -2}, 1, PerceptronActivation)
// 0,0 = 0
p1.Inputs[1] = 0
p1.Inputs[2] = 0
p2.Inputs[1] = p1.Inputs[1]
p2.Inputs[2] = p1.Inputs[2]
p2.Inputs[3] = p1.Compute()
if o := p2.Compute(); o != 0 {
t.Errorf("Unexpected output for XOR 0,0=0, %f", o)
}
// 0,1 = 1
p1.Inputs[1] = 0
p1.Inputs[2] = 1
p2.Inputs[1] = p1.Inputs[1]
p2.Inputs[2] = p1.Inputs[2]
p2.Inputs[3] = p1.Compute()
if o := p2.Compute(); o != 1 {
t.Errorf("Unexpected output for XOR 0,1=1, %f", o)
}
// 1,0 = 1
p1.Inputs[1] = 1
p1.Inputs[2] = 0
p2.Inputs[1] = p1.Inputs[1]
p2.Inputs[2] = p1.Inputs[2]
p2.Inputs[3] = p1.Compute()
if o := p2.Compute(); o != 1 {
t.Errorf("Unexpected output for XOR 1,0=1, %f", o)
}
// 1,1 = 0
p1.Inputs[1] = 1
p1.Inputs[2] = 1
p2.Inputs[1] = p1.Inputs[1]
p2.Inputs[2] = p1.Inputs[2]
p2.Inputs[3] = p1.Compute()
if o := p2.Compute(); o != 0 {
t.Errorf("Unexpected output for XOR 1,1=0, %f", o)
}
}
func buildPerceptron(w []float64, t float64, actFunc ActivationFunction) *Node {
inputs := make([]float64, len(w))
return &Node{
Inputs: inputs,
Weights: w,
Threshold: t,
Activation: actFunc,
}
}