@@ -8,14 +8,20 @@
8{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE MultiParamTypeClasses #-}
9{-# LANGUAGE FlexibleContexts #-}
9{-# LANGUAGE FlexibleContexts #-}
10{-# LANGUAGE FlexibleInstances #-}
10{-# LANGUAGE FlexibleInstances #-}
11+{-# LANGUAGE LambdaCase #-}
12module Grenade.Core.Network (
13module Grenade.Core.Network (
13 Layer (..)
14 Layer (..)
14 , Network (..)
15 , Network (..)
15 , UpdateLayer (..)
16 , UpdateLayer (..)
16 , LearningParameters (..)
17 , LearningParameters (..)
19+ , CreatableNetwork (..)
22+import Control.Monad.Random (MonadRandom)
19import Grenade.Core.Shape
25import Grenade.Core.Shape
21data LearningParameters = LearningParameters {
27data LearningParameters = LearningParameters {
@@ -26,12 +32,14 @@ data LearningParameters = LearningParameters {
27-- | Class for updating a layer. All layers implement this, and it is
33-- | Class for updating a layer. All layers implement this, and it is
28-- shape independent.
34-- shape independent.
29−class UpdateLayer x where
35+class Show x => UpdateLayer x where
30 -- | The type for the gradient for this layer.
36 -- | The type for the gradient for this layer.
31 -- Unit if there isn't a gradient to pass back.
37 -- Unit if there isn't a gradient to pass back.
32 type Gradient x :: *
38 type Gradient x :: *
33 -- | Update a layer with its gradient and learning parameters
39 -- | Update a layer with its gradient and learning parameters
34 runUpdate :: LearningParameters -> x -> Gradient x -> x
40 runUpdate :: LearningParameters -> x -> Gradient x -> x
41+ -- | Create a random layer, many layers will use pure
42+ createRandom :: MonadRandom m => m x
36-- | Class for a layer. All layers implement this, however, they don't
44-- | Class for a layer. All layers implement this, however, they don't
37-- need to implement it for all shapes, only ones which are appropriate.
45-- need to implement it for all shapes, only ones which are appropriate.
@@ -46,19 +54,35 @@ class UpdateLayer x => Layer x (i :: Shape) (o :: Shape) where
46 runBackards :: x -> S' i -> S' o -> (Gradient x, S' i)
54 runBackards :: x -> S' i -> S' o -> (Gradient x, S' i)
48-- | Type of a network.
56-- | Type of a network.
57+-- The [*] type specifies the types of the layers. This is needed for parallel
58+-- running and being all the gradients beck together.
49-- The [Shape] type specifies the shapes of data passed between the layers.
59-- The [Shape] type specifies the shapes of data passed between the layers.
50-- Could be considered to be a heterogeneous list of layers which are able to
60-- Could be considered to be a heterogeneous list of layers which are able to
51-- transform the data shapes of the network.
61-- transform the data shapes of the network.
52−data Network :: [Shape] -> * where
62+data Network :: [*] -> [Shape] -> * where
53− O :: (Show x, Layer x i o, KnownShape o, KnownShape i)
55− -> Network '[i, o]
63+ O :: Layer x i o => !x -> Network '[x] '[i, o]
56− (:~>) :: (Show x, Layer x i h, KnownShape h, KnownShape i)
58− -> !(Network (h ': hs))
59− -> Network (i ': h ': hs)
64+ (:~>) :: Layer x i h => !x -> !(Network xs (h ': hs)) -> Network (x ': xs) (i ': h ': hs)
60infixr 5 :~>
65infixr 5 :~>
62−instance Show (Network h) where
67+instance Show (Network l h) where
63 show (O a) = "O " ++ show a
68 show (O a) = "O " ++ show a
64 show (i :~> o) = show i ++ "\n:~>\n" ++ show o
69 show (i :~> o) = show i ++ "\n:~>\n" ++ show o
71+-- | Gradients of a network.
72+-- Parameterised on the layers of a Network.
73+data Gradients :: [*] -> * where
74+ OG :: UpdateLayer x => Gradient x -> Gradients '[x]
75+ (:/>) :: UpdateLayer x => Gradient x -> Gradients xs -> Gradients (x ': xs)
78+-- | A network can easily be created by hand with (:~>), but an easy way to initialise a random
79+-- network is with the randomNetwork.
80+class CreatableNetwork (xs :: [*]) (ss :: [Shape]) where
81+ -- | Create a network of the types requested
82+ randomNetwork :: MonadRandom m => m (Network xs ss)
84+instance Layer x i o => CreatableNetwork (x ': '[]) (i ': o ': '[]) where
85+ randomNetwork = O <$> createRandom
87+instance (Layer x i o, CreatableNetwork xs (o ': r ': rs)) => CreatableNetwork (x ': xs) (i ': o ': r ': rs) where
88+ randomNetwork = (:~>) <$> createRandom <*> randomNetwork