on 9d9dfac help sign in
.gitignore+1−3
since splitsnapshots
unifiedsplit
@@ -1,6 +1,4 @@
1−cabal.project.local
2.cabal-sandbox/
1.cabal-sandbox/
3cabal.sandbox.config
2cabal.sandbox.config
4dist/
3dist/
5−dist-newstyle/
4+
6−.stack-work/
.travis.yml+11−12
@@ -2,30 +2,29 @@
2
2
3# The following enables several GHC versions to be tested; often it's enough to test only against the last release in a major GHC version. Feel free to omit lines listings versions you don't need/want testing for.
3# The following enables several GHC versions to be tested; often it's enough to test only against the last release in a major GHC version. Feel free to omit lines listings versions you don't need/want testing for.
4env:
4env:
5− - GHCVER=8.0.2
6− - GHCVER=8.2.2
7− - GHCVER=8.4.4
8− - GHCVER=8.6.5
9− - GHCVER=8.8.3
5+ - CABALVER=1.22 GHCVER=7.10.3
10− - GHCVER=8.10.1
6+ - CABALVER=1.24 GHCVER=8.0.2
7+ - CABALVER=2.0 GHCVER=8.2.1
11
8
12# Note: the distinction between `before_install` and `install` is not important.
9# Note: the distinction between `before_install` and `install` is not important.
13before_install:
10before_install:
14 - travis_retry sudo add-apt-repository -y ppa:hvr/ghc
11 - travis_retry sudo add-apt-repository -y ppa:hvr/ghc
15 - travis_retry sudo apt-get update
12 - travis_retry sudo apt-get update
16− - travis_retry sudo apt-get install cabal-install-3.2 ghc-$GHCVER libblas-dev liblapack-dev
13+ - travis_retry sudo apt-get install cabal-install-$CABALVER ghc-$GHCVER happy-1.19.5 alex-3.1.7 libblas-dev liblapack-dev
17− - export PATH=/opt/cabal/bin:/opt/ghc/$GHCVER/bin:$PATH
14+ - export PATH=/opt/alex/3.1.7/bin:/opt/happy/1.19.5/bin:/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$HOME/.cabal/bin:$PATH
18
15
19install:
16install:
17+ - cabal --version
20 - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
18 - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
21− - travis_retry cabal-3.2 update
19+ - travis_retry cabal update
20+ - cabal sandbox init
21+ - cabal install --enable-tests --enable-benchmarks
22
22
23notifications:
23notifications:
24 email: false
24 email: false
25
25
26# Here starts the actual work to be performed for the package under test; any command which exits with a non-zero exit code causes the build to fail.
26# Here starts the actual work to be performed for the package under test; any command which exits with a non-zero exit code causes the build to fail.
27script:
27script:
28− - cabal-3.2 configure --enable-tests
29− - cabal-3.2 build all
28+ - cabal build
30− - cabal-3.2 test --test-show-details=direct -j1
29+ - cabal test --show-details=streaming
31
30
README.md+2−2
@@ -24,7 +24,7 @@ specified and initialised with random weights in a few lines of code with
24type MNIST
24type MNIST
25 = Network
25 = Network
26 '[ Convolution 1 10 5 5 1 1, Pooling 2 2 2 2, Relu
26 '[ Convolution 1 10 5 5 1 1, Pooling 2 2 2 2, Relu
27− , Convolution 10 16 5 5 1 1, Pooling 2 2 2 2, Reshape, Relu
27+ , Convolution 10 16 5 5 1 1, Pooling 2 2 2 2, FlattenLayer, Relu
28 , FullyConnected 256 80, Logit, FullyConnected 80 10, Logit]
28 , FullyConnected 256 80, Logit, FullyConnected 80 10, Logit]
29 '[ 'D2 28 28, 'D3 24 24 10, 'D3 12 12 10, 'D3 12 12 10
29 '[ 'D2 28 28, 'D3 24 24 10, 'D3 12 12 10, 'D3 12 12 10
30 , 'D3 8 8 16, 'D3 4 4 16, 'D1 256, 'D1 256
30 , 'D3 8 8 16, 'D3 4 4 16, 'D1 256, 'D1 256
@@ -159,7 +159,7 @@ and the tests run using:
159./mafia test
159./mafia test
160```
160```
161
161
162−Grenade builds with ghc 7.10, 8.0, 8.2 and 8.4.
162+Grenade builds with ghc 7.10 and 8.0.
163
163
164Thanks
164Thanks
165------
165------
examples/grenade-examples.cabal+9−10
@@ -26,7 +26,7 @@ executable feedforward
26 , bytestring
26 , bytestring
27 , cereal
27 , cereal
28 , either
28 , either
29− , optparse-applicative >= 0.13 && < 0.18
29+ , optparse-applicative >= 0.13 && < 0.15
30 , text == 1.2.*
30 , text == 1.2.*
31 , mtl >= 2.2.1 && < 2.3
31 , mtl >= 2.2.1 && < 2.3
32 , hmatrix
32 , hmatrix
@@ -42,10 +42,10 @@ executable mnist
42 , grenade
42 , grenade
43 , attoparsec
43 , attoparsec
44 , either
44 , either
45− , optparse-applicative >= 0.13 && < 0.18
45+ , optparse-applicative >= 0.13 && < 0.15
46 , text == 1.2.*
46 , text == 1.2.*
47 , mtl >= 2.2.1 && < 2.3
47 , mtl >= 2.2.1 && < 2.3
48− , hmatrix >= 0.18 && < 0.21
48+ , hmatrix >= 0.18 && < 0.19
49 , transformers
49 , transformers
50 , semigroups
50 , semigroups
51 , singletons
51 , singletons
@@ -61,10 +61,10 @@ executable gan-mnist
61 , bytestring
61 , bytestring
62 , cereal
62 , cereal
63 , either
63 , either
64− , optparse-applicative >= 0.13 && < 0.18
64+ , optparse-applicative >= 0.13 && < 0.15
65 , text == 1.2.*
65 , text == 1.2.*
66 , mtl >= 2.2.1 && < 2.3
66 , mtl >= 2.2.1 && < 2.3
67− , hmatrix >= 0.18 && < 0.21
67+ , hmatrix >= 0.18 && < 0.19
68 , transformers
68 , transformers
69 , semigroups
69 , semigroups
70 , singletons
70 , singletons
@@ -78,10 +78,10 @@ executable recurrent
78 , grenade
78 , grenade
79 , attoparsec
79 , attoparsec
80 , either
80 , either
81− , optparse-applicative >= 0.13 && < 0.18
81+ , optparse-applicative >= 0.13 && < 0.15
82 , text == 1.2.*
82 , text == 1.2.*
83 , mtl >= 2.2.1 && < 2.3
83 , mtl >= 2.2.1 && < 2.3
84− , hmatrix >= 0.18 && < 0.21
84+ , hmatrix >= 0.18 && < 0.19
85 , transformers
85 , transformers
86 , semigroups
86 , semigroups
87 , singletons
87 , singletons
@@ -96,14 +96,13 @@ executable shakespeare
96 , bytestring
96 , bytestring
97 , cereal
97 , cereal
98 , either
98 , either
99− , optparse-applicative >= 0.13 && < 0.18
99+ , optparse-applicative >= 0.13 && < 0.15
100 , text == 1.2.*
100 , text == 1.2.*
101 , mtl >= 2.2.1 && < 2.3
101 , mtl >= 2.2.1 && < 2.3
102− , hmatrix >= 0.18 && < 0.21
102+ , hmatrix >= 0.18 && < 0.19
103 , transformers
103 , transformers
104 , semigroups
104 , semigroups
105 , singletons
105 , singletons
106− , singletons-base
107 , vector
106 , vector
108 , MonadRandom
107 , MonadRandom
109 , containers
108 , containers
examples/mafiadeleted−62
@@ -1,62 +0,0 @@
1−#!/bin/sh -eu
2−
3−: ${MAFIA_HOME:=$HOME/.mafia}
4−: ${MAFIA_VERSIONS:=$MAFIA_HOME/versions}
5−
6−latest_version () {
7− git ls-remote https://github.com/haskell-mafia/mafia | grep refs/heads/master | cut -f 1
8−}
9−
10−build_version() {
11− MAFIA_VERSION="$1"
12− MAFIA_TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t 'exec_mafia')
13− MAFIA_FILE=mafia-$MAFIA_VERSION
14− MAFIA_PATH=$MAFIA_VERSIONS/$MAFIA_FILE
15− mkdir -p $MAFIA_VERSIONS
16− echo "Building $MAFIA_FILE in $MAFIA_TEMP"
17− git clone https://github.com/haskell-mafia/mafia $MAFIA_TEMP
18− git --git-dir="$MAFIA_TEMP/.git" --work-tree="$MAFIA_TEMP" reset --hard $MAFIA_VERSION || {
19− echo "mafia version ($MAFIA_VERSION) could not be found." >&2
20− exit 1
21− }
22− (cd "$MAFIA_TEMP" && ./bin/bootstrap) || {
23− got=$?
24− echo "mafia version ($MAFIA_VERSION) could not be built." >&2
25− exit "$got"
26− }
27− chmod +x "$MAFIA_TEMP/.cabal-sandbox/bin/mafia"
28− # Ensure executable is on same file-system so final mv is atomic.
29− mv -f "$MAFIA_TEMP/.cabal-sandbox/bin/mafia" "$MAFIA_PATH.$$"
30− mv "$MAFIA_PATH.$$" "$MAFIA_PATH" || {
31− rm -f "$MAFIA_PATH.$$"
32− echo "INFO: mafia version ($MAFIA_VERSION) already exists not overiding," >&2
33− echo "INFO: this is expected if parallel builds of the same version of" >&2
34− echo "INFO: mafia occur, we are playing by first in, wins." >&2
35− exit 0
36− }
37−}
38−
39−enable_version() {
40− if [ $# -eq 0 ]; then
41− MAFIA_VERSION="$(latest_version)"
42− echo "INFO: No explicit mafia version requested installing latest ($MAFIA_VERSION)." >&2
43− else
44− MAFIA_VERSION="$1"
45− fi
46− [ -x "$MAFIA_HOME/versions/mafia-$MAFIA_VERSION" ] || build_version "$MAFIA_VERSION"
47− ln -sf "$MAFIA_HOME/versions/mafia-$MAFIA_VERSION" "$MAFIA_HOME/versions/mafia"
48−}
49−
50−exec_mafia () {
51− [ -x "$MAFIA_HOME/versions/mafia" ] || enable_version
52− "$MAFIA_HOME/versions/mafia" "$@"
53−}
54−
55−#
56−# The actual start of the script.....
57−#
58−
59−case "${1:-}" in
60−upgrade) shift; enable_version "$@" ;;
61−*) exec_mafia "$@"
62−esac
examples/main/feedforward.hs+1−3
@@ -1,5 +1,4 @@
1{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE CPP #-}
3{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE ScopedTypeVariables #-}
5{-# LANGUAGE TypeOperators #-}
4{-# LANGUAGE TypeOperators #-}
@@ -11,9 +10,8 @@ import Data.List ( foldl' )
11
10
12import qualified Data.ByteString as B
11import qualified Data.ByteString as B
13import Data.Serialize
12import Data.Serialize
14−#if ! MIN_VERSION_base(4,13,0)
15import Data.Semigroup ( (<>) )
13import Data.Semigroup ( (<>) )
16−#endif
14+
17import GHC.TypeLits
15import GHC.TypeLits
18
16
19import qualified Numeric.LinearAlgebra.Static as SA
17import qualified Numeric.LinearAlgebra.Static as SA
examples/main/gan-mnist.hs−3
@@ -1,5 +1,4 @@
1{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE CPP #-}
3{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE GADTs #-}
3{-# LANGUAGE GADTs #-}
5{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE ScopedTypeVariables #-}
@@ -44,9 +43,7 @@ import Control.Monad.Trans.Except
44import qualified Data.Attoparsec.Text as A
43import qualified Data.Attoparsec.Text as A
45import qualified Data.ByteString as B
44import qualified Data.ByteString as B
46import Data.List ( foldl' )
45import Data.List ( foldl' )
47−#if ! MIN_VERSION_base(4,13,0)
48import Data.Semigroup ( (<>) )
46import Data.Semigroup ( (<>) )
49−#endif
50import Data.Serialize
47import Data.Serialize
51import qualified Data.Text as T
48import qualified Data.Text as T
52import qualified Data.Text.IO as T
49import qualified Data.Text.IO as T
examples/main/mnist.hs−4
@@ -1,5 +1,4 @@
1{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE CPP #-}
3{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE ScopedTypeVariables #-}
5{-# LANGUAGE TypeOperators #-}
4{-# LANGUAGE TypeOperators #-}
@@ -14,10 +13,7 @@ import Control.Monad.Trans.Except
14
13
15import qualified Data.Attoparsec.Text as A
14import qualified Data.Attoparsec.Text as A
16import Data.List ( foldl' )
15import Data.List ( foldl' )
17−#if ! MIN_VERSION_base(4,13,0)
18import Data.Semigroup ( (<>) )
16import Data.Semigroup ( (<>) )
19−#endif
20−
21import qualified Data.Text as T
17import qualified Data.Text as T
22import qualified Data.Text.IO as T
18import qualified Data.Text.IO as T
23import qualified Data.Vector.Storable as V
19import qualified Data.Vector.Storable as V
examples/main/recurrent.hs+5−5
@@ -9,12 +9,12 @@
9import Control.Monad ( foldM )
9import Control.Monad ( foldM )
10import Control.Monad.Random ( MonadRandom, getRandomR )
10import Control.Monad.Random ( MonadRandom, getRandomR )
11
11
12−#if MIN_VERSION_base(4,13,0)
12+#if __GLASGOW_HASKELL__ < 800
13import Data.List ( unfoldr )
13import Data.List ( unfoldr )
14#else
14#else
15import Data.List ( cycle, unfoldr )
15import Data.List ( cycle, unfoldr )
16−import Data.Semigroup ( (<>) )
17#endif
16#endif
17+import Data.Semigroup ( (<>) )
18
18
19import qualified Numeric.LinearAlgebra.Static as SA
19import qualified Numeric.LinearAlgebra.Static as SA
20
20
@@ -31,10 +31,10 @@ import Grenade.Recurrent
31-- creation function know how to treat the layers.
31-- creation function know how to treat the layers.
32type R = Recurrent
32type R = Recurrent
33
33
34−type RecNet = RecurrentNetwork '[ R (LSTM 1 1)]
34+type RecNet = RecurrentNetwork '[ R (LSTM 1 4), R (LSTM 4 1)]
35− '[ 'D1 1, 'D1 1]
35+ '[ 'D1 1, 'D1 4, 'D1 1 ]
36
36
37−type RecInput = RecurrentInputs '[ R (LSTM 1 1)]
37+type RecInput = RecurrentInputs '[ R (LSTM 1 4), R (LSTM 4 1)]
38
38
39randomNet :: MonadRandom m => m RecNet
39randomNet :: MonadRandom m => m RecNet
40randomNet = randomRecurrent
40randomNet = randomRecurrent
examples/main/shakespeare.hs+16−16
@@ -1,5 +1,5 @@
1{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE CPP #-}
2+{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE ScopedTypeVariables #-}
5{-# LANGUAGE TypeOperators #-}
5{-# LANGUAGE TypeOperators #-}
@@ -13,16 +13,18 @@ import Control.Monad.Trans.Except
13import Data.Char ( isUpper, toUpper, toLower )
13import Data.Char ( isUpper, toUpper, toLower )
14import Data.List ( foldl' )
14import Data.List ( foldl' )
15import Data.Maybe ( fromMaybe )
15import Data.Maybe ( fromMaybe )
16−
16+import Data.Semigroup ( (<>) )
17
17
18import qualified Data.Vector as V
18import qualified Data.Vector as V
19import Data.Vector ( Vector )
19import Data.Vector ( Vector )
20
20
21import qualified Data.Map as M
21import qualified Data.Map as M
22+import Data.Proxy ( Proxy (..) )
22
23
23import qualified Data.ByteString as B
24import qualified Data.ByteString as B
24import Data.Serialize
25import Data.Serialize
25
26
27+import Data.Singletons.Prelude
26import GHC.TypeLits
28import GHC.TypeLits
27
29
28import Numeric.LinearAlgebra.Static ( konst )
30import Numeric.LinearAlgebra.Static ( konst )
@@ -34,8 +36,6 @@ import Grenade.Recurrent
34import Grenade.Utils.OneHot
36import Grenade.Utils.OneHot
35
37
36import System.IO.Unsafe ( unsafeInterleaveIO )
38import System.IO.Unsafe ( unsafeInterleaveIO )
37−import Data.Proxy
38−import Prelude.Singletons
39
39
40-- The defininition for our natural language recurrent network.
40-- The defininition for our natural language recurrent network.
41-- This network is able to learn and generate simple words in
41-- This network is able to learn and generate simple words in
@@ -77,34 +77,34 @@ loadShakespeare path = do
77 return (V.fromList hot, m, cs)
77 return (V.fromList hot, m, cs)
78
78
79trainSlice :: LearningParameters -> Shakespeare -> Shakespearian -> Vector Int -> Int -> Int -> (Shakespeare, Shakespearian)
79trainSlice :: LearningParameters -> Shakespeare -> Shakespearian -> Vector Int -> Int -> Int -> (Shakespeare, Shakespearian)
80−trainSlice !lrate !net !recIns input offset size =
80+trainSlice !rate !net !recIns input offset size =
81 let e = fmap (x . oneHot) . V.toList $ V.slice offset size input
81 let e = fmap (x . oneHot) . V.toList $ V.slice offset size input
82 in case reverse e of
82 in case reverse e of
83 (o : l : xs) ->
83 (o : l : xs) ->
84 let examples = reverse $ (l, Just o) : ((,Nothing) <$> xs)
84 let examples = reverse $ (l, Just o) : ((,Nothing) <$> xs)
85− in trainRecurrent lrate net recIns examples
85+ in trainRecurrent rate net recIns examples
86 _ -> error "Not enough input"
86 _ -> error "Not enough input"
87 where
87 where
88 x = fromMaybe (error "Hot variable didn't fit.")
88 x = fromMaybe (error "Hot variable didn't fit.")
89
89
90runShakespeare :: ShakespeareOpts -> ExceptT String IO ()
90runShakespeare :: ShakespeareOpts -> ExceptT String IO ()
91−runShakespeare opts = do
91+runShakespeare ShakespeareOpts {..} = do
92− (shakespeare, oneHotMap, oneHotDictionary) <- loadShakespeare $ trainingFile opts
92+ (shakespeare, oneHotMap, oneHotDictionary) <- loadShakespeare trainingFile
93 (net0, i0) <- lift $
93 (net0, i0) <- lift $
94− case loadPath opts of
94+ case loadPath of
95 Just loadFile -> netLoad loadFile
95 Just loadFile -> netLoad loadFile
96 Nothing -> (,0) <$> randomNet
96 Nothing -> (,0) <$> randomNet
97
97
98 (trained, bestInput) <- lift $ foldM (\(!net, !io) size -> do
98 (trained, bestInput) <- lift $ foldM (\(!net, !io) size -> do
99− xs <- take (iterations opts `div` 10) <$> getRandomRs (0, length shakespeare - size - 1)
99+ xs <- take (iterations `div` 10) <$> getRandomRs (0, length shakespeare - size - 1)
100− let (!trained, !bestInput) = foldl' (\(!n, !i) offset -> trainSlice (rate opts) n i shakespeare offset size) (net, io) xs
100+ let (!trained, !bestInput) = foldl' (\(!n, !i) offset -> trainSlice rate n i shakespeare offset size) (net, io) xs
101− results <- take 1000 <$> generateParagraph trained bestInput (temperature opts) oneHotMap oneHotDictionary ( S1D $ konst 0)
101+ results <- take 1000 <$> generateParagraph trained bestInput temperature oneHotMap oneHotDictionary ( S1D $ konst 0)
102 putStrLn ("TRAINING STEP WITH SIZE: " ++ show size)
102 putStrLn ("TRAINING STEP WITH SIZE: " ++ show size)
103 putStrLn (unAnnotateCapitals results)
103 putStrLn (unAnnotateCapitals results)
104 return (trained, bestInput)
104 return (trained, bestInput)
105− ) (net0, i0) $ replicate 10 (sequenceSize opts)
105+ ) (net0, i0) $ replicate 10 sequenceSize
106
106
107− case savePath opts of
107+ case savePath of
108 Just saveFile -> lift . B.writeFile saveFile $ runPut (put trained >> put bestInput)
108 Just saveFile -> lift . B.writeFile saveFile $ runPut (put trained >> put bestInput)
109 Nothing -> return ()
109 Nothing -> return ()
110
110
@@ -116,12 +116,12 @@ generateParagraph :: forall layers shapes n a. (Last shapes ~ 'D1 n, Head shapes
116 -> Vector a
116 -> Vector a
117 -> S ('D1 n)
117 -> S ('D1 n)
118 -> IO [a]
118 -> IO [a]
119−generateParagraph n s temp hotmap hotdict =
119+generateParagraph n s temperature hotmap hotdict =
120 go s
120 go s
121 where
121 where
122 go x y =
122 go x y =
123 do let (_, ns, o) = runRecurrent n x y
123 do let (_, ns, o) = runRecurrent n x y
124− un <- sample temp hotdict o
124+ un <- sample temperature hotdict o
125 Just re <- return $ makeHot hotmap un
125 Just re <- return $ makeHot hotmap un
126 rest <- unsafeInterleaveIO $ go ns re
126 rest <- unsafeInterleaveIO $ go ns re
127 return (un : rest)
127 return (un : rest)
framework/mafiadeleted−62
@@ -1,62 +0,0 @@
1−#!/bin/sh -eu
2−
3−: ${MAFIA_HOME:=$HOME/.mafia}
4−: ${MAFIA_VERSIONS:=$MAFIA_HOME/versions}
5−
6−latest_version () {
7− git ls-remote https://github.com/haskell-mafia/mafia | grep refs/heads/master | cut -f 1
8−}
9−
10−build_version() {
11− MAFIA_VERSION="$1"
12− MAFIA_TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t 'exec_mafia')
13− MAFIA_FILE=mafia-$MAFIA_VERSION
14− MAFIA_PATH=$MAFIA_VERSIONS/$MAFIA_FILE
15− mkdir -p $MAFIA_VERSIONS
16− echo "Building $MAFIA_FILE in $MAFIA_TEMP"
17− git clone https://github.com/haskell-mafia/mafia $MAFIA_TEMP
18− git --git-dir="$MAFIA_TEMP/.git" --work-tree="$MAFIA_TEMP" reset --hard $MAFIA_VERSION || {
19− echo "mafia version ($MAFIA_VERSION) could not be found." >&2
20− exit 1
21− }
22− (cd "$MAFIA_TEMP" && ./bin/bootstrap) || {
23− got=$?
24− echo "mafia version ($MAFIA_VERSION) could not be built." >&2
25− exit "$got"
26− }
27− chmod +x "$MAFIA_TEMP/.cabal-sandbox/bin/mafia"
28− # Ensure executable is on same file-system so final mv is atomic.
29− mv -f "$MAFIA_TEMP/.cabal-sandbox/bin/mafia" "$MAFIA_PATH.$$"
30− mv "$MAFIA_PATH.$$" "$MAFIA_PATH" || {
31− rm -f "$MAFIA_PATH.$$"
32− echo "INFO: mafia version ($MAFIA_VERSION) already exists not overiding," >&2
33− echo "INFO: this is expected if parallel builds of the same version of" >&2
34− echo "INFO: mafia occur, we are playing by first in, wins." >&2
35− exit 0
36− }
37−}
38−
39−enable_version() {
40− if [ $# -eq 0 ]; then
41− MAFIA_VERSION="$(latest_version)"
42− echo "INFO: No explicit mafia version requested installing latest ($MAFIA_VERSION)." >&2
43− else
44− MAFIA_VERSION="$1"
45− fi
46− [ -x "$MAFIA_HOME/versions/mafia-$MAFIA_VERSION" ] || build_version "$MAFIA_VERSION"
47− ln -sf "$MAFIA_HOME/versions/mafia-$MAFIA_VERSION" "$MAFIA_HOME/versions/mafia"
48−}
49−
50−exec_mafia () {
51− [ -x "$MAFIA_HOME/versions/mafia" ] || enable_version
52− "$MAFIA_HOME/versions/mafia" "$@"
53−}
54−
55−#
56−# The actual start of the script.....
57−#
58−
59−case "${1:-}" in
60−upgrade) shift; enable_version "$@" ;;
61−*) exec_mafia "$@"
62−esac
grenade.cabal+15−33
@@ -7,7 +7,7 @@ maintainer: Huw Campbell <huw.campbell@gmail.com>
7copyright: (c) 2016-2017 Huw Campbell.
7copyright: (c) 2016-2017 Huw Campbell.
8synopsis: Practical Deep Learning in Haskell
8synopsis: Practical Deep Learning in Haskell
9category: AI, Machine Learning
9category: AI, Machine Learning
10−cabal-version: >= 1.10
10+cabal-version: >= 1.8
11build-type: Simple
11build-type: Simple
12description:
12description:
13 Grenade is a composable, dependently typed, practical, and fast
13 Grenade is a composable, dependently typed, practical, and fast
@@ -38,17 +38,14 @@ source-repository head
38library
38library
39 build-depends:
39 build-depends:
40 base >= 4.8 && < 5
40 base >= 4.8 && < 5
41− , bytestring >= 0.10.0
41+ , bytestring == 0.10.*
42− , containers >= 0.5 && < 0.7
42+ , containers >= 0.5 && < 0.6
43 , cereal >= 0.5 && < 0.6
43 , cereal >= 0.5 && < 0.6
44 , deepseq >= 1.4 && < 1.5
44 , deepseq >= 1.4 && < 1.5
45− , hmatrix >= 0.18 && < 0.21
45+ , hmatrix == 0.18.*
46 , MonadRandom >= 0.4 && < 0.6
46 , MonadRandom >= 0.4 && < 0.6
47− , primitive >= 0.6 && < 0.8
47+ , primitive >= 0.6 && < 0.7
48− -- Versions of singletons are *tightly* coupled with the
48+ , singletons >= 2.1 && < 2.4
49− -- GHC version so its fine to drop version bounds.
50− , singletons
51− , singletons-base
52 , vector >= 0.11 && < 0.13
49 , vector >= 0.11 && < 0.13
53
50
54 ghc-options:
51 ghc-options:
@@ -56,14 +53,9 @@ library
56 hs-source-dirs:
53 hs-source-dirs:
57 src
54 src
58
55
59− default-language: Haskell2010
60−
61 if impl(ghc < 8.0)
56 if impl(ghc < 8.0)
62 ghc-options: -fno-warn-incomplete-patterns
57 ghc-options: -fno-warn-incomplete-patterns
63− cpp-options: -DType=*
64
58
65− if impl(ghc >= 8.6)
66− default-extensions: NoStarIsType
67
59
68 exposed-modules:
60 exposed-modules:
69 Grenade
61 Grenade
@@ -89,7 +81,6 @@ library
89 Grenade.Layers.Pooling
81 Grenade.Layers.Pooling
90 Grenade.Layers.Relu
82 Grenade.Layers.Relu
91 Grenade.Layers.Reshape
83 Grenade.Layers.Reshape
92− Grenade.Layers.Sinusoid
93 Grenade.Layers.Softmax
84 Grenade.Layers.Softmax
94 Grenade.Layers.Tanh
85 Grenade.Layers.Tanh
95 Grenade.Layers.Trivial
86 Grenade.Layers.Trivial
@@ -132,7 +123,6 @@ test-suite test
132 hs-source-dirs:
123 hs-source-dirs:
133 test
124 test
134
125
135− default-language: Haskell2010
136
126
137 other-modules: Test.Hedgehog.Compat
127 other-modules: Test.Hedgehog.Compat
138 Test.Hedgehog.Hmatrix
128 Test.Hedgehog.Hmatrix
@@ -153,20 +143,16 @@ test-suite test
153
143
154 if impl(ghc < 8.0)
144 if impl(ghc < 8.0)
155 ghc-options: -fno-warn-incomplete-patterns
145 ghc-options: -fno-warn-incomplete-patterns
156− cpp-options: -DType=*
157−
158− if impl(ghc >= 8.6)
159− default-extensions: NoStarIsType
160
146
161 build-depends:
147 build-depends:
162− base
148+ base >= 4.8 && < 5
163 , grenade
149 , grenade
164− , hedgehog >= 1.0 && < 1.1
150+ , hedgehog >= 0.5 && < 0.6
165 , hmatrix
151 , hmatrix
166 , mtl
152 , mtl
167 , singletons
153 , singletons
168 , text == 1.2.*
154 , text == 1.2.*
169− , typelits-witnesses < 0.4
155+ , typelits-witnesses
170 , transformers
156 , transformers
171 , constraints
157 , constraints
172 , MonadRandom
158 , MonadRandom
@@ -186,12 +172,10 @@ benchmark bench
186 hs-source-dirs:
172 hs-source-dirs:
187 bench
173 bench
188
174
189− default-language: Haskell2010
190−
191 build-depends:
175 build-depends:
192− base
176+ base >= 3 && < 5
193− , bytestring
177+ , bytestring == 0.10.*
194− , criterion >= 1.1 && < 1.6
178+ , criterion >= 1.1 && < 1.3
195 , grenade
179 , grenade
196 , hmatrix
180 , hmatrix
197
181
@@ -205,11 +189,9 @@ benchmark bench-lstm
205 hs-source-dirs:
189 hs-source-dirs:
206 bench
190 bench
207
191
208− default-language: Haskell2010
209−
210 build-depends:
192 build-depends:
211− base
193+ base >= 3 && < 5
212− , bytestring
194+ , bytestring == 0.10.*
213− , criterion
195+ , criterion == 1.1.*
214 , grenade
196 , grenade
215 , hmatrix
197 , hmatrix
mafiamode 120000 → 100755+123−1
@@ -1 +0,0 @@
1−framework/mafia
@@ -0,0 +1,123 @@
1+#!/bin/sh -eu
2+
3+: ${MAFIA_HOME:=$HOME/.mafia}
4+
5+fetch_latest () {
6+ if [ -z ${MAFIA_TEST_MODE+x} ]; then
7+ TZ=$(date +"%T")
8+ curl --silent "https://raw.githubusercontent.com/ambiata/mafia/master/script/mafia?$TZ"
9+ else
10+ cat ../script/mafia
11+ fi
12+}
13+
14+latest_version () {
15+ git ls-remote https://github.com/ambiata/mafia | grep refs/heads/master | cut -f 1
16+}
17+
18+local_version () {
19+ awk '/^# Version: / { print $3; exit 0; }' $0
20+}
21+
22+run_upgrade () {
23+ MAFIA_TEMP=$(mktemp 2>/dev/null || mktemp -t 'upgrade_mafia')
24+
25+ clean_up () {
26+ rm -f "$MAFIA_TEMP"
27+ }
28+
29+ trap clean_up EXIT
30+
31+ MAFIA_CUR="$0"
32+
33+ if [ -L "$MAFIA_CUR" ]; then
34+ echo 'Refusing to overwrite a symlink; run `upgrade` from the canonical path.' >&2
35+ exit 1
36+ fi
37+
38+ echo "Checking for a new version of mafia ..."
39+ fetch_latest > $MAFIA_TEMP
40+
41+ LATEST_VERSION=$(latest_version)
42+ echo "# Version: $LATEST_VERSION" >> $MAFIA_TEMP
43+
44+ if ! cmp $MAFIA_CUR $MAFIA_TEMP >/dev/null 2>&1; then
45+ mv $MAFIA_TEMP $MAFIA_CUR
46+ chmod +x $MAFIA_CUR
47+ echo "New version found and upgraded. You can now commit it to your git repo."
48+ else
49+ echo "You have latest mafia."
50+ fi
51+}
52+
53+exec_mafia () {
54+ MAFIA_VERSION=$(local_version)
55+
56+ if [ "x$MAFIA_VERSION" = "x" ]; then
57+ # If we can't find the mafia version, then we need to upgrade the script.
58+ run_upgrade
59+ else
60+ MAFIA_BIN=$MAFIA_HOME/bin
61+ MAFIA_FILE=mafia-$MAFIA_VERSION
62+ MAFIA_PATH=$MAFIA_BIN/$MAFIA_FILE
63+
64+ [ -f "$MAFIA_PATH" ] || {
65+ # Create a temporary directory which will be deleted when the script
66+ # terminates. Unfortunately `mktemp` doesn't behave the same on
67+ # Linux and OS/X so we need to try two different approaches.
68+ MAFIA_TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t 'exec_mafia')
69+
70+ # Create a temporary file in MAFIA_BIN so we can do an atomic copy/move dance.
71+ mkdir -p $MAFIA_BIN
72+
73+ clean_up () {
74+ rm -rf "$MAFIA_TEMP"
75+ }
76+
77+ trap clean_up EXIT
78+
79+ echo "Building $MAFIA_FILE in $MAFIA_TEMP"
80+
81+ ( cd "$MAFIA_TEMP"
82+
83+ git clone https://github.com/ambiata/mafia
84+ cd mafia
85+
86+ git reset --hard $MAFIA_VERSION
87+
88+ bin/bootstrap ) || exit $?
89+
90+ MAFIA_PATH_TEMP=$(mktemp --tmpdir=$MAFIA_BIN $MAFIA_FILE-XXXXXX 2>/dev/null || TMPDIR=$MAFIA_BIN mktemp -t $MAFIA_FILE)
91+
92+ clean_up_temp () {
93+ clean_up
94+ rm -f "$MAFIA_PATH_TEMP"
95+ }
96+ trap clean_up_temp EXIT
97+
98+ cp "$MAFIA_TEMP/mafia/.cabal-sandbox/bin/mafia" "$MAFIA_PATH_TEMP"
99+ chmod 755 "$MAFIA_PATH_TEMP"
100+ mv "$MAFIA_PATH_TEMP" "$MAFIA_PATH"
101+
102+ clean_up_temp
103+ }
104+
105+ exec $MAFIA_PATH "$@"
106+ fi
107+}
108+
109+#
110+# The actual start of the script.....
111+#
112+
113+if [ $# -gt 0 ]; then
114+ MODE="$1"
115+else
116+ MODE=""
117+fi
118+
119+case "$MODE" in
120+upgrade) shift; run_upgrade "$@" ;;
121+*) exec_mafia "$@"
122+esac
123+# Version: 360716306a06db842ec022a7b9f161d2208483f0
src/Grenade/Core/Layer.hs+3−8
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE GADTs #-}
2{-# LANGUAGE GADTs #-}
4{-# LANGUAGE TypeOperators #-}
3{-# LANGUAGE TypeOperators #-}
@@ -20,7 +19,7 @@ neural network.
20There are two classes of interest: `UpdateLayer` and `Layer`.
19There are two classes of interest: `UpdateLayer` and `Layer`.
21
20
22`UpdateLayer` is required for all types which are used as a layer
21`UpdateLayer` is required for all types which are used as a layer
23−in a network. Having no shape information, this class is agnostic
22+in a network. Having no shape information, this class is agnotostic
24to the input and output data of the layer.
23to the input and output data of the layer.
25
24
26An instance of `Layer` on the other hand is required for usage in
25An instance of `Layer` on the other hand is required for usage in
@@ -42,10 +41,6 @@ import Control.Monad.Random ( MonadRandom )
42
41
43import Data.List ( foldl' )
42import Data.List ( foldl' )
44
43
45−#if MIN_VERSION_base(4,9,0)
46−import Data.Kind (Type)
47−#endif
48−
49import Grenade.Core.Shape
44import Grenade.Core.Shape
50import Grenade.Core.LearningParameters
45import Grenade.Core.LearningParameters
51
46
@@ -55,7 +50,7 @@ import Grenade.Core.LearningParameters
55class UpdateLayer x where
50class UpdateLayer x where
56 -- | The type for the gradient for this layer.
51 -- | The type for the gradient for this layer.
57 -- Unit if there isn't a gradient to pass back.
52 -- Unit if there isn't a gradient to pass back.
58− type Gradient x :: Type
53+ type Gradient x :: *
59
54
60 -- | Update a layer with its gradient and learning parameters
55 -- | Update a layer with its gradient and learning parameters
61 runUpdate :: LearningParameters -> x -> Gradient x -> x
56 runUpdate :: LearningParameters -> x -> Gradient x -> x
@@ -77,7 +72,7 @@ class UpdateLayer x => Layer x (i :: Shape) (o :: Shape) where
77 -- | The Wengert tape for this layer. Includes all that is required
72 -- | The Wengert tape for this layer. Includes all that is required
78 -- to generate the back propagated gradients efficiently. As a
73 -- to generate the back propagated gradients efficiently. As a
79 -- default, `S i` is fine.
74 -- default, `S i` is fine.
80− type Tape x i o :: Type
75+ type Tape x i o :: *
81
76
82 -- | Used in training and scoring. Take the input from the previous
77 -- | Used in training and scoring. Take the input from the previous
83 -- layer, and give the output from this layer.
78 -- layer, and give the output from this layer.
src/Grenade/Core/Network.hs+5−10
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE BangPatterns #-}
4{-# LANGUAGE GADTs #-}
3{-# LANGUAGE GADTs #-}
@@ -34,16 +33,12 @@ module Grenade.Core.Network (
34import Control.Monad.Random ( MonadRandom )
33import Control.Monad.Random ( MonadRandom )
35
34
36import Data.Singletons
35import Data.Singletons
36+import Data.Singletons.Prelude
37import Data.Serialize
37import Data.Serialize
38
38
39−#if MIN_VERSION_base(4,9,0)
40−import Data.Kind (Type)
41−#endif
42−
43import Grenade.Core.Layer
39import Grenade.Core.Layer
44import Grenade.Core.LearningParameters
40import Grenade.Core.LearningParameters
45import Grenade.Core.Shape
41import Grenade.Core.Shape
46−import Prelude.Singletons
47
42
48-- | Type of a network.
43-- | Type of a network.
49--
44--
@@ -53,7 +48,7 @@ import Prelude.Singletons
53--
48--
54-- Can be considered to be a heterogeneous list of layers which are able to
49-- Can be considered to be a heterogeneous list of layers which are able to
55-- transform the data shapes of the network.
50-- transform the data shapes of the network.
56−data Network :: [Type] -> [Shape] -> Type where
51+data Network :: [*] -> [Shape] -> * where
57 NNil :: SingI i
52 NNil :: SingI i
58 => Network '[] '[i]
53 => Network '[] '[i]
59
54
@@ -71,7 +66,7 @@ instance (Show x, Show (Network xs rs)) => Show (Network (x ': xs) (i ': rs)) wh
71-- | Gradient of a network.
66-- | Gradient of a network.
72--
67--
73-- Parameterised on the layers of the network.
68-- Parameterised on the layers of the network.
74−data Gradients :: [Type] -> Type where
69+data Gradients :: [*] -> * where
75 GNil :: Gradients '[]
70 GNil :: Gradients '[]
76
71
77 (:/>) :: UpdateLayer x
72 (:/>) :: UpdateLayer x
@@ -82,7 +77,7 @@ data Gradients :: [Type] -> Type where
82-- | Wegnert Tape of a network.
77-- | Wegnert Tape of a network.
83--
78--
84-- Parameterised on the layers and shapes of the network.
79-- Parameterised on the layers and shapes of the network.
85−data Tapes :: [Type] -> [Shape] -> Type where
80+data Tapes :: [*] -> [Shape] -> * where
86 TNil :: SingI i
81 TNil :: SingI i
87 => Tapes '[] '[i]
82 => Tapes '[] '[i]
88
83
@@ -157,7 +152,7 @@ applyUpdate _ NNil GNil
157
152
158-- | A network can easily be created by hand with (:~>), but an easy way to
153-- | A network can easily be created by hand with (:~>), but an easy way to
159-- initialise a random network is with the randomNetwork.
154-- initialise a random network is with the randomNetwork.
160−class CreatableNetwork (xs :: [Type]) (ss :: [Shape]) where
155+class CreatableNetwork (xs :: [*]) (ss :: [Shape]) where
161 -- | Create a network with randomly initialised weights.
156 -- | Create a network with randomly initialised weights.
162 --
157 --
163 -- Calls to this function will not compile if the type of the neural
158 -- Calls to this function will not compile if the type of the neural
src/Grenade/Core/Runner.hs+1−2
@@ -13,12 +13,11 @@ module Grenade.Core.Runner (
13 , runNet
13 , runNet
14 ) where
14 ) where
15
15
16+import Data.Singletons.Prelude
16
17
17import Grenade.Core.LearningParameters
18import Grenade.Core.LearningParameters
18import Grenade.Core.Network
19import Grenade.Core.Network
19import Grenade.Core.Shape
20import Grenade.Core.Shape
20−import Data.Singletons
21−import Prelude.Singletons
22
21
23-- | Perform reverse automatic differentiation on the network
22-- | Perform reverse automatic differentiation on the network
24-- for the current input and expected output.
23-- for the current input and expected output.
src/Grenade/Core/Shape.hs+21−29
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE GADTs #-}
2{-# LANGUAGE GADTs #-}
4{-# LANGUAGE KindSignatures #-}
3{-# LANGUAGE KindSignatures #-}
@@ -8,7 +7,6 @@
8{-# LANGUAGE FlexibleContexts #-}
7{-# LANGUAGE FlexibleContexts #-}
9{-# LANGUAGE ScopedTypeVariables #-}
8{-# LANGUAGE ScopedTypeVariables #-}
10{-# LANGUAGE RankNTypes #-}
9{-# LANGUAGE RankNTypes #-}
11−{-# LANGUAGE UndecidableInstances #-}
12{-|
10{-|
13Module : Grenade.Core.Shape
11Module : Grenade.Core.Shape
14Description : Dependently typed shapes of data which are passed between layers of a network
12Description : Dependently typed shapes of data which are passed between layers of a network
@@ -19,22 +17,26 @@ Stability : experimental
19
17
20-}
18-}
21module Grenade.Core.Shape (
19module Grenade.Core.Shape (
20+ Shape (..)
22− S (..)
21+ , S (..)
23− , Shape (..)
22+ , Sing (..)
24− , SShape (..)
23+
25 , randomOfShape
24 , randomOfShape
26 , fromStorable
25 , fromStorable
27 ) where
26 ) where
28
27
29import Control.DeepSeq (NFData (..))
28import Control.DeepSeq (NFData (..))
30import Control.Monad.Random ( MonadRandom, getRandom )
29import Control.Monad.Random ( MonadRandom, getRandom )
31−import Data.Kind (Type)
30+
32import Data.Proxy
31import Data.Proxy
33import Data.Serialize
32import Data.Serialize
34import Data.Singletons
33import Data.Singletons
34+import Data.Singletons.TypeLits
35import Data.Vector.Storable ( Vector )
35import Data.Vector.Storable ( Vector )
36import qualified Data.Vector.Storable as V
36import qualified Data.Vector.Storable as V
37+
37import GHC.TypeLits
38import GHC.TypeLits
39+
38import qualified Numeric.LinearAlgebra.Static as H
40import qualified Numeric.LinearAlgebra.Static as H
39import Numeric.LinearAlgebra.Static
41import Numeric.LinearAlgebra.Static
40import qualified Numeric.LinearAlgebra as NLA
42import qualified Numeric.LinearAlgebra as NLA
@@ -79,27 +81,17 @@ deriving instance Show (S n)
79-- These could probably be derived with template haskell, but this seems
81-- These could probably be derived with template haskell, but this seems
80-- clear and makes adding the KnownNat constraints simple.
82-- clear and makes adding the KnownNat constraints simple.
81-- We can also keep our code TH free, which is great.
83-- We can also keep our code TH free, which is great.
82−#if MIN_VERSION_singletons(2,6,0)
83−-- In singletons 2.6 Sing switched from a data family to a type family.
84−type instance Sing = SShape
85−
86−data SShape :: Shape -> Type where
87− D1Sing :: KnownNat a => SShape ('D1 a)
88− D2Sing :: (KnownNat a, KnownNat b) => SShape ('D2 a b)
89− D3Sing :: (KnownNat (a * c), KnownNat a, KnownNat b, KnownNat c) => SShape ('D3 a b c)
90−#else
91data instance Sing (n :: Shape) where
84data instance Sing (n :: Shape) where
92 D1Sing :: Sing a -> Sing ('D1 a)
85 D1Sing :: Sing a -> Sing ('D1 a)
93 D2Sing :: Sing a -> Sing b -> Sing ('D2 a b)
86 D2Sing :: Sing a -> Sing b -> Sing ('D2 a b)
94 D3Sing :: KnownNat (a * c) => Sing a -> Sing b -> Sing c -> Sing ('D3 a b c)
87 D3Sing :: KnownNat (a * c) => Sing a -> Sing b -> Sing c -> Sing ('D3 a b c)
95−#endif
96
88
97instance KnownNat a => SingI ('D1 a) where
89instance KnownNat a => SingI ('D1 a) where
98− sing = D1Sing
90+ sing = D1Sing sing
99instance (KnownNat a, KnownNat b) => SingI ('D2 a b) where
91instance (KnownNat a, KnownNat b) => SingI ('D2 a b) where
100− sing = D2Sing
92+ sing = D2Sing sing sing
101instance (KnownNat a, KnownNat b, KnownNat c, KnownNat (a * c)) => SingI ('D3 a b c) where
93instance (KnownNat a, KnownNat b, KnownNat c, KnownNat (a * c)) => SingI ('D3 a b c) where
102− sing = D3Sing
94+ sing = D3Sing sing sing sing
103
95
104instance SingI x => Num (S x) where
96instance SingI x => Num (S x) where
105 (+) = n2 (+)
97 (+) = n2 (+)
@@ -148,13 +140,13 @@ randomOfShape :: forall x m. ( MonadRandom m, SingI x ) => m (S x)
148randomOfShape = do
140randomOfShape = do
149 seed :: Int <- getRandom
141 seed :: Int <- getRandom
150 return $ case (sing :: Sing x) of
142 return $ case (sing :: Sing x) of
151− D1Sing ->
143+ D1Sing SNat ->
152 S1D (randomVector seed Uniform * 2 - 1)
144 S1D (randomVector seed Uniform * 2 - 1)
153
145
154− D2Sing ->
146+ D2Sing SNat SNat ->
155 S2D (uniformSample seed (-1) 1)
147 S2D (uniformSample seed (-1) 1)
156
148
157− D3Sing ->
149+ D3Sing SNat SNat SNat ->
158 S3D (uniformSample seed (-1) 1)
150 S3D (uniformSample seed (-1) 1)
159
151
160-- | Generate a shape from a Storable Vector.
152-- | Generate a shape from a Storable Vector.
@@ -162,13 +154,13 @@ randomOfShape = do
162-- Returns Nothing if the vector is of the wrong size.
154-- Returns Nothing if the vector is of the wrong size.
163fromStorable :: forall x. SingI x => Vector Double -> Maybe (S x)
155fromStorable :: forall x. SingI x => Vector Double -> Maybe (S x)
164fromStorable xs = case sing :: Sing x of
156fromStorable xs = case sing :: Sing x of
165− D1Sing ->
157+ D1Sing SNat ->
166 S1D <$> H.create xs
158 S1D <$> H.create xs
167
159
168− D2Sing ->
160+ D2Sing SNat SNat ->
169 S2D <$> mkL xs
161 S2D <$> mkL xs
170
162
171− D3Sing ->
163+ D3Sing SNat SNat SNat ->
172 S3D <$> mkL xs
164 S3D <$> mkL xs
173 where
165 where
174 mkL :: forall rows columns. (KnownNat rows, KnownNat columns)
166 mkL :: forall rows columns. (KnownNat rows, KnownNat columns)
@@ -205,13 +197,13 @@ n2 f (S2D x) (S2D y) = S2D (f x y)
205n2 f (S3D x) (S3D y) = S3D (f x y)
197n2 f (S3D x) (S3D y) = S3D (f x y)
206
198
207-- Helper function for creating the number instances
199-- Helper function for creating the number instances
208−nk :: forall x. (SingI x) => Double -> S x
200+nk :: forall x. SingI x => Double -> S x
209nk x = case (sing :: Sing x) of
201nk x = case (sing :: Sing x) of
210− D1Sing ->
202+ D1Sing SNat ->
211 S1D (konst x)
203 S1D (konst x)
212
204
213− D2Sing ->
205+ D2Sing SNat SNat ->
214 S2D (konst x)
206 S2D (konst x)
215
207
216− D3Sing ->
208+ D3Sing SNat SNat SNat ->
217 S3D (konst x)
209 S3D (konst x)
src/Grenade/Layers/Concat.hs+1−7
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE GADTs #-}
2{-# LANGUAGE GADTs #-}
4{-# LANGUAGE TypeOperators #-}
3{-# LANGUAGE TypeOperators #-}
@@ -9,7 +8,6 @@
9{-# LANGUAGE FlexibleInstances #-}
8{-# LANGUAGE FlexibleInstances #-}
10{-# LANGUAGE ScopedTypeVariables #-}
9{-# LANGUAGE ScopedTypeVariables #-}
11{-# LANGUAGE StandaloneDeriving #-}
10{-# LANGUAGE StandaloneDeriving #-}
12−{-# LANGUAGE UndecidableInstances #-}
13{-|
11{-|
14Module : Grenade.Layers.Concat
12Module : Grenade.Layers.Concat
15Description : Concatenation layer
13Description : Concatenation layer
@@ -28,10 +26,6 @@ import Data.Serialize
28import Data.Singletons
26import Data.Singletons
29import GHC.TypeLits
27import GHC.TypeLits
30
28
31−#if MIN_VERSION_base(4,9,0)
32−import Data.Kind (Type)
33−#endif
34−
35import Grenade.Core
29import Grenade.Core
36
30
37import Numeric.LinearAlgebra.Static ( row, (===), splitRows, unrow, (#), split, R )
31import Numeric.LinearAlgebra.Static ( row, (===), splitRows, unrow, (#), split, R )
@@ -49,7 +43,7 @@ import Numeric.LinearAlgebra.Static ( row, (===), splitRows, unrow, (#
49--
43--
50-- 3D images become 3D images with more channels. The sizes must be the same, one can use Pad
44-- 3D images become 3D images with more channels. The sizes must be the same, one can use Pad
51-- and Crop layers to ensure this is the case.
45-- and Crop layers to ensure this is the case.
52−data Concat :: Shape -> Type -> Shape -> Type -> Type where
46+data Concat :: Shape -> * -> Shape -> * -> * where
53 Concat :: x -> y -> Concat m x n y
47 Concat :: x -> y -> Concat m x n y
54
48
55instance (Show x, Show y) => Show (Concat m x n y) where
49instance (Show x, Show y) => Show (Concat m x n y) where
src/Grenade/Layers/Convolution.hs+6−7
@@ -1,13 +1,12 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE ScopedTypeVariables #-}
3+{-# LANGUAGE RecordWildCards #-}
4{-# LANGUAGE GADTs #-}
4{-# LANGUAGE GADTs #-}
5{-# LANGUAGE TypeOperators #-}
5{-# LANGUAGE TypeOperators #-}
6{-# LANGUAGE TypeFamilies #-}
6{-# LANGUAGE TypeFamilies #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE FlexibleInstances #-}
8{-# LANGUAGE FlexibleInstances #-}
9{-# LANGUAGE FlexibleContexts #-}
9{-# LANGUAGE FlexibleContexts #-}
10−{-# LANGUAGE UndecidableInstances #-}
11{-|
10{-|
12Module : Grenade.Layers.Convolution
11Module : Grenade.Layers.Convolution
13Description : Convolution layer
12Description : Convolution layer
@@ -28,9 +27,9 @@ import Control.Monad.Random hiding ( fromList )
28import Data.Maybe
27import Data.Maybe
29import Data.Proxy
28import Data.Proxy
30import Data.Serialize
29import Data.Serialize
30+import Data.Singletons.TypeLits
31
31
32import GHC.TypeLits
32import GHC.TypeLits
33−import Data.Kind (Type)
34
33
35import Numeric.LinearAlgebra hiding ( uniformSample, konst )
34import Numeric.LinearAlgebra hiding ( uniformSample, konst )
36import qualified Numeric.LinearAlgebra as LA
35import qualified Numeric.LinearAlgebra as LA
@@ -57,7 +56,7 @@ data Convolution :: Nat -- Number of channels, for the first layer this could be
57 -> Nat -- The number of column in the kernel filter
56 -> Nat -- The number of column in the kernel filter
58 -> Nat -- The row stride of the convolution filter
57 -> Nat -- The row stride of the convolution filter
59 -> Nat -- The columns stride of the convolution filter
58 -> Nat -- The columns stride of the convolution filter
60− -> Type where
59+ -> * where
61 Convolution :: ( KnownNat channels
60 Convolution :: ( KnownNat channels
62 , KnownNat filters
61 , KnownNat filters
63 , KnownNat kernelRows
62 , KnownNat kernelRows
@@ -76,7 +75,7 @@ data Convolution' :: Nat -- Number of channels, for the first layer this could b
76 -> Nat -- The number of column in the kernel filter
75 -> Nat -- The number of column in the kernel filter
77 -> Nat -- The row stride of the convolution filter
76 -> Nat -- The row stride of the convolution filter
78 -> Nat -- The columns stride of the convolution filter
77 -> Nat -- The columns stride of the convolution filter
79− -> Type where
78+ -> * where
80 Convolution' :: ( KnownNat channels
79 Convolution' :: ( KnownNat channels
81 , KnownNat filters
80 , KnownNat filters
82 , KnownNat kernelRows
81 , KnownNat kernelRows
@@ -131,8 +130,8 @@ instance ( KnownNat channels
131 , KnownNat (kernelRows * kernelColumns * channels)
130 , KnownNat (kernelRows * kernelColumns * channels)
132 ) => UpdateLayer (Convolution channels filters kernelRows kernelColumns strideRows strideColumns) where
131 ) => UpdateLayer (Convolution channels filters kernelRows kernelColumns strideRows strideColumns) where
133 type Gradient (Convolution channels filters kernelRows kernelColumns strideRows strideColumns) = (Convolution' channels filters kernelRows kernelColumns strideRows strideColumns)
132 type Gradient (Convolution channels filters kernelRows kernelColumns strideRows strideColumns) = (Convolution' channels filters kernelRows kernelColumns strideRows strideColumns)
134− runUpdate lp (Convolution oldKernel oldMomentum) (Convolution' kernelGradient) =
133+ runUpdate LearningParameters {..} (Convolution oldKernel oldMomentum) (Convolution' kernelGradient) =
135− let (newKernel, newMomentum) = descendMatrix (learningRate lp) (learningMomentum lp) (learningRegulariser lp) oldKernel kernelGradient oldMomentum
134+ let (newKernel, newMomentum) = descendMatrix learningRate learningMomentum learningRegulariser oldKernel kernelGradient oldMomentum
136 in Convolution newKernel newMomentum
135 in Convolution newKernel newMomentum
137
136
138 createRandom = randomConvolution
137 createRandom = randomConvolution
src/Grenade/Layers/Crop.hs+2−10
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE GADTs #-}
3{-# LANGUAGE GADTs #-}
@@ -6,7 +5,6 @@
6{-# LANGUAGE TypeFamilies #-}
5{-# LANGUAGE TypeFamilies #-}
7{-# LANGUAGE FlexibleContexts #-}
6{-# LANGUAGE FlexibleContexts #-}
8{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
9−{-# LANGUAGE UndecidableInstances #-}
10{-|
8{-|
11Module : Grenade.Layers.Crop
9Module : Grenade.Layers.Crop
12Description : Cropping layer
10Description : Cropping layer
@@ -20,10 +18,8 @@ module Grenade.Layers.Crop (
20
18
21import Data.Maybe
19import Data.Maybe
22import Data.Proxy
20import Data.Proxy
23−import Data.Serialize
21+import Data.Singletons.TypeLits
24−
25import GHC.TypeLits
22import GHC.TypeLits
26−import Data.Kind (Type)
27
23
28import Grenade.Core
24import Grenade.Core
29import Grenade.Layers.Internal.Pad
25import Grenade.Layers.Internal.Pad
@@ -35,7 +31,7 @@ import Numeric.LinearAlgebra.Static (extract, create)
35data Crop :: Nat
31data Crop :: Nat
36 -> Nat
32 -> Nat
37 -> Nat
33 -> Nat
38− -> Nat -> Type where
34+ -> Nat -> * where
39 Crop :: Crop cropLeft cropTop cropRight cropBottom
35 Crop :: Crop cropLeft cropTop cropRight cropBottom
40
36
41instance Show (Crop cropLeft cropTop cropRight cropBottom) where
37instance Show (Crop cropLeft cropTop cropRight cropBottom) where
@@ -46,10 +42,6 @@ instance UpdateLayer (Crop l t r b) where
46 runUpdate _ x _ = x
42 runUpdate _ x _ = x
47 createRandom = return Crop
43 createRandom = return Crop
48
44
49−instance Serialize (Crop l t r b) where
50− put _ = return ()
51− get = return Crop
52−
53-- | A two dimentional image can be cropped.
45-- | A two dimentional image can be cropped.
54instance ( KnownNat cropLeft
46instance ( KnownNat cropLeft
55 , KnownNat cropTop
47 , KnownNat cropTop
src/Grenade/Layers/Deconvolution.hs+6−7
@@ -1,13 +1,12 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE ScopedTypeVariables #-}
3+{-# LANGUAGE RecordWildCards #-}
4{-# LANGUAGE GADTs #-}
4{-# LANGUAGE GADTs #-}
5{-# LANGUAGE TypeOperators #-}
5{-# LANGUAGE TypeOperators #-}
6{-# LANGUAGE TypeFamilies #-}
6{-# LANGUAGE TypeFamilies #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE FlexibleInstances #-}
8{-# LANGUAGE FlexibleInstances #-}
9{-# LANGUAGE FlexibleContexts #-}
9{-# LANGUAGE FlexibleContexts #-}
10−{-# LANGUAGE UndecidableInstances #-}
11{-|
10{-|
12Module : Grenade.Layers.Deconvolution
11Module : Grenade.Layers.Deconvolution
13Description : Deconvolution layer
12Description : Deconvolution layer
@@ -32,9 +31,9 @@ import Control.Monad.Random hiding ( fromList )
32import Data.Maybe
31import Data.Maybe
33import Data.Proxy
32import Data.Proxy
34import Data.Serialize
33import Data.Serialize
34+import Data.Singletons.TypeLits
35
35
36import GHC.TypeLits
36import GHC.TypeLits
37−import Data.Kind (Type)
38
37
39import Numeric.LinearAlgebra hiding ( uniformSample, konst )
38import Numeric.LinearAlgebra hiding ( uniformSample, konst )
40import qualified Numeric.LinearAlgebra as LA
39import qualified Numeric.LinearAlgebra as LA
@@ -56,7 +55,7 @@ data Deconvolution :: Nat -- Number of channels, for the first layer this could
56 -> Nat -- The number of column in the kernel filter
55 -> Nat -- The number of column in the kernel filter
57 -> Nat -- The row stride of the Deconvolution filter
56 -> Nat -- The row stride of the Deconvolution filter
58 -> Nat -- The columns stride of the Deconvolution filter
57 -> Nat -- The columns stride of the Deconvolution filter
59− -> Type where
58+ -> * where
60 Deconvolution :: ( KnownNat channels
59 Deconvolution :: ( KnownNat channels
61 , KnownNat filters
60 , KnownNat filters
62 , KnownNat kernelRows
61 , KnownNat kernelRows
@@ -75,7 +74,7 @@ data Deconvolution' :: Nat -- Number of channels, for the first layer this could
75 -> Nat -- The number of column in the kernel filter
74 -> Nat -- The number of column in the kernel filter
76 -> Nat -- The row stride of the Deconvolution filter
75 -> Nat -- The row stride of the Deconvolution filter
77 -> Nat -- The columns stride of the Deconvolution filter
76 -> Nat -- The columns stride of the Deconvolution filter
78− -> Type where
77+ -> * where
79 Deconvolution' :: ( KnownNat channels
78 Deconvolution' :: ( KnownNat channels
80 , KnownNat filters
79 , KnownNat filters
81 , KnownNat kernelRows
80 , KnownNat kernelRows
@@ -130,8 +129,8 @@ instance ( KnownNat channels
130 , KnownNat (kernelRows * kernelColumns * filters)
129 , KnownNat (kernelRows * kernelColumns * filters)
131 ) => UpdateLayer (Deconvolution channels filters kernelRows kernelColumns strideRows strideColumns) where
130 ) => UpdateLayer (Deconvolution channels filters kernelRows kernelColumns strideRows strideColumns) where
132 type Gradient (Deconvolution channels filters kernelRows kernelColumns strideRows strideColumns) = (Deconvolution' channels filters kernelRows kernelColumns strideRows strideColumns)
131 type Gradient (Deconvolution channels filters kernelRows kernelColumns strideRows strideColumns) = (Deconvolution' channels filters kernelRows kernelColumns strideRows strideColumns)
133− runUpdate lp (Deconvolution oldKernel oldMomentum) (Deconvolution' kernelGradient) =
132+ runUpdate LearningParameters {..} (Deconvolution oldKernel oldMomentum) (Deconvolution' kernelGradient) =
134− let (newKernel, newMomentum) = descendMatrix (learningRate lp) (learningMomentum lp) (learningRegulariser lp) oldKernel kernelGradient oldMomentum
133+ let (newKernel, newMomentum) = descendMatrix learningRate learningMomentum learningRegulariser oldKernel kernelGradient oldMomentum
135 in Deconvolution newKernel newMomentum
134 in Deconvolution newKernel newMomentum
136
135
137 createRandom = randomDeconvolution
136 createRandom = randomDeconvolution
src/Grenade/Layers/FullyConnected.hs+5−4
@@ -1,4 +1,5 @@
1{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE RecordWildCards #-}
2{-# LANGUAGE TypeOperators #-}
3{-# LANGUAGE TypeOperators #-}
3{-# LANGUAGE TypeFamilies #-}
4{-# LANGUAGE TypeFamilies #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
5{-# LANGUAGE MultiParamTypeClasses #-}
@@ -13,6 +14,7 @@ import Control.Monad.Random hiding (fromList)
13
14
14import Data.Proxy
15import Data.Proxy
15import Data.Serialize
16import Data.Serialize
17+import Data.Singletons.TypeLits
16
18
17import qualified Numeric.LinearAlgebra as LA
19import qualified Numeric.LinearAlgebra as LA
18import Numeric.LinearAlgebra.Static
20import Numeric.LinearAlgebra.Static
@@ -20,7 +22,6 @@ import Numeric.LinearAlgebra.Static
20import Grenade.Core
22import Grenade.Core
21
23
22import Grenade.Layers.Internal.Update
24import Grenade.Layers.Internal.Update
23−import GHC.TypeLits
24
25
25-- | A basic fully connected (or inner product) neural network layer.
26-- | A basic fully connected (or inner product) neural network layer.
26data FullyConnected i o = FullyConnected
27data FullyConnected i o = FullyConnected
@@ -37,9 +38,9 @@ instance Show (FullyConnected i o) where
37instance (KnownNat i, KnownNat o) => UpdateLayer (FullyConnected i o) where
38instance (KnownNat i, KnownNat o) => UpdateLayer (FullyConnected i o) where
38 type Gradient (FullyConnected i o) = (FullyConnected' i o)
39 type Gradient (FullyConnected i o) = (FullyConnected' i o)
39
40
40− runUpdate lp (FullyConnected (FullyConnected' oldBias oldActivations) (FullyConnected' oldBiasMomentum oldMomentum)) (FullyConnected' biasGradient activationGradient) =
41+ runUpdate LearningParameters {..} (FullyConnected (FullyConnected' oldBias oldActivations) (FullyConnected' oldBiasMomentum oldMomentum)) (FullyConnected' biasGradient activationGradient) =
41− let (newBias, newBiasMomentum) = descendVector (learningRate lp) (learningMomentum lp) (learningRegulariser lp) oldBias biasGradient oldBiasMomentum
42+ let (newBias, newBiasMomentum) = descendVector learningRate learningMomentum learningRegulariser oldBias biasGradient oldBiasMomentum
42− (newActivations, newMomentum) = descendMatrix (learningRate lp) (learningMomentum lp) (learningRegulariser lp) oldActivations activationGradient oldMomentum
43+ (newActivations, newMomentum) = descendMatrix learningRate learningMomentum learningRegulariser oldActivations activationGradient oldMomentum
43 in FullyConnected (FullyConnected' newBias newActivations) (FullyConnected' newBiasMomentum newMomentum)
44 in FullyConnected (FullyConnected' newBias newActivations) (FullyConnected' newBiasMomentum newMomentum)
44
45
45 createRandom = randomFullyConnected
46 createRandom = randomFullyConnected
src/Grenade/Layers/Merge.hs+1−6
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE GADTs #-}
2{-# LANGUAGE GADTs #-}
4{-# LANGUAGE TypeOperators #-}
3{-# LANGUAGE TypeOperators #-}
@@ -24,17 +23,13 @@ import Data.Serialize
24
23
25import Data.Singletons
24import Data.Singletons
26
25
27−#if MIN_VERSION_base(4,9,0)
28−import Data.Kind (Type)
29−#endif
30−
31import Grenade.Core
26import Grenade.Core
32
27
33-- | A Merging layer.
28-- | A Merging layer.
34--
29--
35-- Similar to Concat layer, except sums the activations instead of creating a larger
30-- Similar to Concat layer, except sums the activations instead of creating a larger
36-- shape.
31-- shape.
37−data Merge :: Type -> Type -> Type where
32+data Merge :: * -> * -> * where
38 Merge :: x -> y -> Merge x y
33 Merge :: x -> y -> Merge x y
39
34
40instance (Show x, Show y) => Show (Merge x y) where
35instance (Show x, Show y) => Show (Merge x y) where
src/Grenade/Layers/Pad.hs+4−7
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE GADTs #-}
3{-# LANGUAGE GADTs #-}
@@ -6,7 +5,6 @@
6{-# LANGUAGE TypeFamilies #-}
5{-# LANGUAGE TypeFamilies #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE FlexibleContexts #-}
7{-# LANGUAGE FlexibleContexts #-}
9−{-# LANGUAGE UndecidableInstances #-}
10{-|
8{-|
11Module : Grenade.Core.Pad
9Module : Grenade.Core.Pad
12Description : Padding layer for 2D and 3D images
10Description : Padding layer for 2D and 3D images
@@ -21,9 +19,8 @@ module Grenade.Layers.Pad (
21import Data.Maybe
19import Data.Maybe
22import Data.Proxy
20import Data.Proxy
23import Data.Serialize
21import Data.Serialize
24−
22+import Data.Singletons.TypeLits
25import GHC.TypeLits
23import GHC.TypeLits
26−import Data.Kind (Type)
27
24
28import Grenade.Core
25import Grenade.Core
29import Grenade.Layers.Internal.Pad
26import Grenade.Layers.Internal.Pad
@@ -37,7 +34,7 @@ import Numeric.LinearAlgebra.Static (extract, create)
37data Pad :: Nat
34data Pad :: Nat
38 -> Nat
35 -> Nat
39 -> Nat
36 -> Nat
40− -> Nat -> Type where
37+ -> Nat -> * where
41 Pad :: Pad padLeft padTop padRight padBottom
38 Pad :: Pad padLeft padTop padRight padBottom
42
39
43instance Show (Pad padLeft padTop padRight padBottom) where
40instance Show (Pad padLeft padTop padRight padBottom) where
@@ -52,7 +49,7 @@ instance Serialize (Pad l t r b) where
52 put _ = return ()
49 put _ = return ()
53 get = return Pad
50 get = return Pad
54
51
55−-- | A two dimentional image can be padded.
52+-- | A two dimentional image can be padped.
56instance ( KnownNat padLeft
53instance ( KnownNat padLeft
57 , KnownNat padTop
54 , KnownNat padTop
58 , KnownNat padRight
55 , KnownNat padRight
@@ -82,7 +79,7 @@ instance ( KnownNat padLeft
82 vs = subMatrix (padt, padl) (nrows, ncols) m
79 vs = subMatrix (padt, padl) (nrows, ncols) m
83 in ((), S2D . fromJust . create $ vs)
80 in ((), S2D . fromJust . create $ vs)
84
81
85−-- | A two dimentional image can be padded.
82+-- | A two dimentional image can be padped.
86instance ( KnownNat padLeft
83instance ( KnownNat padLeft
87 , KnownNat padTop
84 , KnownNat padTop
88 , KnownNat padRight
85 , KnownNat padRight
src/Grenade/Layers/Pooling.hs+2−5
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE StandaloneDeriving #-}
3{-# LANGUAGE StandaloneDeriving #-}
@@ -7,7 +6,6 @@
7{-# LANGUAGE TypeFamilies #-}
6{-# LANGUAGE TypeFamilies #-}
8{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
9{-# LANGUAGE FlexibleContexts #-}
8{-# LANGUAGE FlexibleContexts #-}
10−{-# LANGUAGE UndecidableInstances #-}
11{-|
9{-|
12Module : Grenade.Core.Pooling
10Module : Grenade.Core.Pooling
13Description : Max Pooling layer for 2D and 3D images
11Description : Max Pooling layer for 2D and 3D images
@@ -22,9 +20,8 @@ module Grenade.Layers.Pooling (
22import Data.Maybe
20import Data.Maybe
23import Data.Proxy
21import Data.Proxy
24import Data.Serialize
22import Data.Serialize
25−
23+import Data.Singletons.TypeLits
26import GHC.TypeLits
24import GHC.TypeLits
27−import Data.Kind (Type)
28
25
29import Grenade.Core
26import Grenade.Core
30import Grenade.Layers.Internal.Pooling
27import Grenade.Layers.Internal.Pooling
@@ -39,7 +36,7 @@ import Numeric.LinearAlgebra.Static as LAS hiding ((|||), build, toRow
39-- The kernel size dictates which input and output sizes will "fit". Fitting the equation:
36-- The kernel size dictates which input and output sizes will "fit". Fitting the equation:
40-- `out = (in - kernel) / stride + 1` for both dimensions.
37-- `out = (in - kernel) / stride + 1` for both dimensions.
41--
38--
42−data Pooling :: Nat -> Nat -> Nat -> Nat -> Type where
39+data Pooling :: Nat -> Nat -> Nat -> Nat -> * where
43 Pooling :: Pooling kernelRows kernelColumns strideRows strideColumns
40 Pooling :: Pooling kernelRows kernelColumns strideRows strideColumns
44
41
45instance Show (Pooling k k' s s') where
42instance Show (Pooling k k' s s') where
src/Grenade/Layers/Reshape.hs+1−1
@@ -3,7 +3,6 @@
3{-# LANGUAGE TypeFamilies #-}
3{-# LANGUAGE TypeFamilies #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
5{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleContexts #-}
6−{-# LANGUAGE UndecidableInstances #-}
7{-|
6{-|
8Module : Grenade.Layers.Reshape
7Module : Grenade.Layers.Reshape
9Description : Multipurpose reshaping layer
8Description : Multipurpose reshaping layer
@@ -17,6 +16,7 @@ module Grenade.Layers.Reshape (
17
16
18import Data.Serialize
17import Data.Serialize
19
18
19+import Data.Singletons.TypeLits
20import GHC.TypeLits
20import GHC.TypeLits
21
21
22import Numeric.LinearAlgebra.Static
22import Numeric.LinearAlgebra.Static
src/Grenade/Layers/Sinusoid.hsdeleted−39
@@ -1,39 +0,0 @@
1−{-# LANGUAGE DataKinds #-}
2−{-# LANGUAGE FlexibleInstances #-}
3−{-# LANGUAGE MultiParamTypeClasses #-}
4−{-# LANGUAGE TypeFamilies #-}
5−{-# LANGUAGE TypeOperators #-}
6−{-|
7−Module : Grenade.Layers.Sinusoid
8−Description : Sinusoid nonlinear layer
9−Copyright : (c) Manuel Schneckenreither, 2018
10−License : BSD2
11−Stability : experimental
12−-}
13−module Grenade.Layers.Sinusoid (
14− Sinusoid (..)
15− ) where
16−
17−import Data.Serialize
18−import Data.Singletons
19−
20−import Grenade.Core
21−
22−-- | A Sinusoid layer.
23−-- A layer which can act between any shape of the same dimension, performing a sin function.
24−data Sinusoid = Sinusoid
25− deriving Show
26−
27−instance UpdateLayer Sinusoid where
28− type Gradient Sinusoid = ()
29− runUpdate _ _ _ = Sinusoid
30− createRandom = return Sinusoid
31−
32−instance Serialize Sinusoid where
33− put _ = return ()
34− get = return Sinusoid
35−
36−instance (a ~ b, SingI a) => Layer Sinusoid a b where
37− type Tape Sinusoid a b = S a
38− runForwards _ a = (a, sin a)
39− runBackwards _ a g = ((), cos a * g)
src/Grenade/Layers/Tanh.hs+3−3
@@ -1,8 +1,8 @@
1{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE TypeOperators #-}
3+{-# LANGUAGE TypeFamilies #-}
2{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
5{-# LANGUAGE MultiParamTypeClasses #-}
4−{-# LANGUAGE TypeFamilies #-}
5−{-# LANGUAGE TypeOperators #-}
6{-|
6{-|
7Module : Grenade.Layers.Tanh
7Module : Grenade.Layers.Tanh
8Description : Hyperbolic tangent nonlinear layer
8Description : Hyperbolic tangent nonlinear layer
@@ -20,7 +20,7 @@ import Data.Singletons
20import Grenade.Core
20import Grenade.Core
21
21
22-- | A Tanh layer.
22-- | A Tanh layer.
23−-- A layer which can act between any shape of the same dimension, performing a tanh function.
23+-- A layer which can act between any shape of the same dimension, perfoming a tanh function.
24data Tanh = Tanh
24data Tanh = Tanh
25 deriving Show
25 deriving Show
26
26
src/Grenade/Recurrent/Core/Layer.hs+2−7
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE TypeFamilies #-}
2{-# LANGUAGE TypeFamilies #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
@@ -9,10 +8,6 @@ module Grenade.Recurrent.Core.Layer (
9 , RecurrentUpdateLayer (..)
8 , RecurrentUpdateLayer (..)
10 ) where
9 ) where
11
10
12−#if MIN_VERSION_base(4,9,0)
13−import Data.Kind (Type)
14−#endif
15−
16import Grenade.Core
11import Grenade.Core
17
12
18-- | Class for a recurrent layer.
13-- | Class for a recurrent layer.
@@ -20,11 +15,11 @@ import Grenade.Core
20-- of an extra recurrent data shape.
15-- of an extra recurrent data shape.
21class UpdateLayer x => RecurrentUpdateLayer x where
16class UpdateLayer x => RecurrentUpdateLayer x where
22 -- | Shape of data that is passed between each subsequent run of the layer
17 -- | Shape of data that is passed between each subsequent run of the layer
23− type RecurrentShape x :: Type
18+ type RecurrentShape x :: *
24
19
25class (RecurrentUpdateLayer x, Num (RecurrentShape x)) => RecurrentLayer x (i :: Shape) (o :: Shape) where
20class (RecurrentUpdateLayer x, Num (RecurrentShape x)) => RecurrentLayer x (i :: Shape) (o :: Shape) where
26 -- | Wengert Tape
21 -- | Wengert Tape
27− type RecTape x i o :: Type
22+ type RecTape x i o :: *
28 -- | Used in training and scoring. Take the input from the previous
23 -- | Used in training and scoring. Take the input from the previous
29 -- layer, and give the output from this layer.
24 -- layer, and give the output from this layer.
30 runRecurrentForwards :: x -> RecurrentShape x -> S i -> (RecTape x i o, RecurrentShape x, S o)
25 runRecurrentForwards :: x -> RecurrentShape x -> S i -> (RecTape x i o, RecurrentShape x, S o)
src/Grenade/Recurrent/Core/Network.hs+10−12
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE GADTs #-}
2{-# LANGUAGE GADTs #-}
4{-# LANGUAGE TypeOperators #-}
3{-# LANGUAGE TypeOperators #-}
@@ -29,23 +28,22 @@ module Grenade.Recurrent.Core.Network (
29
28
30
29
31import Control.Monad.Random ( MonadRandom )
30import Control.Monad.Random ( MonadRandom )
31+import Data.Singletons ( SingI )
32+import Data.Singletons.Prelude ( Head, Last )
32import Data.Serialize
33import Data.Serialize
33
34
34−import Data.Kind (Type)
35−
36import Grenade.Core
35import Grenade.Core
37import Grenade.Recurrent.Core.Layer
36import Grenade.Recurrent.Core.Layer
38−import Prelude.Singletons
39
37
40-- | Witness type to say indicate we're building up with a normal feed
38-- | Witness type to say indicate we're building up with a normal feed
41-- forward layer.
39-- forward layer.
42−data FeedForward :: Type -> Type
40+data FeedForward :: * -> *
43-- | Witness type to say indicate we're building up with a recurrent layer.
41-- | Witness type to say indicate we're building up with a recurrent layer.
44−data Recurrent :: Type -> Type
42+data Recurrent :: * -> *
45
43
46-- | Type of a recurrent neural network.
44-- | Type of a recurrent neural network.
47--
45--
48−-- The [Type] type specifies the types of the layers.
46+-- The [*] type specifies the types of the layers.
49--
47--
50-- The [Shape] type specifies the shapes of data passed between the layers.
48-- The [Shape] type specifies the shapes of data passed between the layers.
51--
49--
@@ -54,7 +52,7 @@ data Recurrent :: Type -> Type
54--
52--
55-- Often, to make the definitions more concise, one will use a type alias
53-- Often, to make the definitions more concise, one will use a type alias
56-- for these empty data types.
54-- for these empty data types.
57−data RecurrentNetwork :: [Type] -> [Shape] -> Type where
55+data RecurrentNetwork :: [*] -> [Shape] -> * where
58 RNil :: SingI i
56 RNil :: SingI i
59 => RecurrentNetwork '[] '[i]
57 => RecurrentNetwork '[] '[i]
60
58
@@ -73,7 +71,7 @@ infixr 5 :~@>
73-- | Gradient of a network.
71-- | Gradient of a network.
74--
72--
75-- Parameterised on the layers of the network.
73-- Parameterised on the layers of the network.
76−data RecurrentGradient :: [Type] -> Type where
74+data RecurrentGradient :: [*] -> * where
77 RGNil :: RecurrentGradient '[]
75 RGNil :: RecurrentGradient '[]
78
76
79 (://>) :: UpdateLayer x
77 (://>) :: UpdateLayer x
@@ -83,7 +81,7 @@ data RecurrentGradient :: [Type] -> Type where
83
81
84-- | Recurrent inputs (sideways shapes on an imaginary unrolled graph)
82-- | Recurrent inputs (sideways shapes on an imaginary unrolled graph)
85-- Parameterised on the layers of a Network.
83-- Parameterised on the layers of a Network.
86−data RecurrentInputs :: [Type] -> Type where
84+data RecurrentInputs :: [*] -> * where
87 RINil :: RecurrentInputs '[]
85 RINil :: RecurrentInputs '[]
88
86
89 (:~~+>) :: (UpdateLayer x, Fractional (RecurrentInputs xs))
87 (:~~+>) :: (UpdateLayer x, Fractional (RecurrentInputs xs))
@@ -97,7 +95,7 @@ data RecurrentInputs :: [Type] -> Type where
97--
95--
98-- We index on the time step length as well, to ensure
96-- We index on the time step length as well, to ensure
99-- that that all Tape lengths are the same.
97-- that that all Tape lengths are the same.
100−data RecurrentTape :: [Type] -> [Shape] -> Type where
98+data RecurrentTape :: [*] -> [Shape] -> * where
101 TRNil :: SingI i
99 TRNil :: SingI i
102 => RecurrentTape '[] '[i]
100 => RecurrentTape '[] '[i]
103
101
@@ -206,7 +204,7 @@ instance (Show x, Show (RecurrentNetwork xs rs)) => Show (RecurrentNetwork (Recu
206
204
207-- | A network can easily be created by hand with (:~~>) and (:~@>), but an easy way to initialise a random
205-- | A network can easily be created by hand with (:~~>) and (:~@>), but an easy way to initialise a random
208-- recurrent network and a set of random inputs for it is with the randomRecurrent.
206-- recurrent network and a set of random inputs for it is with the randomRecurrent.
209−class CreatableRecurrent (xs :: [Type]) (ss :: [Shape]) where
207+class CreatableRecurrent (xs :: [*]) (ss :: [Shape]) where
210 -- | Create a network of the types requested
208 -- | Create a network of the types requested
211 randomRecurrent :: MonadRandom m => m (RecurrentNetwork xs ss)
209 randomRecurrent :: MonadRandom m => m (RecurrentNetwork xs ss)
212
210
src/Grenade/Recurrent/Core/Runner.hs+6−5
@@ -6,6 +6,7 @@
6{-# LANGUAGE TypeFamilies #-}
6{-# LANGUAGE TypeFamilies #-}
7{-# LANGUAGE FlexibleContexts #-}
7{-# LANGUAGE FlexibleContexts #-}
8{-# LANGUAGE RankNTypes #-}
8{-# LANGUAGE RankNTypes #-}
9+{-# LANGUAGE RecordWildCards #-}
9
10
10module Grenade.Recurrent.Core.Runner (
11module Grenade.Recurrent.Core.Runner (
11 runRecurrentExamples
12 runRecurrentExamples
@@ -17,10 +18,10 @@ module Grenade.Recurrent.Core.Runner (
17 ) where
18 ) where
18
19
19import Data.List ( foldl' )
20import Data.List ( foldl' )
21+import Data.Singletons.Prelude
20import Grenade.Core
22import Grenade.Core
21
23
22import Grenade.Recurrent.Core.Network
24import Grenade.Recurrent.Core.Network
23−import Prelude.Singletons
24
25
25type RecurrentGradients layers = [RecurrentGradient layers]
26type RecurrentGradients layers = [RecurrentGradient layers]
26
27
@@ -100,11 +101,11 @@ updateRecInputs :: Fractional (RecurrentInputs sublayers)
100 -> RecurrentInputs sublayers
101 -> RecurrentInputs sublayers
101 -> RecurrentInputs sublayers
102 -> RecurrentInputs sublayers
102
103
103−updateRecInputs lp (() :~~+> xs) (() :~~+> ys)
104+updateRecInputs l@LearningParameters {..} (() :~~+> xs) (() :~~+> ys)
104− = () :~~+> updateRecInputs lp xs ys
105+ = () :~~+> updateRecInputs l xs ys
105
106
106−updateRecInputs lp (x :~@+> xs) (y :~@+> ys)
107+updateRecInputs l@LearningParameters {..} (x :~@+> xs) (y :~@+> ys)
107− = (realToFrac (1 - learningRate lp * learningRegulariser lp) * x - realToFrac (learningRate lp) * y) :~@+> updateRecInputs lp xs ys
108+ = (realToFrac (1 - learningRate * learningRegulariser) * x - realToFrac learningRate * y) :~@+> updateRecInputs l xs ys
108
109
109updateRecInputs _ RINil RINil
110updateRecInputs _ RINil RINil
110 = RINil
111 = RINil
src/Grenade/Recurrent/Layers/BasicRecurrent.hs+8−9
@@ -1,6 +1,6 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE GADTs #-}
2{-# LANGUAGE GADTs #-}
3+{-# LANGUAGE RecordWildCards #-}
4{-# LANGUAGE TypeOperators #-}
4{-# LANGUAGE TypeOperators #-}
5{-# LANGUAGE TypeFamilies #-}
5{-# LANGUAGE TypeFamilies #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
@@ -16,8 +16,7 @@ module Grenade.Recurrent.Layers.BasicRecurrent (
16
16
17import Control.Monad.Random ( MonadRandom, getRandom )
17import Control.Monad.Random ( MonadRandom, getRandom )
18
18
19−
20−import Data.Kind (Type)
19+import Data.Singletons.TypeLits
21
20
22import Numeric.LinearAlgebra.Static
21import Numeric.LinearAlgebra.Static
23
22
@@ -28,7 +27,7 @@ import Grenade.Recurrent.Core
28
27
29data BasicRecurrent :: Nat -- Input layer size
28data BasicRecurrent :: Nat -- Input layer size
30 -> Nat -- Output layer size
29 -> Nat -- Output layer size
31− -> Type where
30+ -> * where
32 BasicRecurrent :: ( KnownNat input
31 BasicRecurrent :: ( KnownNat input
33 , KnownNat output
32 , KnownNat output
34 , KnownNat matrixCols
33 , KnownNat matrixCols
@@ -41,7 +40,7 @@ data BasicRecurrent :: Nat -- Input layer size
41
40
42data BasicRecurrent' :: Nat -- Input layer size
41data BasicRecurrent' :: Nat -- Input layer size
43 -> Nat -- Output layer size
42 -> Nat -- Output layer size
44− -> Type where
43+ -> * where
45 BasicRecurrent' :: ( KnownNat input
44 BasicRecurrent' :: ( KnownNat input
46 , KnownNat output
45 , KnownNat output
47 , KnownNat matrixCols
46 , KnownNat matrixCols
@@ -56,11 +55,11 @@ instance Show (BasicRecurrent i o) where
56instance (KnownNat i, KnownNat o, KnownNat (i + o)) => UpdateLayer (BasicRecurrent i o) where
55instance (KnownNat i, KnownNat o, KnownNat (i + o)) => UpdateLayer (BasicRecurrent i o) where
57 type Gradient (BasicRecurrent i o) = (BasicRecurrent' i o)
56 type Gradient (BasicRecurrent i o) = (BasicRecurrent' i o)
58
57
59− runUpdate lp (BasicRecurrent oldBias oldBiasMomentum oldActivations oldMomentum) (BasicRecurrent' biasGradient activationGradient) =
58+ runUpdate LearningParameters {..} (BasicRecurrent oldBias oldBiasMomentum oldActivations oldMomentum) (BasicRecurrent' biasGradient activationGradient) =
60− let newBiasMomentum = konst (learningMomentum lp) * oldBiasMomentum - konst (learningRate lp) * biasGradient
59+ let newBiasMomentum = konst learningMomentum * oldBiasMomentum - konst learningRate * biasGradient
61 newBias = oldBias + newBiasMomentum
60 newBias = oldBias + newBiasMomentum
62− newMomentum = konst (learningMomentum lp) * oldMomentum - konst (learningRate lp) * activationGradient
61+ newMomentum = konst learningMomentum * oldMomentum - konst learningRate * activationGradient
63− regulariser = konst (learningRegulariser lp * learningRate lp) * oldActivations
62+ regulariser = konst (learningRegulariser * learningRate) * oldActivations
64 newActivations = oldActivations + newMomentum - regulariser
63 newActivations = oldActivations + newMomentum - regulariser
65 in BasicRecurrent newBias newBiasMomentum newActivations newMomentum
64 in BasicRecurrent newBias newBiasMomentum newActivations newMomentum
66
65
src/Grenade/Recurrent/Layers/ConcatRecurrent.hs+1−7
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE GADTs #-}
2{-# LANGUAGE GADTs #-}
4{-# LANGUAGE TypeOperators #-}
3{-# LANGUAGE TypeOperators #-}
@@ -9,7 +8,6 @@
9{-# LANGUAGE FlexibleInstances #-}
8{-# LANGUAGE FlexibleInstances #-}
10{-# LANGUAGE ScopedTypeVariables #-}
9{-# LANGUAGE ScopedTypeVariables #-}
11{-# LANGUAGE StandaloneDeriving #-}
10{-# LANGUAGE StandaloneDeriving #-}
12−{-# LANGUAGE UndecidableInstances #-}
13{-|
11{-|
14Module : Grenade.Layers.Concat
12Module : Grenade.Layers.Concat
15Description : Concatenation layer
13Description : Concatenation layer
@@ -28,10 +26,6 @@ import Data.Serialize
28import Data.Singletons
26import Data.Singletons
29import GHC.TypeLits
27import GHC.TypeLits
30
28
31−#if MIN_VERSION_base(4,9,0)
32−import Data.Kind (Type)
33−#endif
34−
35import Grenade.Core
29import Grenade.Core
36import Grenade.Recurrent.Core
30import Grenade.Recurrent.Core
37
31
@@ -50,7 +44,7 @@ import Numeric.LinearAlgebra.Static ( (#), split, R )
50--
44--
51-- 3D images become 3D images with more channels. The sizes must be the same, one can use Pad
45-- 3D images become 3D images with more channels. The sizes must be the same, one can use Pad
52-- and Crop layers to ensure this is the case.
46-- and Crop layers to ensure this is the case.
53−data ConcatRecurrent :: Shape -> Type -> Shape -> Type -> Type where
47+data ConcatRecurrent :: Shape -> * -> Shape -> * -> * where
54 ConcatRecLeft :: x -> y -> ConcatRecurrent m (Recurrent x) n (FeedForward y)
48 ConcatRecLeft :: x -> y -> ConcatRecurrent m (Recurrent x) n (FeedForward y)
55 ConcatRecRight :: x -> y -> ConcatRecurrent m (FeedForward x) n (Recurrent y)
49 ConcatRecRight :: x -> y -> ConcatRecurrent m (FeedForward x) n (Recurrent y)
56 ConcatRecBoth :: x -> y -> ConcatRecurrent m (Recurrent x) n (Recurrent y)
50 ConcatRecBoth :: x -> y -> ConcatRecurrent m (Recurrent x) n (Recurrent y)
src/Grenade/Recurrent/Layers/LSTM.hs+54−45
@@ -1,8 +1,8 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE GADTs #-}
3{-# LANGUAGE GADTs #-}
5{-# LANGUAGE RankNTypes #-}
4{-# LANGUAGE RankNTypes #-}
5+{-# LANGUAGE RecordWildCards #-}
6{-# LANGUAGE TypeOperators #-}
6{-# LANGUAGE TypeOperators #-}
7{-# LANGUAGE TypeFamilies #-}
7{-# LANGUAGE TypeFamilies #-}
8{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE MultiParamTypeClasses #-}
@@ -21,7 +21,7 @@ import Control.Monad.Random ( MonadRandom, getRandom )
21-- import Data.List ( foldl1' )
21-- import Data.List ( foldl1' )
22import Data.Proxy
22import Data.Proxy
23import Data.Serialize
23import Data.Serialize
24−import Data.Kind (Type)
24+import Data.Singletons.TypeLits
25
25
26import qualified Numeric.LinearAlgebra as LA
26import qualified Numeric.LinearAlgebra as LA
27import Numeric.LinearAlgebra.Static
27import Numeric.LinearAlgebra.Static
@@ -29,7 +29,6 @@ import Numeric.LinearAlgebra.Static
29import Grenade.Core
29import Grenade.Core
30import Grenade.Recurrent.Core
30import Grenade.Recurrent.Core
31import Grenade.Layers.Internal.Update
31import Grenade.Layers.Internal.Update
32−import GHC.TypeLits
33
32
34
33
35-- | Long Short Term Memory Recurrent unit
34-- | Long Short Term Memory Recurrent unit
@@ -37,14 +36,14 @@ import GHC.TypeLits
37-- This is a Peephole formulation, so the recurrent shape is
36-- This is a Peephole formulation, so the recurrent shape is
38-- just the cell state, the previous output is not held or used
37-- just the cell state, the previous output is not held or used
39-- at all.
38-- at all.
40−data LSTM :: Nat -> Nat -> Type where
39+data LSTM :: Nat -> Nat -> * where
41 LSTM :: ( KnownNat input
40 LSTM :: ( KnownNat input
42 , KnownNat output
41 , KnownNat output
43 ) => !(LSTMWeights input output) -- Weights
42 ) => !(LSTMWeights input output) -- Weights
44 -> !(LSTMWeights input output) -- Momentums
43 -> !(LSTMWeights input output) -- Momentums
45 -> LSTM input output
44 -> LSTM input output
46
45
47−data LSTMWeights :: Nat -> Nat -> Type where
46+data LSTMWeights :: Nat -> Nat -> * where
48 LSTMWeights :: ( KnownNat input
47 LSTMWeights :: ( KnownNat input
49 , KnownNat output
48 , KnownNat output
50 ) => {
49 ) => {
@@ -71,7 +70,7 @@ instance (KnownNat i, KnownNat o) => UpdateLayer (LSTM i o) where
71
70
72 -- Run the update function for each group matrix/vector of weights, momentums and gradients.
71 -- Run the update function for each group matrix/vector of weights, momentums and gradients.
73 -- Hmm, maybe the function should be used instead of passing in the learning parameters.
72 -- Hmm, maybe the function should be used instead of passing in the learning parameters.
74− runUpdate lp (LSTM w m) g =
73+ runUpdate LearningParameters {..} (LSTM w m) g =
75 let (wf, wf') = u lstmWf w m g
74 let (wf, wf') = u lstmWf w m g
76 (uf, uf') = u lstmUf w m g
75 (uf, uf') = u lstmUf w m g
77 (bf, bf') = v lstmBf w m g
76 (bf, bf') = v lstmBf w m g
@@ -88,11 +87,11 @@ instance (KnownNat i, KnownNat o) => UpdateLayer (LSTM i o) where
88 -- Utility function for updating with the momentum, gradients, and weights.
87 -- Utility function for updating with the momentum, gradients, and weights.
89 u :: forall x ix out. (KnownNat ix, KnownNat out) => (x -> (L out ix)) -> x -> x -> x -> ((L out ix), (L out ix))
88 u :: forall x ix out. (KnownNat ix, KnownNat out) => (x -> (L out ix)) -> x -> x -> x -> ((L out ix), (L out ix))
90 u e (e -> weights) (e -> momentum) (e -> gradient) =
89 u e (e -> weights) (e -> momentum) (e -> gradient) =
91− descendMatrix (learningRate lp) (learningMomentum lp) (learningRegulariser lp) weights gradient momentum
90+ descendMatrix learningRate learningMomentum learningRegulariser weights gradient momentum
92
91
93 v :: forall x ix. (KnownNat ix) => (x -> (R ix)) -> x -> x -> x -> ((R ix), (R ix))
92 v :: forall x ix. (KnownNat ix) => (x -> (R ix)) -> x -> x -> x -> ((R ix), (R ix))
94 v e (e -> weights) (e -> momentum) (e -> gradient) =
93 v e (e -> weights) (e -> momentum) (e -> gradient) =
95− descendVector (learningRate lp) (learningMomentum lp) (learningRegulariser lp) weights gradient momentum
94+ descendVector learningRate learningMomentum learningRegulariser weights gradient momentum
96
95
97 -- There's a lot of updates here, so to try and minimise the number of data copies
96 -- There's a lot of updates here, so to try and minimise the number of data copies
98 -- we'll create a mutable bucket for each.
97 -- we'll create a mutable bucket for each.
@@ -133,18 +132,18 @@ instance (KnownNat i, KnownNat o) => RecurrentLayer (LSTM i o) ('D1 i) ('D1 o) w
133 type RecTape (LSTM i o) ('D1 i) ('D1 o) = (R o, R i, R o, R o, R o, R o, R o, R o, R o, R o, R o)
132 type RecTape (LSTM i o) ('D1 i) ('D1 o) = (R o, R i, R o, R o, R o, R o, R o, R o, R o, R o, R o)
134 -- Forward propagation for the LSTM layer.
133 -- Forward propagation for the LSTM layer.
135 -- The size of the cell state is also the size of the output.
134 -- The size of the cell state is also the size of the output.
136− runRecurrentForwards (LSTM lw _) (S1D cell) (S1D input) =
135+ runRecurrentForwards (LSTM (LSTMWeights {..}) _) (S1D cell) (S1D input) =
137 let -- Forget state vector
136 let -- Forget state vector
138− f_s = lstmBf lw + lstmWf lw #> input + lstmUf lw #> cell
137+ f_s = lstmBf + lstmWf #> input + lstmUf #> cell
139 f_t = sigmoid f_s
138 f_t = sigmoid f_s
140 -- Input state vector
139 -- Input state vector
141− i_s = lstmBi lw + lstmWi lw #> input + lstmUi lw #> cell
140+ i_s = lstmBi + lstmWi #> input + lstmUi #> cell
142 i_t = sigmoid i_s
141 i_t = sigmoid i_s
143 -- Output state vector
142 -- Output state vector
144− o_s = lstmBo lw + lstmWo lw #> input + lstmUo lw #> cell
143+ o_s = lstmBo + lstmWo #> input + lstmUo #> cell
145 o_t = sigmoid o_s
144 o_t = sigmoid o_s
146 -- Cell input state vector
145 -- Cell input state vector
147− c_s = lstmBc lw + lstmWc lw #> input
146+ c_s = lstmBc + lstmWc #> input
148 c_x = tanh c_s
147 c_x = tanh c_s
149 -- Cell state
148 -- Cell state
150 c_t = f_t * cell + i_t * c_x
149 c_t = f_t * cell + i_t * c_x
@@ -158,7 +157,7 @@ instance (KnownNat i, KnownNat o) => RecurrentLayer (LSTM i o) ('D1 i) ('D1 o) w
158 --
157 --
159 -- There's a test version using the AD library without hmatrix in the test
158 -- There's a test version using the AD library without hmatrix in the test
160 -- suite. These should match always.
159 -- suite. These should match always.
161− runRecurrentBackwards (LSTM lw _) (cell, input, f_s, f_t, i_s, i_t, o_s, o_t, c_s, c_x, c_t) (S1D cellGrad) (S1D h_t') =
160+ runRecurrentBackwards (LSTM (LSTMWeights {..}) _) (cell, input, f_s, f_t, i_s, i_t, o_s, o_t, c_s, c_x, c_t) (S1D cellGrad) (S1D h_t') =
162 let -- Reverse Mode AD Derivitives
161 let -- Reverse Mode AD Derivitives
163 c_t' = h_t' * o_t + cellGrad
162 c_t' = h_t' * o_t + cellGrad
164
163
@@ -175,8 +174,8 @@ instance (KnownNat i, KnownNat o) => RecurrentLayer (LSTM i o) ('D1 i) ('D1 o) w
175 c_s' = tanh' c_s * c_x'
174 c_s' = tanh' c_s * c_x'
176
175
177 -- The derivatives to pass sideways (recurrent) and downwards
176 -- The derivatives to pass sideways (recurrent) and downwards
178− cell' = tr (lstmUf lw) #> f_s' + tr (lstmUo lw) #> o_s' + tr (lstmUi lw) #> i_s' + c_t' * f_t
177+ cell' = tr lstmUf #> f_s' + tr lstmUo #> o_s' + tr lstmUi #> i_s' + c_t' * f_t
179− input' = tr (lstmWf lw) #> f_s' + tr (lstmWo lw) #> o_s' + tr (lstmWi lw) #> i_s' + tr (lstmWc lw) #> c_s'
178+ input' = tr lstmWf #> f_s' + tr lstmWo #> o_s' + tr lstmWi #> i_s' + tr lstmWc #> c_s'
180
179
181 -- Calculate the gradient Matricies for the input
180 -- Calculate the gradient Matricies for the input
182 lstmWf' = f_s' `outer` input
181 lstmWf' = f_s' `outer` input
@@ -235,34 +234,44 @@ tanh' :: (Floating a) => a -> a
235tanh' t = 1 - s ^ (2 :: Int) where s = tanh t
234tanh' t = 1 - s ^ (2 :: Int) where s = tanh t
236
235
237instance (KnownNat i, KnownNat o) => Serialize (LSTM i o) where
236instance (KnownNat i, KnownNat o) => Serialize (LSTM i o) where
238− put (LSTM lw _) = do
237+ put (LSTM LSTMWeights {..} _) = do
239− u (lstmWf lw)
238+ u lstmWf
240− u (lstmUf lw)
239+ u lstmUf
241− v (lstmBf lw)
240+ v lstmBf
242− u (lstmWi lw)
241+ u lstmWi
243− u (lstmUi lw)
242+ u lstmUi
244− v (lstmBi lw)
243+ v lstmBi
245− u (lstmWo lw)
244+ u lstmWo
246− u (lstmUo lw)
245+ u lstmUo
247− v (lstmBo lw)
246+ v lstmBo
248− u (lstmWc lw)
247+ u lstmWc
249− v (lstmBc lw)
248+ v lstmBc
250− where
249+ where
251− u :: forall a b. (KnownNat a, KnownNat b) => Putter (L b a)
250+ u :: forall a b. (KnownNat a, KnownNat b) => Putter (L b a)
252− u = putListOf put . LA.toList . LA.flatten . extract
251+ u = putListOf put . LA.toList . LA.flatten . extract
253− v :: forall a. (KnownNat a) => Putter (R a)
252+ v :: forall a. (KnownNat a) => Putter (R a)
254− v = putListOf put . LA.toList . extract
253+ v = putListOf put . LA.toList . extract
255
254
256 get = do
255 get = do
257− w <- LSTMWeights <$> u <*> u <*> v <*> u <*> u <*> v <*> u <*> u <*> v <*> u <*> v
256+ lstmWf <- u
257+ lstmUf <- u
258+ lstmBf <- v
259+ lstmWi <- u
260+ lstmUi <- u
261+ lstmBi <- v
262+ lstmWo <- u
263+ lstmUo <- u
264+ lstmBo <- v
265+ lstmWc <- u
266+ lstmBc <- v
258− return $ LSTM w (LSTMWeights w0 u0 v0 w0 u0 v0 w0 u0 v0 w0 v0)
267+ return $ LSTM (LSTMWeights {..}) (LSTMWeights w0 u0 v0 w0 u0 v0 w0 u0 v0 w0 v0)
259− where
268+ where
260− u :: forall a b. (KnownNat a, KnownNat b) => Get (L b a)
269+ u :: forall a b. (KnownNat a, KnownNat b) => Get (L b a)
261− u = let f = fromIntegral $ natVal (Proxy :: Proxy a)
270+ u = let f = fromIntegral $ natVal (Proxy :: Proxy a)
262− in maybe (fail "Vector of incorrect size") return . create . LA.reshape f . LA.fromList =<< getListOf get
271+ in maybe (fail "Vector of incorrect size") return . create . LA.reshape f . LA.fromList =<< getListOf get
263− v :: forall a. (KnownNat a) => Get (R a)
272+ v :: forall a. (KnownNat a) => Get (R a)
264− v = maybe (fail "Vector of incorrect size") return . create . LA.fromList =<< getListOf get
273+ v = maybe (fail "Vector of incorrect size") return . create . LA.fromList =<< getListOf get
265−
274+
266− w0 = konst 0
275+ w0 = konst 0
267− u0 = konst 0
276+ u0 = konst 0
268− v0 = konst 0
277+ v0 = konst 0
src/Grenade/Utils/OneHot.hs+1−1
@@ -22,6 +22,7 @@ import Data.Map ( Map )
22import qualified Data.Map as M
22import qualified Data.Map as M
23
23
24import Data.Proxy
24import Data.Proxy
25+import Data.Singletons.TypeLits
25
26
26import Data.Vector ( Vector )
27import Data.Vector ( Vector )
27import qualified Data.Vector as V
28import qualified Data.Vector as V
@@ -30,7 +31,6 @@ import qualified Data.Vector.Storable as VS
30import Numeric.LinearAlgebra ( maxIndex )
31import Numeric.LinearAlgebra ( maxIndex )
31import Numeric.LinearAlgebra.Devel
32import Numeric.LinearAlgebra.Devel
32import Numeric.LinearAlgebra.Static
33import Numeric.LinearAlgebra.Static
33−import GHC.TypeLits
34
34
35import Grenade.Core.Shape
35import Grenade.Core.Shape
36
36
stack.yamldeleted−78
@@ -1,78 +0,0 @@
1−# This file was automatically generated by 'stack init'
2−#
3−# Some commonly used options have been documented as comments in this file.
4−# For advanced use and comprehensive documentation of the format, please see:
5−# https://docs.haskellstack.org/en/stable/yaml_configuration/
6−
7−# A warning or info to be displayed to the user on config load.
8−# user-message: |
9−
10−# Resolver to choose a 'specific' stackage snapshot or a compiler version.
11−# A snapshot resolver dictates the compiler version and the set of packages
12−# to be used for project dependencies. For example:
13−#
14−# resolver: lts-3.5
15−# resolver: nightly-2015-09-21
16−# resolver: ghc-7.10.2
17−#
18−# The location of a snapshot can be provided as a file or url. Stack assumes
19−# a snapshot provided as a file might change, whereas a url resource does not.
20−#
21−# resolver: ./custom-snapshot.yaml
22−# resolver: https://example.com/snapshots/2018-01-01.yaml
23−resolver: lts-20.18
24−
25−# User packages to be built.
26−# Various formats can be used as shown in the example below.
27−#
28−# packages:
29−# - some-directory
30−# - https://example.com/foo/bar/baz-0.0.2.tar.gz
31−# subdirs:
32−# - auto-update
33−# - wai
34−packages:
35− - .
36− - examples
37−
38−# Dependency packages to be pulled from upstream that are not in the resolver.
39−# These entries can reference officially published versions as well as
40−# forks / in-progress versions pinned to a git hash. For example:
41−#
42−# extra-deps:
43−# - acme-missiles-0.3
44−# - git: https://github.com/commercialhaskell/stack.git
45−# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
46−#
47−extra-deps:
48− - typelits-witnesses-0.3.0.3
49−
50−# Override default flag values for local packages and extra-deps
51−# flags: {}
52−
53−# Extra package databases containing global packages
54−# extra-package-dbs: []
55−
56−# Control whether we use the GHC we find on the path
57−# system-ghc: true
58−#
59−# Require a specific version of stack, using version ranges
60−# require-stack-version: -any # Default
61−# require-stack-version: ">=2.1"
62−#
63−# Override the architecture used by stack, especially useful on Windows
64−# arch: i386
65−# arch: x86_64
66−#
67−# Extra directories used by stack for building
68−# extra-include-dirs: [/path/to/dir]
69−# extra-lib-dirs: [/path/to/dir]
70−#
71−# Allow a newer minor version of GHC than the snapshot specifies
72−# compiler-check: newer-minor
73−
74−nix:
75− enable: true
76− packages:
77− - blas
78− - lapack
stack.yaml.lockdeleted−19
@@ -1,19 +0,0 @@
1−# This file was autogenerated by Stack.
2−# You should not edit this file by hand.
3−# For more information, please see the documentation at:
4−# https://docs.haskellstack.org/en/stable/lock_files
5−
6−packages:
7−- completed:
8− hackage: typelits-witnesses-0.3.0.3@sha256:2d9df4ac6ff3077bfd2bf659e4b495e157723ac5b45c519762853f55df5c16db,2738
9− pantry-tree:
10− sha256: 6a42a462f98e94933b6e9721acd912c6c6b6a4743635efd15cc5871908c816a0
11− size: 469
12− original:
13− hackage: typelits-witnesses-0.3.0.3
14−snapshots:
15−- completed:
16− sha256: 9fa4bece7acfac1fc7930c5d6e24606004b09e80aa0e52e9f68b148201008db9
17− size: 649606
18− url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/18.yaml
19− original: lts-20.18
test/Test/Grenade/Layers/Convolution.hs+1−6
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE TemplateHaskell #-}
1{-# LANGUAGE TemplateHaskell #-}
3{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE GADTs #-}
3{-# LANGUAGE GADTs #-}
@@ -16,10 +15,6 @@ import Data.Singletons ()
16import GHC.TypeLits
15import GHC.TypeLits
17import GHC.TypeLits.Witnesses
16import GHC.TypeLits.Witnesses
18
17
19−#if MIN_VERSION_base(4,9,0)
20−import Data.Kind (Type)
21−#endif
22−
23import Grenade.Core
18import Grenade.Core
24import Grenade.Layers.Convolution
19import Grenade.Layers.Convolution
25
20
@@ -30,7 +25,7 @@ import Test.Hedgehog.Hmatrix
30import Test.Hedgehog.TypeLits
25import Test.Hedgehog.TypeLits
31import Test.Hedgehog.Compat
26import Test.Hedgehog.Compat
32
27
33−data OpaqueConvolution :: Type where
28+data OpaqueConvolution :: * where
34 OpaqueConvolution :: Convolution channels filters kernelRows kernelColumns strideRows strideColumns -> OpaqueConvolution
29 OpaqueConvolution :: Convolution channels filters kernelRows kernelColumns strideRows strideColumns -> OpaqueConvolution
35
30
36instance Show OpaqueConvolution where
31instance Show OpaqueConvolution where
test/Test/Grenade/Layers/FullyConnected.hs+1−6
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE TemplateHaskell #-}
2{-# LANGUAGE TemplateHaskell #-}
4{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE DataKinds #-}
@@ -13,10 +12,6 @@ import Data.Singletons ()
13
12
14import GHC.TypeLits
13import GHC.TypeLits
15
14
16−#if MIN_VERSION_base(4,9,0)
17−import Data.Kind (Type)
18−#endif
19−
20import Grenade.Core
15import Grenade.Core
21import Grenade.Layers.FullyConnected
16import Grenade.Layers.FullyConnected
22
17
@@ -25,7 +20,7 @@ import Hedgehog
25import Test.Hedgehog.Compat
20import Test.Hedgehog.Compat
26import Test.Hedgehog.Hmatrix
21import Test.Hedgehog.Hmatrix
27
22
28−data OpaqueFullyConnected :: Type where
23+data OpaqueFullyConnected :: * where
29 OpaqueFullyConnected :: (KnownNat i, KnownNat o) => FullyConnected i o -> OpaqueFullyConnected
24 OpaqueFullyConnected :: (KnownNat i, KnownNat o) => FullyConnected i o -> OpaqueFullyConnected
30
25
31instance Show OpaqueFullyConnected where
26instance Show OpaqueFullyConnected where
test/Test/Grenade/Layers/PadCrop.hs+4
@@ -7,6 +7,10 @@
7{-# LANGUAGE ScopedTypeVariables #-}
7{-# LANGUAGE ScopedTypeVariables #-}
8{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
8{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
9
9
10+#if __GLASGOW_HASKELL__ < 800
11+{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
12+#endif
13+
10module Test.Grenade.Layers.PadCrop where
14module Test.Grenade.Layers.PadCrop where
11
15
12import Grenade
16import Grenade
test/Test/Grenade/Layers/Pooling.hs+5−10
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE TemplateHaskell #-}
1{-# LANGUAGE TemplateHaskell #-}
3{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE KindSignatures #-}
3{-# LANGUAGE KindSignatures #-}
@@ -10,10 +9,6 @@ module Test.Grenade.Layers.Pooling where
10import Data.Proxy
9import Data.Proxy
11import Data.Singletons ()
10import Data.Singletons ()
12
11
13−#if MIN_VERSION_base(4,9,0)
14−import Data.Kind (Type)
15−#endif
16−
17import GHC.TypeLits
12import GHC.TypeLits
18import Grenade.Layers.Pooling
13import Grenade.Layers.Pooling
19
14
@@ -21,7 +16,7 @@ import Hedgehog
21
16
22import Test.Hedgehog.Compat
17import Test.Hedgehog.Compat
23
18
24−data OpaquePooling :: Type where
19+data OpaquePooling :: * where
25 OpaquePooling :: (KnownNat kh, KnownNat kw, KnownNat sh, KnownNat sw) => Pooling kh kw sh sw -> OpaquePooling
20 OpaquePooling :: (KnownNat kh, KnownNat kw, KnownNat sh, KnownNat sw) => Pooling kh kw sh sw -> OpaquePooling
26
21
27instance Show OpaquePooling where
22instance Show OpaquePooling where
@@ -29,10 +24,10 @@ instance Show OpaquePooling where
29
24
30genOpaquePooling :: Gen OpaquePooling
25genOpaquePooling :: Gen OpaquePooling
31genOpaquePooling = do
26genOpaquePooling = do
32− ~(Just kernelHeight) <- someNatVal <$> choose 2 15
27+ Just kernelHeight <- someNatVal <$> choose 2 15
33− ~(Just kernelWidth ) <- someNatVal <$> choose 2 15
28+ Just kernelWidth <- someNatVal <$> choose 2 15
34− ~(Just strideHeight) <- someNatVal <$> choose 2 15
29+ Just strideHeight <- someNatVal <$> choose 2 15
35− ~(Just strideWidth ) <- someNatVal <$> choose 2 15
30+ Just strideWidth <- someNatVal <$> choose 2 15
36
31
37 case (kernelHeight, kernelWidth, strideHeight, strideWidth) of
32 case (kernelHeight, kernelWidth, strideHeight, strideWidth) of
38 (SomeNat (_ :: Proxy kh), SomeNat (_ :: Proxy kw), SomeNat (_ :: Proxy sh), SomeNat (_ :: Proxy sw)) ->
33 (SomeNat (_ :: Proxy kh), SomeNat (_ :: Proxy kw), SomeNat (_ :: Proxy sh), SomeNat (_ :: Proxy sw)) ->
test/Test/Grenade/Network.hs+33−37
@@ -14,12 +14,17 @@ import Control.Monad ( guard )
14import Control.Monad.ST ( runST )
14import Control.Monad.ST ( runST )
15
15
16import Data.Constraint
16import Data.Constraint
17+#if __GLASGOW_HASKELL__ < 800
18+import Data.Proxy
19+#endif
17import qualified Data.Vector.Storable as VS
20import qualified Data.Vector.Storable as VS
18import qualified Data.Vector.Storable.Mutable as VS ( write )
21import qualified Data.Vector.Storable.Mutable as VS ( write )
19import Data.Singletons
22import Data.Singletons
20import Data.Singletons.Prelude.List
23import Data.Singletons.Prelude.List
21import Data.Singletons.TypeLits
24import Data.Singletons.TypeLits
22
25
26+-- import Data.Type.Equality
27+
23import Hedgehog
28import Hedgehog
24import qualified Hedgehog.Gen as Gen
29import qualified Hedgehog.Gen as Gen
25import Hedgehog.Internal.Source
30import Hedgehog.Internal.Source
@@ -27,15 +32,7 @@ import Hedgehog.Internal.Property ( failWith )
27
32
28import Grenade
33import Grenade
29
34
30−#if MIN_VERSION_base(4,11,0)
31−import GHC.TypeLits hiding (natVal)
32−#else
33import GHC.TypeLits
35import GHC.TypeLits
34−#endif
35−#if MIN_VERSION_base(4,9,0)
36−import Data.Kind (Type)
37−#endif
38−
39import GHC.TypeLits.Witnesses
36import GHC.TypeLits.Witnesses
40import Test.Hedgehog.Compat
37import Test.Hedgehog.Compat
41import Test.Hedgehog.TypeLits
38import Test.Hedgehog.TypeLits
@@ -46,7 +43,7 @@ import Numeric.LinearAlgebra ( flatten )
46import Numeric.LinearAlgebra.Static ( extract, norm_Inf )
43import Numeric.LinearAlgebra.Static ( extract, norm_Inf )
47import Unsafe.Coerce
44import Unsafe.Coerce
48
45
49−data SomeNetwork :: Type where
46+data SomeNetwork :: * where
50 SomeNetwork :: ( SingI shapes, SingI (Head shapes), SingI (Last shapes), Show (Network layers shapes) ) => Network layers shapes -> SomeNetwork
47 SomeNetwork :: ( SingI shapes, SingI (Head shapes), SingI (Last shapes), Show (Network layers shapes) ) => Network layers shapes -> SomeNetwork
51
48
52instance Show SomeNetwork where
49instance Show SomeNetwork where
@@ -77,9 +74,8 @@ genNetwork =
77 , pure (SomeNetwork (Elu :~> rest :: Network ( Elu ': layers ) ( h ': h ': hs )))
74 , pure (SomeNetwork (Elu :~> rest :: Network ( Elu ': layers ) ( h ': h ': hs )))
78 , pure (SomeNetwork (Softmax :~> rest :: Network ( Softmax ': layers ) ( h ': h ': hs )))
75 , pure (SomeNetwork (Softmax :~> rest :: Network ( Softmax ': layers ) ( h ': h ': hs )))
79 , do -- Reshape to two dimensions
76 , do -- Reshape to two dimensions
80− let divisors :: Integer -> [Integer]
81− divisors n = 1 : [x | x <- [2..(n-1)], n `rem` x == 0]
77+ let divisors n = 1 : [x | x <- [2..(n-1)], n `rem` x == 0]
82− let len = fromIntegral $ natVal l
78+ let len = natVal l
83 rs <- Gen.element $ divisors len
79 rs <- Gen.element $ divisors len
84 let cs = len `quot` rs
80 let cs = len `quot` rs
85 case ( someNatVal rs, someNatVal cs, someNatVal len ) of
81 case ( someNatVal rs, someNatVal cs, someNatVal len ) of
@@ -100,8 +96,8 @@ genNetwork =
100 , do -- Build a convolution layer with one filter output
96 , do -- Build a convolution layer with one filter output
101 -- Figure out some kernel sizes which work for this layer
97 -- Figure out some kernel sizes which work for this layer
102 -- There must be a better way than this...
98 -- There must be a better way than this...
103− let output_r = fromIntegral $ natVal r
99+ let output_r = natVal r
104− let output_c = fromIntegral $ natVal c
100+ let output_c = natVal c
105
101
106 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
102 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
107
103
@@ -140,8 +136,8 @@ genNetwork =
140 , do -- Build a convolution layer with one filter output
136 , do -- Build a convolution layer with one filter output
141 -- Figure out some kernel sizes which work for this layer
137 -- Figure out some kernel sizes which work for this layer
142 -- There must be a better way than this...
138 -- There must be a better way than this...
143− let output_r = fromIntegral $ natVal r
139+ let output_r = natVal r
144− let output_c = fromIntegral $ natVal c
140+ let output_c = natVal c
145
141
146 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
142 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
147
143
@@ -182,8 +178,8 @@ genNetwork =
182 pure (SomeNetwork (conv :~> rest :: Network ( Convolution channels 1 kernelRows kernelCols strideRows strideCols ': layers ) ( ('D3 inRows inCols channels) ': h ': hs )))
178 pure (SomeNetwork (conv :~> rest :: Network ( Convolution channels 1 kernelRows kernelCols strideRows strideCols ': layers ) ( ('D3 inRows inCols channels) ': h ': hs )))
183 _ -> Gen.discard -- Can't occur
179 _ -> Gen.discard -- Can't occur
184 , do -- Build a Pooling layer
180 , do -- Build a Pooling layer
185− let output_r = fromIntegral $ natVal r
181+ let output_r = natVal r
186− let output_c = fromIntegral $ natVal c
182+ let output_c = natVal c
187
183
188 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
184 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
189
185
@@ -219,8 +215,8 @@ genNetwork =
219 pure (SomeNetwork (Pooling :~> rest :: Network ( Pooling kernelRows kernelCols strideRows strideCols ': layers ) ( ('D2 inRows inCols) ': h ': hs )))
215 pure (SomeNetwork (Pooling :~> rest :: Network ( Pooling kernelRows kernelCols strideRows strideCols ': layers ) ( ('D2 inRows inCols) ': h ': hs )))
220 _ -> Gen.discard -- Can't occur
216 _ -> Gen.discard -- Can't occur
221 , do -- Build a Pad layer
217 , do -- Build a Pad layer
222− let output_r = fromIntegral $ natVal r
218+ let output_r = natVal r
223− let output_c = fromIntegral $ natVal c
219+ let output_c = natVal c
224
220
225 pad_left <- choose 0 (output_r - 1)
221 pad_left <- choose 0 (output_r - 1)
226 pad_right <- choose 0 (output_r - 1 - pad_left)
222 pad_right <- choose 0 (output_r - 1 - pad_left)
@@ -246,8 +242,8 @@ genNetwork =
246 pure (SomeNetwork (Pad :~> rest :: Network ( Pad padLeft padTop padRight padBottom ': layers ) ( ('D2 inputRows inputColumns) ': h ': hs )))
242 pure (SomeNetwork (Pad :~> rest :: Network ( Pad padLeft padTop padRight padBottom ': layers ) ( ('D2 inputRows inputColumns) ': h ': hs )))
247 _ -> Gen.discard -- Can't occur
243 _ -> Gen.discard -- Can't occur
248 , do -- Build a Crop layer
244 , do -- Build a Crop layer
249− let output_r = fromIntegral $ natVal r
245+ let output_r = natVal r
250− let output_c = fromIntegral $ natVal c
246+ let output_c = natVal c
251
247
252 crop_left <- choose 0 10
248 crop_left <- choose 0 10
253 crop_right <- choose 0 10
249 crop_right <- choose 0 10
@@ -279,9 +275,9 @@ genNetwork =
279 , do -- Build a convolution layer with one filter output
275 , do -- Build a convolution layer with one filter output
280 -- Figure out some kernel sizes which work for this layer
276 -- Figure out some kernel sizes which work for this layer
281 -- There must be a better way than this...
277 -- There must be a better way than this...
282− let output_r = fromIntegral $ natVal r
278+ let output_r = natVal r
283− let output_c = fromIntegral $ natVal c
279+ let output_c = natVal c
284− let output_f = fromIntegral $ natVal f
280+ let output_f = natVal f
285
281
286 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
282 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
287
283
@@ -322,9 +318,9 @@ genNetwork =
322 pure (SomeNetwork (conv :~> rest :: Network ( Convolution channels filters kernelRows kernelCols strideRows strideCols ': layers ) ( ('D3 inRows inCols channels) ': h ': hs )))
318 pure (SomeNetwork (conv :~> rest :: Network ( Convolution channels filters kernelRows kernelCols strideRows strideCols ': layers ) ( ('D3 inRows inCols channels) ': h ': hs )))
323 _ -> Gen.discard -- Can't occur
319 _ -> Gen.discard -- Can't occur
324 , do -- Build a Pooling layer
320 , do -- Build a Pooling layer
325− let output_r = fromIntegral $ natVal r
321+ let output_r = natVal r
326− let output_c = fromIntegral $ natVal c
322+ let output_c = natVal c
327− let output_f = fromIntegral $ natVal f
323+ let output_f = natVal f
328
324
329 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
325 let ok extent kernel = [stride | stride <- [ 1 .. extent ], (extent - kernel) `mod` stride == 0]
330
326
@@ -363,9 +359,9 @@ genNetwork =
363 pure (SomeNetwork (Pooling :~> rest :: Network ( Pooling kernelRows kernelCols strideRows strideCols ': layers ) ( ('D3 inRows inCols filters) ': h ': hs )))
359 pure (SomeNetwork (Pooling :~> rest :: Network ( Pooling kernelRows kernelCols strideRows strideCols ': layers ) ( ('D3 inRows inCols filters) ': h ': hs )))
364 _ -> Gen.discard -- Can't occur
360 _ -> Gen.discard -- Can't occur
365 , do -- Build a Pad layer
361 , do -- Build a Pad layer
366− let output_r = fromIntegral $ natVal r
362+ let output_r = natVal r
367− let output_c = fromIntegral $ natVal c
363+ let output_c = natVal c
368− let output_f = fromIntegral $ natVal f
364+ let output_f = natVal f
369
365
370 pad_left <- choose 0 (output_r - 1)
366 pad_left <- choose 0 (output_r - 1)
371 pad_right <- choose 0 (output_r - 1 - pad_left)
367 pad_right <- choose 0 (output_r - 1 - pad_left)
@@ -393,9 +389,9 @@ genNetwork =
393 pure (SomeNetwork (Pad :~> rest :: Network ( Pad padLeft padTop padRight padBottom ': layers ) ( ('D3 inputRows inputColumns filters) ': h ': hs )))
389 pure (SomeNetwork (Pad :~> rest :: Network ( Pad padLeft padTop padRight padBottom ': layers ) ( ('D3 inputRows inputColumns filters) ': h ': hs )))
394 _ -> Gen.discard -- Can't occur
390 _ -> Gen.discard -- Can't occur
395 , do -- Build a Crop layer
391 , do -- Build a Crop layer
396− let output_r = fromIntegral $ natVal r
392+ let output_r = natVal r
397− let output_c = fromIntegral $ natVal c
393+ let output_c = natVal c
398− let output_f = fromIntegral $ natVal f
394+ let output_f = natVal f
399
395
400 crop_left <- choose 0 10
396 crop_left <- choose 0 10
401 crop_right <- choose 0 10
397 crop_right <- choose 0 10
@@ -448,7 +444,7 @@ oneUp =
448 D1Sing SNat ->
444 D1Sing SNat ->
449 let x = 0 :: S ( shape )
445 let x = 0 :: S ( shape )
450 in case x of
446 in case x of
451− ( S1D x' ) -> do
447+ ( S1D x' ) -> do
452 let ex = extract x'
448 let ex = extract x'
453 let len = VS.length ex
449 let len = VS.length ex
454 ix <- choose 0 (len - 1)
450 ix <- choose 0 (len - 1)
@@ -460,7 +456,7 @@ oneUp =
460 D2Sing SNat SNat ->
456 D2Sing SNat SNat ->
461 let x = 0 :: S ( shape )
457 let x = 0 :: S ( shape )
462 in case x of
458 in case x of
463− ( S2D x' ) -> do
459+ ( S2D x' ) -> do
464 let ex = flatten ( extract x' )
460 let ex = flatten ( extract x' )
465 let len = VS.length ex
461 let len = VS.length ex
466 ix <- choose 0 (len - 1)
462 ix <- choose 0 (len - 1)
@@ -472,7 +468,7 @@ oneUp =
472 D3Sing SNat SNat SNat ->
468 D3Sing SNat SNat SNat ->
473 let x = 0 :: S ( shape )
469 let x = 0 :: S ( shape )
474 in case x of
470 in case x of
475− ( S3D x' ) -> do
471+ ( S3D x' ) -> do
476 let ex = flatten ( extract x' )
472 let ex = flatten ( extract x' )
477 let len = VS.length ex
473 let len = VS.length ex
478 ix <- choose 0 (len - 1)
474 ix <- choose 0 (len - 1)
test/Test/Grenade/Recurrent/Layers/LSTM.hs+2−2
@@ -121,9 +121,9 @@ prop_lstm_reference_backwards_cell =
121 , showPretty x
121 , showPretty x
122 , showPretty y
122 , showPretty y
123 ]
123 ]
124− Just differ ->
124+ Just diff ->
125 withFrozenCallStack $
125 withFrozenCallStack $
126− failWith (Just $ Diff "Failed (" "- lhs" "~/~" "+ rhs" ")" differ) ""
126+ failWith (Just $ Diff "Failed (" "- lhs" "~/~" "+ rhs" ")" diff) ""
127infix 4 ~~~
127infix 4 ~~~
128
128
129tests :: IO Bool
129tests :: IO Bool
test/Test/Grenade/Recurrent/Layers/LSTM/Reference.hs+21−25
@@ -6,6 +6,7 @@
6{-# LANGUAGE DeriveFunctor #-}
6{-# LANGUAGE DeriveFunctor #-}
7{-# LANGUAGE DeriveFoldable #-}
7{-# LANGUAGE DeriveFoldable #-}
8{-# LANGUAGE DeriveTraversable #-}
8{-# LANGUAGE DeriveTraversable #-}
9+{-# LANGUAGE RecordWildCards #-}
9{-# LANGUAGE FlexibleContexts #-}
10{-# LANGUAGE FlexibleContexts #-}
10{-# LANGUAGE RankNTypes #-}
11{-# LANGUAGE RankNTypes #-}
11
12
@@ -14,13 +15,9 @@ module Test.Grenade.Recurrent.Layers.LSTM.Reference where
14
15
15import Data.Reflection
16import Data.Reflection
16import Numeric.AD.Mode.Reverse
17import Numeric.AD.Mode.Reverse
17−import Numeric.AD.Internal.Reverse (Tape)
18+import Numeric.AD.Internal.Reverse ( Tape )
18
19
19−import GHC.TypeLits (KnownNat)
20−
21−import Grenade.Recurrent.Layers.LSTM (LSTMWeights (..))
22import qualified Grenade.Recurrent.Layers.LSTM as LSTM
20import qualified Grenade.Recurrent.Layers.LSTM as LSTM
23−
24import qualified Numeric.LinearAlgebra.Static as S
21import qualified Numeric.LinearAlgebra.Static as S
25import qualified Numeric.LinearAlgebra as H
22import qualified Numeric.LinearAlgebra as H
26
23
@@ -57,32 +54,31 @@ data RefLSTM a = RefLSTM
57 , refLstmBc :: Vector a -- Bias Cell (b_c)
54 , refLstmBc :: Vector a -- Bias Cell (b_c)
58 } deriving (Functor, Foldable, Traversable, Eq, Show)
55 } deriving (Functor, Foldable, Traversable, Eq, Show)
59
56
60−lstmToReference :: (KnownNat a, KnownNat b) => LSTM.LSTMWeights a b -> RefLSTM Double
57+lstmToReference :: LSTM.LSTMWeights a b -> RefLSTM Double
61−lstmToReference lw =
58+lstmToReference LSTM.LSTMWeights {..} =
62− RefLSTM
63− { refLstmWf = Matrix . H.toLists . S.extract $ lstmWf lw -- Weight Forget (W_f)
59+ let refLstmWf = Matrix . H.toLists . S.extract $ lstmWf -- Weight Forget (W_f)
64− , refLstmUf = Matrix . H.toLists . S.extract $ lstmUf lw -- Cell State Forget (U_f)
60+ refLstmUf = Matrix . H.toLists . S.extract $ lstmUf -- Cell State Forget (U_f)
65− , refLstmBf = Vector . H.toList . S.extract $ lstmBf lw -- Bias Forget (b_f)
61+ refLstmBf = Vector . H.toList . S.extract $ lstmBf -- Bias Forget (b_f)
66− , refLstmWi = Matrix . H.toLists . S.extract $ lstmWi lw -- Weight Input (W_i)
62+ refLstmWi = Matrix . H.toLists . S.extract $ lstmWi -- Weight Input (W_i)
67− , refLstmUi = Matrix . H.toLists . S.extract $ lstmUi lw -- Cell State Input (U_i)
63+ refLstmUi = Matrix . H.toLists . S.extract $ lstmUi -- Cell State Input (U_i)
68− , refLstmBi = Vector . H.toList . S.extract $ lstmBi lw -- Bias Input (b_i)
64+ refLstmBi = Vector . H.toList . S.extract $ lstmBi -- Bias Input (b_i)
69− , refLstmWo = Matrix . H.toLists . S.extract $ lstmWo lw -- Weight Output (W_o)
65+ refLstmWo = Matrix . H.toLists . S.extract $ lstmWo -- Weight Output (W_o)
70− , refLstmUo = Matrix . H.toLists . S.extract $ lstmUo lw -- Cell State Output (U_o)
66+ refLstmUo = Matrix . H.toLists . S.extract $ lstmUo -- Cell State Output (U_o)
71− , refLstmBo = Vector . H.toList . S.extract $ lstmBo lw -- Bias Output (b_o)
67+ refLstmBo = Vector . H.toList . S.extract $ lstmBo -- Bias Output (b_o)
72− , refLstmWc = Matrix . H.toLists . S.extract $ lstmWc lw -- Weight Cell (W_c)
68+ refLstmWc = Matrix . H.toLists . S.extract $ lstmWc -- Weight Cell (W_c)
73− , refLstmBc = Vector . H.toList . S.extract $ lstmBc lw -- Bias Cell (b_c)
69+ refLstmBc = Vector . H.toList . S.extract $ lstmBc -- Bias Cell (b_c)
74− }
70+ in RefLSTM {..}
75
71
76runLSTM :: Floating a => RefLSTM a -> Vector a -> Vector a -> (Vector a, Vector a)
72runLSTM :: Floating a => RefLSTM a -> Vector a -> Vector a -> (Vector a, Vector a)
77−runLSTM rl cell input =
73+runLSTM RefLSTM {..} cell input =
78 let -- Forget state vector
74 let -- Forget state vector
79− f_t = sigmoid $ refLstmBf rl #+ refLstmWf rl #> input #+ refLstmUf rl #> cell
75+ f_t = sigmoid $ refLstmBf #+ refLstmWf #> input #+ refLstmUf #> cell
80 -- Input state vector
76 -- Input state vector
81− i_t = sigmoid $ refLstmBi rl #+ refLstmWi rl #> input #+ refLstmUi rl #> cell
77+ i_t = sigmoid $ refLstmBi #+ refLstmWi #> input #+ refLstmUi #> cell
82 -- Output state vector
78 -- Output state vector
83− o_t = sigmoid $ refLstmBo rl #+ refLstmWo rl #> input #+ refLstmUo rl #> cell
79+ o_t = sigmoid $ refLstmBo #+ refLstmWo #> input #+ refLstmUo #> cell
84 -- Cell input state vector
80 -- Cell input state vector
85− c_x = fmap tanh $ refLstmBc rl #+ refLstmWc rl #> input
81+ c_x = fmap tanh $ refLstmBc #+ refLstmWc #> input
86 -- Cell state
82 -- Cell state
87 c_t = f_t #* cell #+ i_t #* c_x
83 c_t = f_t #* cell #+ i_t #* c_x
88 -- Output (it's sometimes recommended to use tanh c_t)
84 -- Output (it's sometimes recommended to use tanh c_t)
test/Test/Hedgehog/Hmatrix.hs+2−3
@@ -1,8 +1,7 @@
1−{-# LANGUAGE DataKinds #-}
2−{-# LANGUAGE KindSignatures #-}
3−{-# LANGUAGE GADTs #-}
4{-# LANGUAGE RankNTypes #-}
1{-# LANGUAGE RankNTypes #-}
2+{-# LANGUAGE DataKinds #-}
5{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE ScopedTypeVariables #-}
4+{-# LANGUAGE GADTs #-}
6
5
7module Test.Hedgehog.Hmatrix where
6module Test.Hedgehog.Hmatrix where
8
7
test/Test/Hedgehog/TypeLits.hs+19−13
@@ -7,27 +7,33 @@
7{-# LANGUAGE GADTs #-}
7{-# LANGUAGE GADTs #-}
8module Test.Hedgehog.TypeLits where
8module Test.Hedgehog.TypeLits where
9
9
10−import Data.Constraint (Dict (..))
10+import Data.Constraint
11−import Data.Singletons (Proxy (..), Sing (..), SomeSing (..), sing)
11+#if __GLASGOW_HASKELL__ < 800
12−#if MIN_VERSION_singletons(2,6,0)
13−import Data.Singletons.TypeLits (SNat (..))
12+import Data.Proxy
14#endif
13#endif
14+import Data.Singletons
15
15
16import Hedgehog (Gen)
16import Hedgehog (Gen)
17import qualified Hedgehog.Gen as Gen
17import qualified Hedgehog.Gen as Gen
18
18
19import Grenade
19import Grenade
20
20
21−import GHC.TypeLits (SomeNat (..), natVal, someNatVal)
21+import GHC.TypeLits
22−import GHC.TypeLits.Witnesses ((%*), natDict)
22+import GHC.TypeLits.Witnesses
23−import Test.Hedgehog.Compat (choose)
23+import Test.Hedgehog.Compat
24
24
25genNat :: Gen SomeNat
25genNat :: Gen SomeNat
26genNat = do
26genNat = do
27− ~(Just n) <- someNatVal <$> choose 1 10
27+ Just n <- someNatVal <$> choose 1 10
28 return n
28 return n
29
29
30+#if __GLASGOW_HASKELL__ < 800
31+type Shape' = ('KProxy :: KProxy Shape)
32+#else
33+type Shape' = Shape
34+#endif
35+
30−genShape :: Gen (SomeSing Shape)
36+genShape :: Gen (SomeSing Shape')
31genShape
37genShape
32 = Gen.choice [
38 = Gen.choice [
33 genD1
39 genD1
@@ -35,20 +41,20 @@ genShape
35 , genD3
41 , genD3
36 ]
42 ]
37
43
38−genD1 :: Gen (SomeSing Shape)
44+genD1 :: Gen (SomeSing Shape')
39genD1 = do
45genD1 = do
40 n <- genNat
46 n <- genNat
41 return $ case n of
47 return $ case n of
42 SomeNat (_ :: Proxy x) -> SomeSing (sing :: Sing ('D1 x))
48 SomeNat (_ :: Proxy x) -> SomeSing (sing :: Sing ('D1 x))
43
49
44−genD2 :: Gen (SomeSing Shape)
50+genD2 :: Gen (SomeSing Shape')
45genD2 = do
51genD2 = do
46 n <- genNat
52 n <- genNat
47 m <- genNat
53 m <- genNat
48 return $ case (n, m) of
54 return $ case (n, m) of
49 (SomeNat (_ :: Proxy x), SomeNat (_ :: Proxy y)) -> SomeSing (sing :: Sing ('D2 x y))
55 (SomeNat (_ :: Proxy x), SomeNat (_ :: Proxy y)) -> SomeSing (sing :: Sing ('D2 x y))
50
56
51−genD3 :: Gen (SomeSing Shape)
57+genD3 :: Gen (SomeSing Shape')
52genD3 = do
58genD3 = do
53 n <- genNat
59 n <- genNat
54 m <- genNat
60 m <- genNat
@@ -58,7 +64,7 @@ genD3 = do
58 case natDict px %* natDict pz of
64 case natDict px %* natDict pz of
59 Dict -> SomeSing (sing :: Sing ('D3 x y z))
65 Dict -> SomeSing (sing :: Sing ('D3 x y z))
60
66
61−rss :: SomeSing Shape -> String
67+rss :: SomeSing Shape' -> String
62rss (SomeSing (r :: Sing s)) = case r of
68rss (SomeSing (r :: Sing s)) = case r of
63 (D1Sing a@SNat) -> "D1 " ++ show (natVal a)
69 (D1Sing a@SNat) -> "D1 " ++ show (natVal a)
64 (D2Sing a@SNat b@SNat) -> "D2 " ++ show (natVal a) ++ " " ++ show (natVal b)
70 (D2Sing a@SNat b@SNat) -> "D2 " ++ show (natVal a) ++ " " ++ show (natVal b)