forked from emer/leabra
-
Notifications
You must be signed in to change notification settings - Fork 1
/
pptg.go
105 lines (90 loc) · 2.35 KB
/
pptg.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
// Copyright (c) 2020, The Emergent Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package pvlv
import (
"strconv"
"github.com/ccnlab/leabrax/leabra"
"github.com/emer/emergent/emer"
//"github.com/ccnlab/leabrax/pbwm"
"github.com/goki/ki/kit"
)
// The PPTg passes on a positively-rectified version of its input signal.
type PPTgLayer struct {
leabra.Layer
Ge float32
GePrev float32
SendAct float32
DA float32
DNetGain float32 `desc:"gain on input activation"`
ActThreshold float32 `desc:"activation threshold for passing through"`
ClampActivation bool `desc:"clamp activation directly, after applying gain"`
}
var KiT_PPTgLayer = kit.Types.AddType(&PPTgLayer{}, leabra.LayerProps)
func (ly *PPTgLayer) Build() error {
err := ly.Layer.Build()
if err != nil {
return err
}
return nil
}
func (ly *PPTgLayer) Defaults() {
ly.Layer.Defaults()
}
// Add a Pedunculopontine Gyrus layer. Acts as a positive rectifier for its inputs.
func AddPPTgLayer(nt *Network, name string, nY, nX int) *PPTgLayer {
rl := &PPTgLayer{}
nt.AddLayerInit(rl, name, []int{nY, nX, 1, 1}, emer.Hidden)
return rl
}
func (ly *PPTgLayer) InitActs() {
for ni := range ly.Neurons {
nrn := &ly.Neurons[ni]
nrn.Act = 0
nrn.ActSent = 0
}
}
func (ly *PPTgLayer) GetDA() float32 {
return ly.DA
}
func (ly *PPTgLayer) SetDA(da float32) {
ly.DA = da
}
func (ly *PPTgLayer) QuarterFinal(ltime *leabra.Time) {
ly.Layer.QuarterFinal(ltime)
ly.Ge = ly.Neurons[0].Ge
if ltime.PlusPhase {
ly.GePrev = ly.Ge
}
}
// GetMonitorVal retrieves a value for a trace of some quantity, possibly more than just a variable
func (ly *PPTgLayer) GetMonitorVal(data []string) float64 {
var val float32
idx, _ := strconv.Atoi(data[1])
switch data[0] {
case "Act":
val = ly.Neurons[idx].Act
case "Ge":
val = ly.Neurons[idx].Ge
case "GePrev":
val = ly.GePrev
case "TotalAct":
val = TotalAct(ly)
}
return float64(val)
}
func (ly *PPTgLayer) ActFmG(_ *leabra.Time) {
nrn := &ly.Neurons[0]
geSave := nrn.Ge
nrn.Ge = ly.DNetGain * (nrn.Ge - ly.GePrev)
if nrn.Ge < ly.ActThreshold {
nrn.Ge = 0.0
}
ly.Ge = nrn.Ge
ly.SendAct = nrn.Act // mainly for debugging
nrn.Act = nrn.Ge
nrn.ActLrn = nrn.Act
nrn.ActDel = 0.0
nrn.Ge = geSave
ly.Learn.AvgsFmAct(nrn)
}