packages feed

deeplearning-hs (empty) → 0.1.0.0

raw patch · 7 files changed

+362/−0 lines, 7 filesdep +QuickCheckdep +acceleratedep +basesetup-changed

Dependencies added: QuickCheck, accelerate, base, deeplearning-hs, mtl, repa, repa-algorithms, test-framework, test-framework-quickcheck2, vector

Files

+ DeepLearning/ConvNet.hs view
@@ -0,0 +1,185 @@+{-# LANGUAGE FlexibleContexts          #-}+{-# LANGUAGE FlexibleInstances         #-}+{-# LANGUAGE FunctionalDependencies    #-}+{-# LANGUAGE TypeOperators             #-}++{-|+Module      : DeepLearning.ConvNet+Description : Deep Learning+Copyright   : (c) Andrew Tulloch, 2014+License     : GPL-3+Maintainer  : andrew+cabal@tullo.ch+Stability   : experimental+Portability : POSIX+-}+module DeepLearning.ConvNet+    (+     (>->),+     DVol,+     Forward,+     InnerLayer,+     SoftMaxLayer(..),+     TopLayer,+     Vol,+     flowNetwork,+     net1,+     net2,+     newFC,+     withActivations,+    ) where++import           Control.Monad as CM+import           Control.Monad.Writer                 hiding (Any)+import           Data.Array.Repa+import           Data.Array.Repa.Algorithms.Randomish+import qualified Data.Vector.Unboxed                  as V+import           Prelude                              as P hiding (map, zipWith)+++-- ** Helper Types++-- |Activation matrix+type Vol sh = Array U sh Double+-- |Delayed activation matrix+type DVol sh = Array D sh Double++-- |Label for supervised learning+type Label = Int++-- **  Top Layers+-- |'TopLayer' is a top level layer that can initialize a+-- backpropagation pass.+class TopLayer a where+    topForward :: (Monad m) => a -> Vol DIM1 -> m (DVol DIM1)+    topBackward :: (Monad m) => a -> Label -> Vol DIM1 -> Vol DIM1 -> m (DVol DIM1)++-- |'SoftMaxLayer' computes the softmax activation function.+data SoftMaxLayer = SoftMaxLayer -- ++instance TopLayer SoftMaxLayer where+    topForward _ = softMaxForward+    topBackward _ = softMaxBackward++softMaxForward :: (Shape sh, Monad m) => Vol sh -> m (DVol sh)+softMaxForward input = do+  exponentials <- exponentiate input+  sumE <- foldAllP (+) 0.0 exponentials+  return $ map (/ sumE) exponentials+      where+        maxA = foldAllP max 0.0+        exponentiate acts = do+              maxAct <- maxA acts+              return $ map (\a -> exp (a - maxAct)) acts++softMaxBackward :: (Monad m) => Label -> Vol DIM1 -> Vol DIM1 -> m (DVol DIM1)+softMaxBackward label output _ = return $ traverse output id gradientAt+      where+        gradientAt f s@(Z :. i) = gradient (f s) i+        gradient outA target = -(bool2Double indicator - outA)+            where+              indicator = label == target+              bool2Double x = if x then 1.0 else 0.0++-- ** Inner Layers+-- |'InnerLayer' represents an inner layer of a neural network that+-- can accept backpropagation input from higher layers+class (Shape sh, Shape sh') => InnerLayer a sh sh' | a -> sh, a -> sh' where+    innerForward :: Monad m => a -> Vol sh -> m (DVol sh')+    innerBackward :: Monad m => a -> Vol sh' -> Vol sh -> m (DVol sh)++-- |'FullyConnectedLayer' represents a fully-connected input layer+data FullyConnectedLayer sh = FullyConnectedLayer {+      _weights :: Vol (sh :. Int),+      _bias    :: Vol DIM1+    }++instance (Shape sh) => InnerLayer (FullyConnectedLayer sh) sh DIM1 where+    innerForward = fcForward+    innerBackward = fcBackward++fcForward :: (Shape sh, Monad m)+          => FullyConnectedLayer sh -> Vol sh -> m (DVol DIM1)+fcForward (FullyConnectedLayer w b) input =+    return $ traverse w toNumFilters f+        where+          toNumFilters (_ :. i) = Z :. i+          f _ (Z :. i) = bias + dotProduct weights input+              where+                bias = toUnboxed b V.! i+                weights = computeUnboxedS $ slice w (Any :. (i :: Int))++fcBackward :: (Monad m)+           => FullyConnectedLayer sh -> Vol DIM1 -> Vol sh -> m (DVol sh)+fcBackward = undefined++dotProduct :: (Num a, V.Unbox a) => Array U sh a -> Array U sh a -> a+dotProduct l r = prod (toUnboxed l) (toUnboxed r)+    where+      prod lv rv = V.sum $ V.zipWith (*) lv rv+++-- ** Composing Layers++-- |The 'Forward' function represents a single forward pass through a layer.+type Forward m sh sh' = (Vol sh -> WriterT [V.Vector Double] m (DVol sh'))++-- |'(>->)' composes two forward activation functions+(>->) :: (Monad m, Shape sh, Shape sh', Shape sh'')+        => Forward m sh sh' -> Forward m sh' sh'' -> Forward m sh sh''+(f >-> g) input = do+  intermediate <- f input+  unboxed <- computeP intermediate+  tell [toUnboxed unboxed]+  g unboxed++-- |'net1' constructs a single-layer fully connected perceptron with+-- softmax output.+net1+  :: (Monad m, InnerLayer a sh DIM1, TopLayer a1) =>+     a -> a1 -> Forward m sh DIM1+net1 bottom top = innerForward bottom >-> topForward top+++-- |'net1' constructs a two-layer fully connected MLP with+-- softmax output.+net2+  :: (Monad m, InnerLayer a sh sh', InnerLayer a1 sh' DIM1,+      TopLayer a2) =>+     a -> a1 -> a2 -> Forward m sh DIM1+net2 bottom middle top = innerForward bottom >-> net1 middle top++-- |'withActivations' computes the output activation, along with the+-- intermediate activations+withActivations :: Forward m sh sh' -> Vol sh -> m (DVol sh', [V.Vector Double])+withActivations f input = runWriterT (f input)++-- |'newFC' constructs a new fully connected layer+newFC :: Shape sh => sh -> Int -> FullyConnectedLayer sh+newFC sh numFilters = FullyConnectedLayer {+                        _weights=randomishDoubleArray (sh :. (numFilters :: Int)) 0 1.0 1,+                        _bias=randomishDoubleArray (Z :. (numFilters :: Int)) 0 1.0 1+                      }++-- |'FlowNetwork' builds a network of the form+--+-- @+--  Input Layer              Output Softmax+--     +--++--     |  |   Inner Layers    +--+   +--++--     |  |                   |  |   |  |+--     |  |   +-+   +-+  +-+  |  |   |  |+--     |  +---+ +---+ +--+ +--+  +--->  |+--     |  |   +-+   +-+  +-+  |  |   |  |+--     |  |                   |  |   |  |+--     |  |                   +--+   +--++--     +--++-- @+flowNetwork :: (Monad m, Shape sh) => sh -> Int -> Int -> Int -> Forward m sh DIM1+flowNetwork inputShape numHiddenLayers numHiddenNodes numClasses =+    inputLayer >-> innerLayers >-> preTopLayer >-> topLayer+    where+      inputLayer = innerForward $ newFC inputShape numHiddenNodes+      innerLayers = flatInner $ P.fmap (\_ -> newFC (Z :. numHiddenNodes) numHiddenNodes) [1..numHiddenLayers]+      preTopLayer = innerForward $ newFC (Z :. numHiddenNodes) numClasses+      topLayer = topForward SoftMaxLayer+      flatInner layers = P.foldl1 (>->) (P.fmap innerForward layers)
+ DeepLearning/ConvNetTest.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE TypeOperators #-}+module Main where++import           Data.Array.Repa+import           Data.Array.Repa.Arbitrary+import           Data.Monoid+import qualified Data.Vector.Unboxed                  as V+import           DeepLearning.ConvNet+import           DeepLearning.Util+import           Test.Framework+import           Test.Framework.Providers.QuickCheck2+import           Test.QuickCheck++genOneLayer :: (Shape sh) => sh -> Gen (Int, Vol sh)+genOneLayer sh = do+  a <- choose (1, 10)+  b <- arbitraryUShaped sh+  return (a, b)++testFilter :: (Shape sh) => (Int, Vol sh) -> Bool+testFilter (numFilters, input) = and invariants+    where+      [(outAP, [innerA])] = withActivations (testNet sh numFilters) (testInput sh)+      outA = computeS outAP :: Vol DIM1+      sh = extent input+      invariants = [+       (length . toList) outA == numFilters,+       V.length innerA == numFilters]++prop_singleLayer :: Property+prop_singleLayer = forAll (genOneLayer testShape) testFilter++tests :: [Test]+tests = [testProperty "singleLayer" prop_singleLayer]+++main :: IO ()+main = defaultMainWithOpts tests mempty
+ DeepLearning/Util.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE TypeOperators #-}++{-|+Module      : DeepLearning.Util+Description : Deep Learning+Copyright   : (c) Andrew Tulloch, 2014+License     : GPL-3+Maintainer  : andrew+cabal@tullo.ch+Stability   : experimental+Portability : POSIX+-}+module DeepLearning.Util where++import           Data.Array.Repa+import           Data.Array.Repa.Algorithms.Randomish+import           DeepLearning.ConvNet++-- |Sample 3x3 matrix used for demonstrations and tests+testShape :: (Z :. Int) :. Int+testShape = Z :. (3 :: Int) :. (3 :: Int)++-- |Random 3x3 matrix+testInput :: Shape sh => sh -> Array U sh Double+testInput sh = randomishDoubleArray sh 0 1.0 1++-- |Random single-layer network+testNet :: (Monad m, Shape sh) => sh -> Int -> Forward m sh DIM1+testNet sh numFilters = net1 testFC testSM+    where+      testFC = newFC sh numFilters+      testSM = SoftMaxLayer
+ LICENSE view
@@ -0,0 +1,28 @@+The MIT License++Author:: Andrew Tulloch <andrew@tullo.ch>+Copyright:: Copyright (c) 2014, Andrew Tulloch++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.++Except as contained in this notice, the name(s) of the above copyright+holders shall not be used in advertising or otherwise to promote the+sale, use or other dealings in this Software without prior written+authorization.
+ Main.hs view
@@ -0,0 +1,13 @@+{-# LANGUAGE TypeOperators #-}+module Main where++import           Data.Array.Repa+import           DeepLearning.ConvNet+import           DeepLearning.Util++-- |Main+main :: IO ()+main = do+  (pvol, acts) <- withActivations (testNet testShape 2) (testInput testShape)+  print (computeS pvol :: Vol DIM1)+  print acts
+ Setup.hs view
@@ -0,0 +1,4 @@+import           Distribution.Simple++main :: IO ()+main = defaultMain
+ deeplearning-hs.cabal view
@@ -0,0 +1,63 @@+-- Initial deeplearning.cabal generated by cabal init.  For further+-- documentation, see http://haskell.org/cabal/users-guide/+++name:                deeplearning-hs+version:             0.1.0.0+description:         Implements type-safe deep neural networks+synopsis:            Deep Learning in Haskell+homepage:            https://github.com/ajtulloch/deeplearning-hs+license:             MIT+license-file:        LICENSE+author:              Andrew Tulloch+maintainer:          Andrew Tulloch <andrew+cabal@tullo.ch>+category:            Math+build-type:          Simple+cabal-version:       >=1.10+bug-reports:         https://github.com/ajtulloch/deeplearning-hs/issues+source-repository head+  type:      git+  location:  https://github.com/ajtulloch/deeplearning-hs.git++Library+  exposed-modules: DeepLearning.ConvNet, DeepLearning.Util+  default-language:    Haskell2010+  GHC-Options: -Wall+  build-depends:+        base >=4.6 && <4.7,+        accelerate,+        vector,+        repa,+        repa-algorithms,+        mtl++Test-suite deeplearning_test+  Main-Is: DeepLearning/ConvNetTest.hs+  Type: exitcode-stdio-1.0+  x-uses-tf: true+  default-language: Haskell2010+  build-depends:+        deeplearning-hs,+        base >=4.6 && <4.7,+        accelerate,+        vector,+        repa,+        repa-algorithms,+        mtl,+        QuickCheck,+        test-framework-quickcheck2,+        test-framework+  Ghc-Options:          -Wall++executable deeplearning_demonstration+  main-is: Main.hs+  default-language: Haskell2010+  GHC-Options:    -Wall+  build-depends:+        deeplearning-hs,+        base >=4.6 && <4.7,+        accelerate,+        vector,+        repa,+        repa-algorithms,+        mtl