neural-0.2.0.0: benchmark/benchmark.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE BangPatterns #-}
module Main where
import Control.Category
import Criterion.Main
import Data.MyPrelude
import Data.Utils
import Data.Void
import Numeric.Neural
import Prelude hiding (id, (.))
main :: IO ()
main = defaultMain
[ bgroup "white"
[ bench "10/200" $ whnf (w 10) 200
, bench "10/2000" $ whnf (w 10) 2000
, bench "10/20000" $ whnf (w 10) 20000
, bench "100/200" $ whnf (w 100) 200
, bench "100/2000" $ whnf (w 100) 2000
, bench "100/20000" $ whnf (w 100) 20000
, bench "1000/200" $ whnf (w 1000) 200
, bench "1000/2000" $ whnf (w 1000) 2000
, bench "1000/20000" $ whnf (w 1000) 20000
]
, env setupEnv $ \ ~(m, xss) -> bgroup "linear"
[ l m xss 1 5
, l m xss 5 5
, l m xss 10 5
]
]
w :: Int -> Int -> Double
w sampleCount testCount = flip evalRand (mkStdGen 123456) $ do
stats <- mkStats'
samples <- replicateM sampleCount $ mkSample stats
let m = whiten model' samples
xss <- replicateM testCount $ mkSample stats
return $ sum [model m xs | xs <- xss]
where
mkStats' :: MonadRandom m => m (Vector Width (Double, Double))
mkStats' = sequenceA (pure $ (,) <$> getRandomR (-100, 100) <*> getRandomR (0.1, 20))
mkSample :: MonadRandom m => Vector Width (Double, Double) -> m (Vector Width Double)
mkSample = mapM $ uncurry boxMuller'
model' :: Model (Vector Width) Identity Void (Vector Width Double) Double
model' = Model (cArr $ Diff $ Identity . sum) absurd id runIdentity
type Width = 10
l :: M -> [Vector Width' Double] -> Int -> Int -> Benchmark
l m xss batchSize steps = bench (printf "%d/%d" batchSize steps) $ whnf l' steps where
l' :: Int -> Double
l' steps' =
let m' = loop steps' m
xs = pure 0
in modelError m' [(xs, xs)]
loop :: Int -> M -> M
loop 0 m' = m'
loop !n m' =
let m'' = m' `deepseq` snd $ descent m' 0.01 [(xs, xs) | xs <- take batchSize xss]
in loop (pred n) m''
setupEnv :: IO (M, [Vector Width' Double])
setupEnv = return $ flip evalRand (mkStdGen 987654) $ do
let e xs = Diff $ Identity . sqDiff (fromDouble <$> xs)
m <- modelR $ mkStdModel linearLayer e id id
xss <- replicateM 100 $ let r = getRandomR (-5, 5) in sequence $ pure r
return (m, xss)
type M = StdModel (Vector Width') (Vector Width') (Vector Width' Double) (Vector Width' Double)
type Width' = 100