@@ -15,9 +15,8 @@ Copyright : (c) Huw Campbell, 2016-2017
15License : BSD2
15License : BSD2
16Stability : experimental
16Stability : experimental
18−This module defines the core data type for the simplest
18+This module defines the core data types and functions
19−Neural network we support.
19+for non-recurrent neural networks.
23#if __GLASGOW_HASKELL__ < 800
22#if __GLASGOW_HASKELL__ < 800
@@ -28,9 +27,12 @@ module Grenade.Core.Network (
28 Network (..)
27 Network (..)
29 , Gradients (..)
28 , Gradients (..)
30 , Tapes (..)
29 , Tapes (..)
31− , CreatableNetwork (..)
33 , applyUpdate
33 , applyUpdate
36import Control.Monad.Random ( MonadRandom )
38import Control.Monad.Random ( MonadRandom )
@@ -66,27 +68,94 @@ instance Show (Network '[] '[i]) where
66instance (Show x, Show (Network xs rs)) => Show (Network (x ': xs) (i ': rs)) where
68instance (Show x, Show (Network xs rs)) => Show (Network (x ': xs) (i ': rs)) where
67 show (x :~> xs) = show x ++ "\n~>\n" ++ show xs
69 show (x :~> xs) = show x ++ "\n~>\n" ++ show xs
70−-- | Apply one step of stochastic gradient decent across the network.
71−applyUpdate :: LearningParameters -> Network ls ss -> Gradients ls -> Network ls ss
72−applyUpdate _ NNil GNil
74−applyUpdate rate (layer :~> rest) (gradient :/> grest)
75− = runUpdate rate layer gradient :~> applyUpdate rate rest grest
79−-- | Gradients of a network.
71+-- | Gradient of a network.
80-- Parameterised on the layers of the network.
73-- Parameterised on the layers of the network.
81data Gradients :: [*] -> * where
74data Gradients :: [*] -> * where
82 GNil :: Gradients '[]
75 GNil :: Gradients '[]
83− (:/>) :: UpdateLayer x => Gradient x -> Gradients xs -> Gradients (x ': xs)
77+ (:/>) :: UpdateLayer x
80+ -> Gradients (x ': xs)
85−-- | Wegnert Tapes of a network.
82+-- | Wegnert Tape of a network.
86-- Parameterised on the layers and shapes of the network.
84-- Parameterised on the layers and shapes of the network.
87data Tapes :: [*] -> [Shape] -> * where
85data Tapes :: [*] -> [Shape] -> * where
88− TNil :: SingI i => Tapes '[] '[i]
86+ TNil :: SingI i
89− (:\>) :: (SingI i, SingI h, Layer x i h) => !(Tape x i h) -> !(Tapes xs (h ': hs)) -> Tapes (x ': xs) (i ': h ': hs)
89+ (:\>) :: (SingI i, SingI h, Layer x i h)
91+ -> !(Tapes xs (h ': hs))
92+ -> Tapes (x ': xs) (i ': h ': hs)
95+-- | Running a network forwards with some input data.
97+-- This gives the output, and the Wengert tape required for back
100+runNetwork :: forall layers shapes.
101+ Network layers shapes
103+ -> (Tapes layers shapes, S (Last shapes))
107+ go :: forall js ss. (Last js ~ Last shapes)
110+ -> (Tapes ss js, S (Last js))
111+ go (layer :~> n) !x =
112+ let (tape, forward) = runForwards layer x
113+ (tapes, answer) = go n forward
114+ in (tape :\> tapes, answer)
120+-- | Running a loss gradient back through the network.
122+-- This requires a Wengert tape, generated with the appropriate input
125+-- Gives the gradients for the layer, and the gradient across the
126+-- input (which may not be required).
128+runGradient :: forall layers shapes. Network layers shapes
129+ -> Tapes layers shapes
131+ -> (Gradients layers, S (Head shapes))
132+runGradient net tapes o =
135+ go :: forall js ss. (Last js ~ Last shapes)
138+ -> (Gradients ss, S (Head js))
139+ go (layer :~> n) (tape :\> nt) =
140+ let (gradients, feed) = go n nt
141+ (layer', backGrad) = runBackwards layer tape feed
142+ in (layer' :/> gradients, backGrad)
148+-- | Apply one step of stochastic gradient decent across the network.
149+applyUpdate :: LearningParameters
150+ -> Network layers shapes
152+ -> Network layers shapes
153+applyUpdate rate (layer :~> rest) (gradient :/> grest)
154+ = runUpdate rate layer gradient :~> applyUpdate rate rest grest
156+applyUpdate _ NNil GNil
91-- | A network can easily be created by hand with (:~>), but an easy way to initialise a random
160-- | A network can easily be created by hand with (:~>), but an easy way to initialise a random
92-- network is with the randomNetwork.
161-- network is with the randomNetwork.
@@ -115,36 +184,10 @@ instance (SingI i, SingI o, Layer x i o, Serialize x, Serialize (Network xs (o '
115-- This allows a complete network to be treated as a layer in a bigger network.
184-- This allows a complete network to be treated as a layer in a bigger network.
116instance CreatableNetwork sublayers subshapes => UpdateLayer (Network sublayers subshapes) where
185instance CreatableNetwork sublayers subshapes => UpdateLayer (Network sublayers subshapes) where
117 type Gradient (Network sublayers subshapes) = Gradients sublayers
186 type Gradient (Network sublayers subshapes) = Gradients sublayers
118− runUpdate = applyUpdate
187+ runUpdate = applyUpdate
119 createRandom = randomNetwork
188 createRandom = randomNetwork
121instance (CreatableNetwork sublayers subshapes, i ~ (Head subshapes), o ~ (Last subshapes)) => Layer (Network sublayers subshapes) i o where
190instance (CreatableNetwork sublayers subshapes, i ~ (Head subshapes), o ~ (Last subshapes)) => Layer (Network sublayers subshapes) i o where
122 type Tape (Network sublayers subshapes) i o = Tapes sublayers subshapes
191 type Tape (Network sublayers subshapes) i o = Tapes sublayers subshapes
124− runForwards net i =
192+ runForwards = runNetwork
125− go i net
193+ runBackwards = runGradient
127− go :: forall js ss. (Last js ~ Last subshapes)
128− => S (Head js) -- ^ input vector
129− -> Network ss js -- ^ network to train
130− -> (Tapes ss js, S (Last js))
131− go !x (layer :~> n) =
132− let (tape, forward) = runForwards layer x
133− (tapes, answer) = go forward n
134− in (tape :\> tapes, answer)
138− runBackwards net tapes o =
141− go :: forall js ss. (Last js ~ Last subshapes)
142− => Network ss js -- ^ network to train
143− -> Tapes ss js -- ^ network to train
144− -> (Gradients ss, S (Head js))
145− go (layer :~> n) (tape :\> nt) =
146− let (gradients, feed) = go n nt
147− (layer', backGrad) = runBackwards layer tape feed
148− in (layer' :/> gradients, backGrad)