sgd 0.1.0 → 0.2.0
raw patch · 4 files changed
+40/−6 lines, 4 files
Files
- Numeric/SGD.hs +1/−2
- Numeric/SGD/Grad.hs +21/−2
- Numeric/SGD/LogSigned.hs +17/−1
- sgd.cabal +1/−1
Numeric/SGD.hs view
@@ -19,7 +19,6 @@ , module Numeric.SGD.Grad ) where -import Control.Applicative (Applicative) import Control.Monad (forM_) import Control.Monad.ST (ST, runST) import qualified System.Random as R@@ -84,7 +83,7 @@ -> (Para -> x -> Grad) -> Dataset x -> Para -> ST s Para #-} sgdM- :: (Applicative m, Prim.PrimMonad m)+ :: (Prim.PrimMonad m) => SgdArgs -- ^ SGD parameter values -> (Para -> Int -> m ()) -- ^ Notification run every update -> (Para -> x -> Grad) -- ^ Gradient for dataset element
Numeric/SGD/Grad.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+ -- | A gradient is represented by an IntMap from gradient indices -- to values. Elements with no associated values in the gradient -- are assumed to have a 0 value assigned. Such elements are@@ -34,15 +36,28 @@ -- components in the gradient. type Grad = M.IntMap LogSigned +{-# INLINE insertWith #-}+insertWith :: (a -> a -> a) -> M.Key -> a -> M.IntMap a -> M.IntMap a+#if MIN_VERSION_containers(0,4,1)+insertWith = M.insertWith'+#else+insertWith f k x m = case M.lookup k m of+ Just y ->+ let x' = f x y+ in x' `seq` M.insert k x' m+ Nothing -> x `seq` M.insert k x m+#endif+ -- | Add normal-domain double to the gradient at the given position. {-# INLINE add #-} add :: Grad -> Int -> Double -> Grad-add grad i y = M.insertWith' (+) i (logSigned y) grad +add grad i y = insertWith (+) i (logSigned y) grad + -- | Add log-domain, singed number to the gradient at the given position. {-# INLINE addL #-} addL :: Grad -> Int -> LogSigned -> Grad-addL grad i y = M.insertWith' (+) i y grad +addL grad i y = insertWith (+) i y grad -- | Construct gradient from a list of (index, value) pairs. -- All values from the list are added at respective gradient@@ -78,6 +93,7 @@ -- Experimental version. parUnions :: [Grad] -> Grad parUnions [] = error "parUnions: empty list"+#if MIN_VERSION_containers(0,4,2) parUnions xs = runPar (parUnionsP xs) -- | Parallel unoins in the Par monad.@@ -94,3 +110,6 @@ split (x:y:rest) = let (xs, ys) = split rest in (x:xs, y:ys)+#else+parUnions xs = M.unions xs+#endif
Numeric/SGD/LogSigned.hs view
@@ -9,9 +9,11 @@ , fromPos , fromNeg , toNorm+, toLogFloat ) where import qualified Data.Number.LogFloat as L+import Data.Function (on) import Control.Monad.Par (NFData) instance NFData L.LogFloat@@ -20,8 +22,14 @@ data LogSigned = LogSigned { pos :: {-# UNPACK #-} !L.LogFloat -- ^ Positive component , neg :: {-# UNPACK #-} !L.LogFloat -- ^ Negative component- }+ } deriving Show +instance Eq LogSigned where+ (==) = (==) `on` toLogFloat++instance Ord LogSigned where+ compare = compare `on` toLogFloat+ -- All fields are strict and unpacked. instance NFData LogSigned @@ -47,6 +55,14 @@ {-# INLINE toNorm #-} toNorm :: LogSigned -> Double toNorm (LogSigned x y) = L.fromLogFloat x - L.fromLogFloat y++-- | Change the 'LogSigned' to either negative 'Left' 'L.LogFloat'+-- or positive 'Right' 'L.LogFloat'.+toLogFloat :: LogSigned -> Either L.LogFloat L.LogFloat+toLogFloat x = case signum x of+ -1 -> Left $ neg x - pos x+ 1 -> Right $ pos x - neg x+ _ -> Right $ L.logFloat (0 :: Double) instance Num LogSigned where LogSigned x y + LogSigned x' y' =
sgd.cabal view
@@ -1,5 +1,5 @@ name: sgd-version: 0.1.0+version: 0.2.0 synopsis: Stochastic gradient descent description: Implementation of a Stochastic Gradient Descent optimization method.