66 "testing"
77)
88
9- func TestController1 (t * testing.T ) {
9+ func TestLogisticModel (t * testing.T ) {
1010 times := 10
1111 x := MakeTensor2 (times , 4 )
1212 for i := 0 ; i < len (x ); i ++ {
@@ -26,12 +26,40 @@ func TestController1(t *testing.T) {
2626 numHeads := 2
2727 c := NewEmptyController1 (len (x [0 ]), len (y [0 ]), h1Size , numHeads , n , m )
2828 c .Weights (func (u * Unit ) { u .Val = 2 * rand .Float64 () })
29- ForwardBackward (c , x , y )
3029
31- l := loss (c , Controller1Forward , x , y )
32- checkGradients (t , c , Controller1Forward , x , y , l )
30+ model := & LogisticModel {Y : y }
31+ ForwardBackward (c , x , model )
32+ checkGradients (t , c , Controller1Forward , x , model )
3333}
3434
35+ func TestMultinomialModel (t * testing.T ) {
36+ times := 10
37+ x := MakeTensor2 (times , 4 )
38+ for i := 0 ; i < len (x ); i ++ {
39+ for j := 0 ; j < len (x [i ]); j ++ {
40+ x [i ][j ] = rand .Float64 ()
41+ }
42+ }
43+ outputSize := 4
44+ y := make ([]int , times )
45+ for i := range y {
46+ y [i ] = rand .Intn (outputSize )
47+ }
48+ n := 3
49+ m := 2
50+ h1Size := 3
51+ numHeads := 2
52+ c := NewEmptyController1 (len (x [0 ]), outputSize , h1Size , numHeads , n , m )
53+ c .Weights (func (u * Unit ) { u .Val = 2 * rand .Float64 () })
54+
55+ model := & MultinomialModel {Y : y }
56+ ForwardBackward (c , x , model )
57+ checkGradients (t , c , Controller1Forward , x , model )
58+ }
59+
60+ // A ControllerForward is a ground truth implementation of the forward pass of a controller.
61+ type ControllerForward func (c Controller , reads [][]float64 , x []float64 ) (prediction []float64 , heads []* Head )
62+
3563func Controller1Forward (c1 Controller , reads [][]float64 , x []float64 ) ([]float64 , []* Head ) {
3664 c := c1 .(* controller1 )
3765 h1Size := len (c .Wh1r )
@@ -57,7 +85,7 @@ func Controller1Forward(c1 Controller, reads [][]float64, x []float64) ([]float6
5785 v += c.Wyh1 [i ][j ].Val * h1 [j ]
5886 }
5987 v += c.Wyh1 [i ][maxJ ].Val
60- prediction [i ] = Sigmoid ( v )
88+ prediction [i ] = v
6189 }
6290 numHeads := len (c .Wh1r [0 ])
6391 m := len (c .Wh1r [0 ][0 ])
@@ -75,7 +103,7 @@ func Controller1Forward(c1 Controller, reads [][]float64, x []float64) ([]float6
75103 return prediction , heads
76104}
77105
78- func loss (c Controller , forward func ( Controller , [][] float64 , []float64 ) ( []float64 , [] * Head ), in , out [][] float64 ) float64 {
106+ func loss (c Controller , forward ControllerForward , in [][]float64 , model DensityModel ) float64 {
79107 // Initialize memory as in the function ForwardBackward
80108 mem := c .Mtm1BiasV ().Top
81109 wtm1Bs := c .Wtm1BiasV ()
@@ -102,10 +130,11 @@ func loss(c Controller, forward func(Controller, [][]float64, []float64) ([]floa
102130 }
103131 }
104132
105- prediction := make ([][]float64 , len (out ))
133+ prediction := make ([][]float64 , len (in ))
106134 var heads []* Head
107135 for t := 0 ; t < len (in ); t ++ {
108136 prediction [t ], heads = forward (c , reads , in [t ])
137+ prediction [t ] = computeDensity (t , prediction [t ], model )
109138 for i := 0 ; i < len (heads ); i ++ {
110139 heads [i ].Wtm1 = wtm1s [i ]
111140 }
@@ -115,24 +144,27 @@ func loss(c Controller, forward func(Controller, [][]float64, []float64) ([]floa
115144 mem = transformMemFloat64 (memFloat64 )
116145 }
117146
118- var llh float64 = 0 // log likelihood
119- for t := 0 ; t < len ( out ); t ++ {
120- for i := 0 ; i < len ( out [ t ]); i ++ {
121- p := prediction [ t ][ i ]
122- y := out [ t ][ i ]
123- llh += y * math . Log ( p ) + ( 1 - y ) * math . Log ( 1 - p )
124- }
147+ return model . Loss ( prediction )
148+ }
149+
150+ func computeDensity ( timestep int , pred [] float64 , model DensityModel ) [] float64 {
151+ units := make ([] Unit , len ( pred ))
152+ for j := range units {
153+ units [ j ]. Val = pred [ j ]
125154 }
126- return - llh
155+ model .Model (timestep , units )
156+ return UnitVals (units )
127157}
128158
129- func checkGradients (t * testing.T , c Controller , forward func (Controller , [][]float64 , []float64 ) ([]float64 , []* Head ), in , out [][]float64 , lx float64 ) {
159+ func checkGradients (t * testing.T , c Controller , forward ControllerForward , in [][]float64 , model DensityModel ) {
160+ lx := loss (c , forward , in , model )
161+
130162 c .WeightsVerbose (func (tag string , w * Unit ) {
131163 x := w .Val
132164 h := machineEpsilonSqrt * math .Max (math .Abs (x ), 1 )
133165 xph := x + h
134166 w .Val = xph
135- lxph := loss (c , forward , in , out )
167+ lxph := loss (c , forward , in , model )
136168 w .Val = x
137169 grad := (lxph - lx ) / (xph - x )
138170
0 commit comments