-
Notifications
You must be signed in to change notification settings - Fork 2
/
connection.go
106 lines (95 loc) · 2.55 KB
/
connection.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
package automata
import "fmt"
import "math/rand"
type LayerType int
const (
LayerTypeAuto LayerType = iota
LayerTypeAllToAll
LayerTypeOneToOne
LayerTypeAllToElse
)
type ConnID int64
// Connection represents a connection between two neurons.
type Connection struct {
ID ConnID
From *Neuron
To *Neuron
Gater *Neuron
Weight float64
Gain float64
}
func NewConnection(from, to *Neuron, weight *float64) *Connection {
if weight == nil {
w := (rand.Float64() * 0.2) - 0.1 // random weight between -0.1 and +0.1
weight = &w
}
conn := &Connection{
From: from,
To: to,
Weight: *weight,
Gain: 1,
}
id := from.LookupTable.SetConnection(conn)
conn.ID = id
return conn
}
// LayerConnection represents a connection between two layers.
type LayerConnection struct {
From *Layer
To *Layer
Type LayerType
Connections map[ConnID]*Connection
List []*Connection
}
func NewLayerConnection(from, to *Layer, ltype LayerType) LayerConnection {
if ltype == LayerTypeAuto {
if from == to {
ltype = LayerTypeOneToOne
} else {
ltype = LayerTypeAllToAll
}
}
var list []*Connection
connsByID := make(map[ConnID]*Connection)
switch ltype {
case LayerTypeOneToOne:
// A neuron in position i in the 'from' layer gets projected to the matching neuron in position i
// in the 'to' layer and nothing more. No neuron is supplied if there is no matching neuron.
for i, neuron := range from.List {
var toNeuron *Neuron
if i < len(to.List) {
toNeuron = to.List[i]
}
conn := neuron.Project(toNeuron, nil)
connsByID[conn.ID] = conn
list = append(list, conn)
}
case LayerTypeAllToAll:
fallthrough
case LayerTypeAllToElse:
// Each neuron in the 'from' layer gets projected to all neurons in the 'to' layer.
// 'ToElse' stops the neuron projecting to itself if it exists in the 'to' layer.
// 'ToAll' projects to all neurons regardless.
for _, fromNeuron := range from.List {
for _, toNeuron := range to.List {
if ltype == LayerTypeAllToElse && &fromNeuron == &toNeuron {
continue
}
conn := fromNeuron.Project(toNeuron, nil)
connsByID[conn.ID] = conn
list = append(list, conn)
}
}
default:
panic(fmt.Sprintf("NewLayerConnection: unknown layer type %d", ltype))
}
lc := LayerConnection{
From: from,
To: to,
Type: ltype,
Connections: connsByID,
List: list,
}
from.ConnectedTo = append(from.ConnectedTo, lc)
return lc
}