@@ -66,11 +66,13 @@ trainRecurrent rate network recinputs examples =
66 -- This is a recurrent layer, so we need to do a scan, first input to last, providing
66 -- This is a recurrent layer, so we need to do a scan, first input to last, providing
67 -- the recurrent shape output to the next layer.
67 -- the recurrent shape output to the next layer.
68 go !xs (layer :~@> n) (g :~@+> nIn)
68 go !xs (layer :~@> n) (g :~@+> nIn)
69− = let ys = scanlFrom layer g xs
69+ = let tys = scanlFrom layer g xs
71− (newFN, ig, grads) = go (snd <$> ys) n nIn
73+ (newFN, ig, grads) = go ys n nIn
73− backExamples = zip3 (fst <$> reverse ys) (reverse xs) grads
75+ backExamples = zip (reverse tapes) grads
75 (rg, back) = myscanbackward layer backExamples
77 (rg, back) = myscanbackward layer backExamples
76 -- the new trained layer.
78 -- the new trained layer.
@@ -105,22 +107,22 @@ scanlFrom :: forall x i o. RecurrentLayer x i o
105 => x -- ^ the layer
107 => x -- ^ the layer
106 -> S (RecurrentShape x) -- ^ place to start
108 -> S (RecurrentShape x) -- ^ place to start
107 -> [S i] -- ^ list of inputs to scan through
109 -> [S i] -- ^ list of inputs to scan through
108− -> [(S (RecurrentShape x), S o)] -- ^ list of scan inputs and outputs
110+ -> [(RecTape x i o, S o)] -- ^ list of scan inputs and outputs
109scanlFrom !layer !recShape (x:xs) =
111scanlFrom !layer !recShape (x:xs) =
110− let (lerec, lepush) = runRecurrentForwards layer recShape x
112+ let (tape, lerec, lepush) = runRecurrentForwards layer recShape x
111− in (recShape, lepush) : scanlFrom layer lerec xs
113+ in (tape, lepush) : scanlFrom layer lerec xs
112scanlFrom _ _ [] = []
114scanlFrom _ _ [] = []
114myscanbackward :: forall x i o. RecurrentLayer x i o
116myscanbackward :: forall x i o. RecurrentLayer x i o
115 => x -- ^ the layer
117 => x -- ^ the layer
116− -> [(S (RecurrentShape x), S i, S o)] -- ^ the list of inputs and output to scan over
118+ -> [(RecTape x i o, S o)] -- ^ the list of inputs and output to scan over
117 -> (S (RecurrentShape x), [(Gradient x, S i)]) -- ^ list of gradients to fold and inputs to backprop
119 -> (S (RecurrentShape x), [(Gradient x, S i)]) -- ^ list of gradients to fold and inputs to backprop
118myscanbackward layer =
120myscanbackward layer =
121− goX :: S (RecurrentShape x) -> [(S (RecurrentShape x), S i, S o)] -> (S (RecurrentShape x), [(Gradient x, S i)])
123+ goX :: S (RecurrentShape x) -> [(RecTape x i o, S o)] -> (S (RecurrentShape x), [(Gradient x, S i)])
122− goX !lastback ((recShape, lastin, backgrad):xs) =
124+ goX !lastback ((recTape, backgrad):xs) =
123− let (layergrad, recgrad, ingrad) = runRecurrentBackwards layer recShape lastin lastback backgrad
125+ let (layergrad, recgrad, ingrad) = runRecurrentBackwards layer recTape lastback backgrad
124 (pushedback, ll) = goX recgrad xs
126 (pushedback, ll) = goX recgrad xs
125 in (pushedback, (layergrad, ingrad) : ll)
127 in (pushedback, (layergrad, ingrad) : ll)
126 goX !lastback [] = (lastback, [])
128 goX !lastback [] = (lastback, [])
@@ -134,8 +136,8 @@ runRecurrent (layer :~~> n) (() :~~+> nr) !x
134 (nr', o) = runRecurrent n nr ys
136 (nr', o) = runRecurrent n nr ys
135 in (() :~~+> nr', o)
137 in (() :~~+> nr', o)
136runRecurrent (layer :~@> n) (recin :~@+> nr) !x
138runRecurrent (layer :~@> n) (recin :~@+> nr) !x
137− = let (recin', y) = runRecurrentForwards layer recin x
139+ = let (_, recin', y) = runRecurrentForwards layer recin x
138− (nr', o) = runRecurrent n nr y
140+ (nr', o) = runRecurrent n nr y
139 in (recin' :~@+> nr', o)
141 in (recin' :~@+> nr', o)
140runRecurrent RNil RINil !x
142runRecurrent RNil RINil !x
141 = (RINil, x)
143 = (RINil, x)