on master help sign in
Move tests to hedgehog.
commitda810e6f4e75c90201b32881f7a2b34057329fb1 authorHuw Campbell <huw.campbell@ambiata.com> dateMon 10 Apr 2017, 08:49 (10 years ago) parent8ebbea6
13 files changed+205−177
.gitmodules−3 grenade.cabal+2−4 lib/haskell-hedgehog−1 test/Test/Grenade/Layers/Convolution.hs+18−18 test/Test/Grenade/Layers/FullyConnected.hs+13−13 test/Test/Grenade/Layers/Internal/Convolution.hs+34−27 test/Test/Grenade/Layers/Internal/Pooling.hs+25−18 test/Test/Grenade/Layers/Nonlinear.hs+24−18 test/Test/Grenade/Layers/PadCrop.hs+11−7 test/Test/Grenade/Layers/Pooling.hs+12−13 test/Test/Grenade/Recurrent/Layers/LSTM.hs+56−49 test/Test/Jack/Hmatrix.hs+5−3 test/Test/Jack/TypeLits.hs+5−3
.gitmodulesdeleted−3
@@ -1,3 +0,0 @@
1−[submodule "lib/haskell-hedgehog"]
2− path = lib/haskell-hedgehog
3− url = git@github.com:hedgehogqa/haskell-hedgehog.git
grenade.cabal+2−4
@@ -125,16 +125,14 @@ test-suite test
125125 build-depends:
126126 base >= 4.8 && < 5
127127 , grenade
128− , ambiata-disorder-core
129− , ambiata-disorder-jack
128+ , hedgehog >= 0.1 && < 0.2
130129 , hmatrix
131130 , mtl
132131 , singletons
133132 , text == 1.2.*
134133 , typelits-witnesses
134+ , transformers
135135 , constraints
136− , QuickCheck >= 2.7 && < 2.9
137− , quickcheck-instances == 0.3.*
138136 , MonadRandom
139137 , random
140138 , ad
lib/haskell-hedgehogdeleted−1

Submodule changed.

test/Test/Grenade/Layers/Convolution.hs+18−18
@@ -18,10 +18,12 @@ import GHC.TypeLits.Witnesses
1818import Grenade.Core
1919import Grenade.Layers.Convolution
2020
21−import Disorder.Jack
21+import Hedgehog
22+import qualified Hedgehog.Gen as Gen
2223
2324import Test.Jack.Hmatrix
2425import Test.Jack.TypeLits
26+import Test.Jack.Compat
2527
2628data OpaqueConvolution :: * where
2729 OpaqueConvolution :: Convolution channels filters kernelRows kernelColumns strideRows strideColumns -> OpaqueConvolution
@@ -58,15 +60,15 @@ genOpaqueOpaqueConvolution = do
5860 in case p1 %* p2 %* p3 of
5961 Dict -> OpaqueConvolution <$> (genConvolution :: Jack (Convolution ch fl kr kc sr sc))
6062
61−prop_conv_net_witness =
62− gamble genOpaqueOpaqueConvolution $ \onet ->
63− (case onet of
64− (OpaqueConvolution ((Convolution _ _) :: Convolution channels filters kernelRows kernelCols strideRows strideCols)) -> True
65− ) :: Bool
63+prop_conv_net_witness = property $
64+ forAll genOpaqueOpaqueConvolution >>= \onet ->
65+ case onet of
66+ (OpaqueConvolution ((Convolution _ _) :: Convolution channels filters kernelRows kernelCols strideRows strideCols)) -> success
6667
67−prop_conv_net =
68− gamble genOpaqueOpaqueConvolution $ \onet ->
69− (case onet of
68+
69+prop_conv_net = property $
70+ forAll genOpaqueOpaqueConvolution >>= \onet ->
71+ case onet of
7072 (OpaqueConvolution (convLayer@(Convolution _ _) :: Convolution channels filters kernelRows kernelCols strideRows strideCols)) ->
7173 let ok stride kernel = [extent | extent <- [(kernel + 1) .. 30 ], (extent - kernel) `mod` stride == 0]
7274 kr = fromIntegral $ natVal (Proxy :: Proxy kernelRows)
@@ -74,15 +76,15 @@ prop_conv_net =
7476 sr = fromIntegral $ natVal (Proxy :: Proxy strideRows)
7577 sc = fromIntegral $ natVal (Proxy :: Proxy strideCols)
7678
77− in gamble (elements (ok sr kr)) $ \er ->
78− gamble (elements (ok sc kc)) $ \ec ->
79+ in forAll (Gen.element (ok sr kr)) >>= \er ->
80+ forAll (Gen.element (ok sc kc)) >>= \ec ->
7981 let rr = ((er - kr) `div` sr) + 1
8082 rc = ((ec - kc) `div` sc) + 1
8183 Just er' = someNatVal er
8284 Just ec' = someNatVal ec
8385 Just rr' = someNatVal rr
8486 Just rc' = someNatVal rc
85− in (case (er', ec', rr', rc') of
87+ in case (er', ec', rr', rc') of
8688 ( SomeNat (pinr :: Proxy inRows), SomeNat (_ :: Proxy inCols), SomeNat (pour :: Proxy outRows), SomeNat (_ :: Proxy outCols)) ->
8789 case ( natDict pinr %* natDict (Proxy :: Proxy channels)
8890 , natDict pour %* natDict (Proxy :: Proxy filters)
@@ -90,14 +92,12 @@ prop_conv_net =
9092 , (unsafeCoerce (Dict :: Dict ()) :: Dict (((outRows - 1) * strideRows) ~ (inRows - kernelRows)))
9193 , (unsafeCoerce (Dict :: Dict ()) :: Dict (((outCols - 1) * strideCols) ~ (inCols - kernelCols)))) of
9294 (Dict, Dict, Dict, Dict) ->
93− gamble (S3D <$> uniformSample) $ \(input :: S ('D3 inRows inCols channels)) ->
95+ forAll (S3D <$> uniformSample) >>= \(input :: S ('D3 inRows inCols channels)) ->
9496 let (tape, output :: S ('D3 outRows outCols filters)) = runForwards convLayer input
9597 backed :: (Gradient (Convolution channels filters kernelRows kernelCols strideRows strideCols), S ('D3 inRows inCols channels))
9698 = runBackwards convLayer tape output
97− in backed `seq` True
98− ) :: Property
99− ) :: Property
99+ in backed `seq` success
100+
100101
101−return []
102102tests :: IO Bool
103−tests = $quickCheckAll
103+tests = $$(checkConcurrent)
test/Test/Grenade/Layers/FullyConnected.hs+13−13
@@ -15,9 +15,10 @@ import GHC.TypeLits
1515import Grenade.Core
1616import Grenade.Layers.FullyConnected
1717
18−import Disorder.Jack
18+import Hedgehog
1919
2020import Test.Jack.Hmatrix
21+import Test.Jack.Compat
2122
2223
2324data OpaqueFullyConnected :: * where
@@ -28,8 +29,8 @@ instance Show OpaqueFullyConnected where
2829
2930genOpaqueFullyConnected :: Jack OpaqueFullyConnected
3031genOpaqueFullyConnected = do
31− input :: Integer <- choose (2, 100)
32− output :: Integer <- choose (1, 100)
32+ input :: Integer <- choose 2 100
33+ output :: Integer <- choose 1 100
3334 let Just input' = someNatVal input
3435 let Just output' = someNatVal output
3536 case (input', output') of
@@ -41,14 +42,13 @@ genOpaqueFullyConnected = do
4142 return . OpaqueFullyConnected $ (FullyConnected (FullyConnected' wB wN) (FullyConnected' bM kM) :: FullyConnected i' o')
4243
4344prop_fully_connected_forwards :: Property
44−prop_fully_connected_forwards =
45− gamble genOpaqueFullyConnected $ \(OpaqueFullyConnected (fclayer :: FullyConnected i o)) ->
46− gamble (S1D <$> randomVector) $ \(input :: S ('D1 i)) ->
47− let (tape, output :: S ('D1 o)) = runForwards fclayer input
48− backed :: (Gradient (FullyConnected i o), S ('D1 i))
49− = runBackwards fclayer tape output
50− in backed `seq` True
51−
52−return []
45+prop_fully_connected_forwards = property $ do
46+ OpaqueFullyConnected (fclayer :: FullyConnected i o) <- forAll genOpaqueFullyConnected
47+ input :: S ('D1 i) <- forAll (S1D <$> randomVector)
48+ let (tape, output :: S ('D1 o)) = runForwards fclayer input
49+ backed :: (Gradient (FullyConnected i o), S ('D1 i))
50+ = runBackwards fclayer tape output
51+ backed `seq` success
52+
5353tests :: IO Bool
54−tests = $quickCheckAll
54+tests = $$(checkConcurrent)
test/Test/Grenade/Layers/Internal/Convolution.hs+34−27
@@ -12,41 +12,48 @@ import Grenade.Layers.Internal.Convolution
1212
1313import Numeric.LinearAlgebra hiding (uniformSample, konst, (===))
1414
15−import Disorder.Jack
15+import Hedgehog
16+import qualified Hedgehog.Gen as Gen
17+import qualified Hedgehog.Range as Range
1618
1719import qualified Test.Grenade.Layers.Internal.Reference as Reference
20+import Test.Jack.Compat
1821
1922prop_im2col_col2im_symmetrical_with_kernel_stride =
2023 let factors n = [x | x <- [1..n], n `mod` x == 0]
21− in gamble (choose (2, 100)) $ \height ->
22− gamble (choose (2, 100)) $ \width ->
23− gamble ((height `div`) <$> elements (factors height)) $ \kernel_h ->
24− gamble ((width `div`) <$> elements (factors width)) $ \kernel_w ->
25− gamble (listOfN (height * width) (height * width) sizedRealFrac) $ \input ->
26− let input' = (height >< width) input
27− stride_h = kernel_h
28− stride_w = kernel_w
29− out = col2im kernel_h kernel_w stride_h stride_w height width . im2col kernel_h kernel_w stride_h stride_w $ input'
30− in input' === out
24+ in property $ do
25+ height <- forAll $ choose 2 100
26+ width <- forAll $ choose 2 100
27+ kernel_h <- forAll $ (height `div`) <$> Gen.element (factors height)
28+ kernel_w <- forAll $ (width `div`) <$> Gen.element (factors width)
29+ input <- forAll $ Gen.list (Range.singleton $ height * width) (Gen.realFloat $ Range.linearFracFrom 0 (-100) 100)
30+
31+ let input' = (height >< width) input
32+ let stride_h = kernel_h
33+ let stride_w = kernel_w
34+ let out = col2im kernel_h kernel_w stride_h stride_w height width . im2col kernel_h kernel_w stride_h stride_w $ input'
35+ input' === out
3136
3237prop_im2col_col2im_behaves_as_reference =
3338 let ok extent kernel = [stride | stride <- [1..extent], (extent - kernel) `mod` stride == 0]
34− in gamble (choose (2, 100)) $ \height ->
35− gamble (choose (2, 100)) $ \width ->
36− gamble (choose (2, height - 1)) $ \kernel_h ->
37− gamble (choose (2, width - 1)) $ \kernel_w ->
38− gamble (elements (ok height kernel_h)) $ \stride_h ->
39− gamble (elements (ok width kernel_w)) $ \stride_w ->
40− gamble (listOfN (height * width) (height * width) sizedRealFrac) $ \input ->
41− let input' = (height >< width) input
42− outFast = im2col kernel_h kernel_w stride_h stride_w input'
43− retFast = col2im kernel_h kernel_w stride_h stride_w height width outFast
44−
45− outReference = Reference.im2col kernel_h kernel_w stride_h stride_w input'
46− retReference = Reference.col2im kernel_h kernel_w stride_h stride_w height width outReference
47− in outFast === outReference .&&. retFast === retReference
48−
39+ in property $ do
40+ height <- forAll (choose 2 100)
41+ width <- forAll (choose 2 100)
42+ kernel_h <- forAll (choose 2 (height - 1))
43+ kernel_w <- forAll (choose 2 (width - 1))
44+ stride_h <- forAll (Gen.element (ok height kernel_h))
45+ stride_w <- forAll (Gen.element (ok width kernel_w))
46+ input <- forAll ( Gen.list (Range.singleton $ height * width) (Gen.realFloat $ Range.linearFracFrom 0 (-100) 100))
47+ let input' = (height >< width) input
48+ let outFast = im2col kernel_h kernel_w stride_h stride_w input'
49+ let retFast = col2im kernel_h kernel_w stride_h stride_w height width outFast
50+
51+ let outReference = Reference.im2col kernel_h kernel_w stride_h stride_w input'
52+ let retReference = Reference.col2im kernel_h kernel_w stride_h stride_w height width outReference
53+
54+ outFast === outReference
55+ retFast === retReference
4956
5057return []
5158tests :: IO Bool
52−tests = $quickCheckAll
59+tests = $$(checkConcurrent)
test/Test/Grenade/Layers/Internal/Pooling.hs+25−18
@@ -12,28 +12,35 @@ import Grenade.Layers.Internal.Pooling
1212
1313import Numeric.LinearAlgebra hiding (uniformSample, konst, (===))
1414
15−import Disorder.Jack
15+import Hedgehog
16+import qualified Hedgehog.Gen as Gen
17+import qualified Hedgehog.Range as Range
1618
1719import qualified Test.Grenade.Layers.Internal.Reference as Reference
20+import Test.Jack.Compat
1821
1922prop_poolForwards_poolBackwards_behaves_as_reference =
2023 let ok extent kernel = [stride | stride <- [1..extent], (extent - kernel) `mod` stride == 0]
2124 output extent kernel stride = (extent - kernel) `div` stride + 1
22− in gamble (choose (2, 100)) $ \height ->
23− gamble (choose (2, 100)) $ \width ->
24− gamble (choose (1, height - 1)) $ \kernel_h ->
25− gamble (choose (1, width - 1)) $ \kernel_w ->
26− gamble (elements (ok height kernel_h)) $ \stride_h ->
27− gamble (elements (ok width kernel_w)) $ \stride_w ->
28− gamble (listOfN (height * width) (height * width) sizedRealFrac) $ \input ->
29− let input' = (height >< width) input
30− outFast = poolForward 1 height width kernel_h kernel_w stride_h stride_w input'
31− retFast = poolBackward 1 height width kernel_h kernel_w stride_h stride_w input' outFast
32−
33− outReference = Reference.poolForward kernel_h kernel_w stride_h stride_w (output height kernel_h stride_h) (output width kernel_w stride_w) input'
34− retReference = Reference.poolBackward kernel_h kernel_w stride_h stride_w input' outReference
35− in outFast === outReference .&&. retFast === retReference
36−
37−return []
25+ in property $ do
26+ height <- forAll $ choose 2 100
27+ width <- forAll $ choose 2 100
28+ kernel_h <- forAll $ choose 1 (height - 1)
29+ kernel_w <- forAll $ choose 1 (width - 1)
30+ stride_h <- forAll $ Gen.element (ok height kernel_h)
31+ stride_w <- forAll $ Gen.element (ok width kernel_w)
32+ input <- forAll $ Gen.list (Range.singleton $ height * width) (Gen.realFloat $ Range.linearFracFrom 0 (-100) 100)
33+
34+ let input' = (height >< width) input
35+ let outFast = poolForward 1 height width kernel_h kernel_w stride_h stride_w input'
36+ let retFast = poolBackward 1 height width kernel_h kernel_w stride_h stride_w input' outFast
37+
38+ let outReference = Reference.poolForward kernel_h kernel_w stride_h stride_w (output height kernel_h stride_h) (output width kernel_w stride_w) input'
39+ let retReference = Reference.poolBackward kernel_h kernel_w stride_h stride_w input' outReference
40+
41+ outFast === outReference
42+ retFast === retReference
43+
44+
3845tests :: IO Bool
39−tests = $quickCheckAll
46+tests = $$(checkConcurrent)
test/Test/Grenade/Layers/Nonlinear.hs+24−18
@@ -9,6 +9,9 @@
99{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
1010module Test.Grenade.Layers.Nonlinear where
1111
12+
13+import Control.Monad.Trans.Class (MonadTrans(..))
14+
1215import Data.Singletons
1316
1417#if __GLASGOW_HASKELL__ < 800
@@ -18,60 +21,63 @@ import Data.Proxy
1821import Grenade
1922import GHC.TypeLits
2023
21−import Disorder.Jack
24+import Hedgehog
25+import Hedgehog.Internal.Property ( Test (..) )
2226
2327import Test.Jack.Hmatrix
2428import Test.Jack.TypeLits
2529
2630import Numeric.LinearAlgebra.Static ( norm_Inf )
2731
32+-- | Generates a random input for the test by running the provided generator.
33+--
34+blindForAll :: Monad m => Gen m a -> Test m a
35+blindForAll = Test . lift . lift
36+
2837prop_sigmoid_grad :: Property
29−prop_sigmoid_grad =
30− gambleDisplay (const "Shape") genShape $ \case
38+prop_sigmoid_grad = property $
39+ blindForAll genShape >>= \case
3140 (SomeSing (r :: Sing s)) ->
3241 withSingI r $
33− gamble genOfShape $ \(ds :: S s) ->
42+ blindForAll genOfShape >>= \(ds :: S s) ->
3443 let (tape, f :: S s) = runForwards Logit ds
3544 ((), ret :: S s) = runBackwards Logit tape (1 :: S s)
3645 (_, numer :: S s) = runForwards Logit (ds + 0.0001)
3746 numericalGradient = (numer - f) * 10000
38− in counterexample (show numericalGradient ++ show ret)
39− ((case numericalGradient - ret of
47+ in assert ((case numericalGradient - ret of
4048 (S1D x) -> norm_Inf x < 0.0001
4149 (S2D x) -> norm_Inf x < 0.0001
4250 (S3D x) -> norm_Inf x < 0.0001) :: Bool)
4351
4452prop_tanh_grad :: Property
45−prop_tanh_grad =
46− gambleDisplay (const "Shape") genShape $ \case
53+prop_tanh_grad = property $
54+ blindForAll genShape >>= \case
4755 (SomeSing (r :: Sing s)) ->
4856 withSingI r $
49− gamble genOfShape $ \(ds :: S s) ->
57+ blindForAll genOfShape >>= \(ds :: S s) ->
5058 let (tape, f :: S s) = runForwards Tanh ds
5159 ((), ret :: S s) = runBackwards Tanh tape (1 :: S s)
5260 (_, numer :: S s) = runForwards Tanh (ds + 0.0001)
5361 numericalGradient = (numer - f) * 10000
54− in counterexample (show numericalGradient ++ show ret)
55− ((case numericalGradient - ret of
62+ in assert ((case numericalGradient - ret of
5663 (S1D x) -> norm_Inf x < 0.001
5764 (S2D x) -> norm_Inf x < 0.001
5865 (S3D x) -> norm_Inf x < 0.001) :: Bool)
5966
6067prop_softmax_grad :: Property
61−prop_softmax_grad =
62− gamble genNat $ \case
68+prop_softmax_grad = property $
69+ forAll genNat >>= \case
6370 (SomeNat (_ :: Proxy s)) ->
64− gamble genOfShape $ \(ds :: S ('D1 s)) ->
71+ forAll genOfShape >>= \(ds :: S ('D1 s)) ->
6572 let (tape, f :: S ('D1 s)) = runForwards Relu ds
6673 ((), ret :: S ('D1 s)) = runBackwards Relu tape (1 :: S ('D1 s))
6774 (_, numer :: S ('D1 s)) = runForwards Relu (ds + 0.0001)
6875 numericalGradient = (numer - f) * 10000
69− in counterexample (show numericalGradient ++ show ret)
70− ((case numericalGradient - ret of
76+ in assert ((case numericalGradient - ret of
7177 (S1D x) -> norm_Inf x < 0.0001) :: Bool)
7278
7379
74−return []
80+
7581tests :: IO Bool
76−tests = $quickCheckAll
82+tests = $$(checkConcurrent)
7783
test/Test/Grenade/Layers/PadCrop.hs+11−7
@@ -15,7 +15,7 @@ module Test.Grenade.Layers.PadCrop where
1515
1616import Grenade
1717
18−import Disorder.Jack
18+import Hedgehog
1919
2020import Numeric.LinearAlgebra.Static ( norm_Inf )
2121
@@ -25,25 +25,29 @@ prop_pad_crop :: Property
2525prop_pad_crop =
2626 let net :: Network '[Pad 2 3 4 6, Crop 2 3 4 6] '[ 'D3 7 9 5, 'D3 16 15 5, 'D3 7 9 5 ]
2727 net = Pad :~> Crop :~> NNil
28− in gamble genOfShape $ \(d :: S ('D3 7 9 5)) ->
28+ in property $
29+ forAll genOfShape >>= \(d :: S ('D3 7 9 5)) ->
2930 let (tapes, res) = runForwards net d
3031 (_ , grad) = runBackwards net tapes d
31− in d ~~~ res .&&. grad ~~~ d
32+ in do assert $ d ~~~ res
33+ assert $ grad ~~~ d
3234
3335prop_pad_crop_2d :: Property
3436prop_pad_crop_2d =
3537 let net :: Network '[Pad 2 3 4 6, Crop 2 3 4 6] '[ 'D2 7 9, 'D2 16 15, 'D2 7 9 ]
3638 net = Pad :~> Crop :~> NNil
37− in gamble genOfShape $ \(d :: S ('D2 7 9)) ->
39+ in property $
40+ forAll genOfShape >>= \(d :: S ('D2 7 9)) ->
3841 let (tapes, res) = runForwards net d
3942 (_ , grad) = runBackwards net tapes d
40− in d ~~~ res .&&. grad ~~~ d
43+ in do assert $ d ~~~ res
44+ assert $ grad ~~~ d
4145
4246(~~~) :: S x -> S x -> Bool
4347(S1D x) ~~~ (S1D y) = norm_Inf (x - y) < 0.00001
4448(S2D x) ~~~ (S2D y) = norm_Inf (x - y) < 0.00001
4549(S3D x) ~~~ (S3D y) = norm_Inf (x - y) < 0.00001
4650
47−return []
51+
4852tests :: IO Bool
49−tests = $quickCheckAll
53+tests = $$(checkConcurrent)
test/Test/Grenade/Layers/Pooling.hs+12−13
@@ -12,8 +12,8 @@ import Data.Singletons ()
1212import GHC.TypeLits
1313import Grenade.Layers.Pooling
1414
15−import Disorder.Jack
16−
15+import Hedgehog
16+import Test.Jack.Compat
1717
1818data OpaquePooling :: * where
1919 OpaquePooling :: (KnownNat kh, KnownNat kw, KnownNat sh, KnownNat sw) => Pooling kh kw sh sw -> OpaquePooling
@@ -23,22 +23,21 @@ instance Show OpaquePooling where
2323
2424genOpaquePooling :: Jack OpaquePooling
2525genOpaquePooling = do
26− Just kernelHeight <- someNatVal <$> choose (2, 15)
27− Just kernelWidth <- someNatVal <$> choose (2, 15)
28− Just strideHeight <- someNatVal <$> choose (2, 15)
29− Just strideWidth <- someNatVal <$> choose (2, 15)
26+ Just kernelHeight <- someNatVal <$> choose 2 15
27+ Just kernelWidth <- someNatVal <$> choose 2 15
28+ Just strideHeight <- someNatVal <$> choose 2 15
29+ Just strideWidth <- someNatVal <$> choose 2 15
3030
3131 case (kernelHeight, kernelWidth, strideHeight, strideWidth) of
3232 (SomeNat (_ :: Proxy kh), SomeNat (_ :: Proxy kw), SomeNat (_ :: Proxy sh), SomeNat (_ :: Proxy sw)) ->
3333 return $ OpaquePooling (Pooling :: Pooling kh kw sh sw)
3434
3535prop_pool_layer_witness =
36− gamble genOpaquePooling $ \onet ->
37− (case onet of
38− (OpaquePooling (Pooling :: Pooling kernelRows kernelCols strideRows strideCols)) -> True
39− ) :: Bool
40−
36+ property $ do
37+ onet <- forAll genOpaquePooling
38+ case onet of
39+ (OpaquePooling (Pooling :: Pooling kernelRows kernelCols strideRows strideCols)) ->
40+ assert True
4141
42−return []
4342tests :: IO Bool
44−tests = $quickCheckAll
43+tests = $$(checkConcurrent)
test/Test/Grenade/Recurrent/Layers/LSTM.hs+56−49
@@ -10,7 +10,7 @@
1010{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
1111module Test.Grenade.Recurrent.Layers.LSTM where
1212
13−import Disorder.Jack
13+import Hedgehog
1414
1515import Data.Foldable ( toList )
1616import Data.Singletons.TypeLits
@@ -24,6 +24,7 @@ import qualified Numeric.LinearAlgebra.Static as S
2424
2525import qualified Test.Grenade.Recurrent.Layers.LSTM.Reference as Reference
2626import Test.Jack.Hmatrix
27+import Test.Jack.Compat
2728
2829genLSTM :: forall i o. (KnownNat i, KnownNat o) => Jack (LSTM i o)
2930genLSTM = do
@@ -39,63 +40,69 @@ genLSTM = do
3940 <*> pure (LSTMWeights w0 u0 v0 w0 u0 v0 w0 u0 v0 w0 v0)
4041
4142prop_lstm_reference_forwards =
42− gamble randomVector $ \(input :: S.R 3) ->
43− gamble randomVector $ \(cell :: S.R 2) ->
44− gamble genLSTM $ \(net@(LSTM lstmWeights _) :: LSTM 3 2) ->
45− let actual = runRecurrentForwards net (S1D cell) (S1D input)
46− in case actual of
47− (_, (S1D cellOut) :: S ('D1 2), (S1D output) :: S ('D1 2)) ->
48− let cellOut' = Reference.Vector . H.toList . S.extract $ cellOut
49− output' = Reference.Vector . H.toList . S.extract $ output
50− refNet = Reference.lstmToReference lstmWeights
51− refCell = Reference.Vector . H.toList . S.extract $ cell
52− refInput = Reference.Vector . H.toList . S.extract $ input
53− (refCO, refO) = Reference.runLSTM refNet refCell refInput
54− in toList refCO ~~~ toList cellOut' .&&. toList refO ~~~ toList output'
43+ property $ do
44+ input :: S.R 3 <- forAll randomVector
45+ cell :: S.R 2 <- forAll randomVector
46+ net@(LSTM lstmWeights _) :: LSTM 3 2 <- forAll genLSTM
47+
48+ let actual = runRecurrentForwards net (S1D cell) (S1D input)
49+ case actual of
50+ (_, (S1D cellOut) :: S ('D1 2), (S1D output) :: S ('D1 2)) ->
51+ let cellOut' = Reference.Vector . H.toList . S.extract $ cellOut
52+ output' = Reference.Vector . H.toList . S.extract $ output
53+ refNet = Reference.lstmToReference lstmWeights
54+ refCell = Reference.Vector . H.toList . S.extract $ cell
55+ refInput = Reference.Vector . H.toList . S.extract $ input
56+ (refCO, refO) = Reference.runLSTM refNet refCell refInput
57+ in do assert (toList refCO ~~~ toList cellOut')
58+ assert (toList refO ~~~ toList output')
59+
5560
5661prop_lstm_reference_backwards =
57− gamble randomVector $ \(input :: S.R 3) ->
58− gamble randomVector $ \(cell :: S.R 2) ->
59− gamble genLSTM $ \(net@(LSTM lstmWeights _) :: LSTM 3 2) ->
60− let actualBacks = runRecurrentBackwards net (S1D cell, S1D input) (S1D (S.konst 1) :: S ('D1 2)) (S1D (S.konst 1) :: S ('D1 2))
61− in case actualBacks of
62− (actualGradients, _, _ :: S ('D1 3)) ->
63− let refNet = Reference.lstmToReference lstmWeights
64− refCell = Reference.Vector . H.toList . S.extract $ cell
65− refInput = Reference.Vector . H.toList . S.extract $ input
66− refGradients = Reference.runLSTMback refCell refInput refNet
67− in toList refGradients ~~~ toList (Reference.lstmToReference actualGradients)
62+ property $ do
63+ input :: S.R 3 <- forAll randomVector
64+ cell :: S.R 2 <- forAll randomVector
65+ net@(LSTM lstmWeights _) :: LSTM 3 2 <- forAll genLSTM
66+ let actualBacks = runRecurrentBackwards net (S1D cell, S1D input) (S1D (S.konst 1) :: S ('D1 2)) (S1D (S.konst 1) :: S ('D1 2))
67+ case actualBacks of
68+ (actualGradients, _, _ :: S ('D1 3)) ->
69+ let refNet = Reference.lstmToReference lstmWeights
70+ refCell = Reference.Vector . H.toList . S.extract $ cell
71+ refInput = Reference.Vector . H.toList . S.extract $ input
72+ refGradients = Reference.runLSTMback refCell refInput refNet
73+ in assert $ toList refGradients ~~~ toList (Reference.lstmToReference actualGradients)
6874
6975prop_lstm_reference_backwards_input =
70− gamble randomVector $ \(input :: S.R 3) ->
71− gamble randomVector $ \(cell :: S.R 2) ->
72− gamble genLSTM $ \(net@(LSTM lstmWeights _) :: LSTM 3 2) ->
73− let actualBacks = runRecurrentBackwards net (S1D cell, S1D input) (S1D (S.konst 1) :: S ('D1 2)) (S1D (S.konst 1) :: S ('D1 2))
74− in case actualBacks of
75− (_, _, S1D actualGradients :: S ('D1 3)) ->
76− let refNet = Reference.lstmToReference lstmWeights
77− refCell = Reference.Vector . H.toList . S.extract $ cell
78− refInput = Reference.Vector . H.toList . S.extract $ input
79− refGradients = Reference.runLSTMbackOnInput refCell refNet refInput
80− in toList refGradients ~~~ H.toList (S.extract actualGradients)
76+ property $ do
77+ input :: S.R 3 <- forAll randomVector
78+ cell :: S.R 2 <- forAll randomVector
79+ net@(LSTM lstmWeights _) :: LSTM 3 2 <- forAll genLSTM
80+ let actualBacks = runRecurrentBackwards net (S1D cell, S1D input) (S1D (S.konst 1) :: S ('D1 2)) (S1D (S.konst 1) :: S ('D1 2))
81+ case actualBacks of
82+ (_, _, S1D actualGradients :: S ('D1 3)) ->
83+ let refNet = Reference.lstmToReference lstmWeights
84+ refCell = Reference.Vector . H.toList . S.extract $ cell
85+ refInput = Reference.Vector . H.toList . S.extract $ input
86+ refGradients = Reference.runLSTMbackOnInput refCell refNet refInput
87+ in assert $ toList refGradients ~~~ H.toList (S.extract actualGradients)
8188
8289prop_lstm_reference_backwards_cell =
83− gamble randomVector $ \(input :: S.R 3) ->
84− gamble randomVector $ \(cell :: S.R 2) ->
85− gamble genLSTM $ \(net@(LSTM lstmWeights _) :: LSTM 3 2) ->
86− let actualBacks = runRecurrentBackwards net (S1D cell, S1D input) (S1D (S.konst 1) :: S ('D1 2)) (S1D (S.konst 1) :: S ('D1 2))
87− in case actualBacks of
88− (_, S1D actualGradients, _ :: S ('D1 3)) ->
89− let refNet = Reference.lstmToReference lstmWeights
90− refCell = Reference.Vector . H.toList . S.extract $ cell
91− refInput = Reference.Vector . H.toList . S.extract $ input
92− refGradients = Reference.runLSTMbackOnCell refInput refNet refCell
93− in toList refGradients ~~~ H.toList (S.extract actualGradients)
90+ property $ do
91+ input :: S.R 3 <- forAll randomVector
92+ cell :: S.R 2 <- forAll randomVector
93+ net@(LSTM lstmWeights _) :: LSTM 3 2 <- forAll genLSTM
94+ let actualBacks = runRecurrentBackwards net (S1D cell, S1D input) (S1D (S.konst 1) :: S ('D1 2)) (S1D (S.konst 1) :: S ('D1 2))
95+ case actualBacks of
96+ (_, S1D actualGradients, _ :: S ('D1 3)) ->
97+ let refNet = Reference.lstmToReference lstmWeights
98+ refCell = Reference.Vector . H.toList . S.extract $ cell
99+ refInput = Reference.Vector . H.toList . S.extract $ input
100+ refGradients = Reference.runLSTMbackOnCell refInput refNet refCell
101+ in assert $ toList refGradients ~~~ H.toList (S.extract actualGradients)
94102
95103
96104(~~~) as bs = all (< 1e-8) (zipWith (-) as bs)
97105infix 4 ~~~
98106
99−return []
100107tests :: IO Bool
101−tests = $quickCheckAll
108+tests = $$(checkConcurrent)
test/Test/Jack/Hmatrix.hs+5−3
@@ -8,17 +8,19 @@ module Test.Jack.Hmatrix where
88import Grenade
99import Data.Singletons
1010
11−import Disorder.Jack
11+import qualified Hedgehog.Gen as Gen
12+import qualified Hedgehog.Range as Range
1213
1314import GHC.TypeLits
1415
1516import qualified Numeric.LinearAlgebra.Static as HStatic
17+import Test.Jack.Compat
1618
1719randomVector :: forall n. KnownNat n => Jack (HStatic.R n)
18−randomVector = (\s -> HStatic.randomVector s HStatic.Uniform * 2 - 1) <$> sizedNat
20+randomVector = (\s -> HStatic.randomVector s HStatic.Uniform * 2 - 1) <$> Gen.int Range.linearBounded
1921
2022uniformSample :: forall m n. (KnownNat m, KnownNat n) => Jack (HStatic.L m n)
21−uniformSample = (\s -> HStatic.uniformSample s (-1) 1 ) <$> sizedNat
23+uniformSample = (\s -> HStatic.uniformSample s (-1) 1 ) <$> Gen.int Range.linearBounded
2224
2325-- | Generate random data of the desired shape
2426genOfShape :: forall x. ( SingI x ) => Jack (S x)
test/Test/Jack/TypeLits.hs+5−3
@@ -10,16 +10,18 @@ import Data.Constraint
1010import Data.Proxy
1111#endif
1212import Data.Singletons
13−import Disorder.Jack
13+
14+import qualified Hedgehog.Gen as Gen
1415
1516import Grenade
1617
1718import GHC.TypeLits
1819import GHC.TypeLits.Witnesses
20+import Test.Jack.Compat
1921
2022genNat :: Jack SomeNat
2123genNat = do
22− Just n <- someNatVal <$> choose (1, 10)
24+ Just n <- someNatVal <$> choose 1 10
2325 return n
2426
2527#if __GLASGOW_HASKELL__ < 800
@@ -30,7 +32,7 @@ type Shape' = Shape
3032
3133genShape :: Jack (SomeSing Shape')
3234genShape
33− = oneOf [
35+ = Gen.choice [
3436 genD1
3537 , genD2
3638 , genD3