Safe Haskell | None |
---|---|
Language | Haskell98 |
Main module of the stochastic gradient descent (SGD) library.
SGD is a method for optimizing a global objective function defined as a sum
of smaller, differentiable functions. The individual component functions
share the same set of parameters, represented by the ParamSet
class.
To perform SGD, the gradients of the individual functions need to be determined. This can be done manually or automatically, using one of the automatic differentiation libraries (ad, backprop) available in Haskell.
For instance, let's say we have a list of functions defined as:
funs = [\x -> 0.3*x^2, \x -> -2*x, const 3, sin]
The global objective is then defined as:
objective x = sum $ map ($x) funs
We can manually determine the individual derivatives:
derivs = [\x -> 0.6*x, const (-2), const 0, cos]
or use an automatic differentiation library, for instance:
import qualified Numeric.AD as AD derivs = map (\k -> AD.diff (funs !! k)) [0..length funs-1]
Finally, run
allows to approach a (potentially local) minimum of the
global objective function:
>>>
run (momentum def id) (take 10000 $ cycle derivs) 0.0
4.180177042912455
where:
Synopsis
- momentum :: (Monad m, ParamSet p) => Config -> (e -> p -> p) -> SGD m e p
- adaDelta :: (Monad m, ParamSet p) => Config -> (e -> p -> p) -> SGD m e p
- adam :: (Monad m, ParamSet p) => Config -> (e -> p -> p) -> SGD m e p
- run :: ParamSet p => SGD Identity e p -> [e] -> p -> p
- data Config = Config {
- iterNum :: Natural
- batchRandom :: Bool
- reportEvery :: Double
- runIO :: ParamSet p => Config -> SGD IO e p -> (e -> p -> Double) -> DataSet e -> p -> IO p
- pipeSeq :: DataSet e -> Producer e IO ()
- pipeRan :: DataSet e -> Producer e IO ()
- result :: Monad m => p -> Producer p m () -> m p
- every :: Monad m => Int -> (p -> m ()) -> Pipe p p m x
- def :: Default a => a
SGD variants
:: (Monad m, ParamSet p) | |
=> Config | Momentum configuration |
-> (e -> p -> p) | Gradient on a training element |
-> SGD m e p |
Stochastic gradient descent with momentum. See Numeric.SGD.Momentum for more information.
:: (Monad m, ParamSet p) | |
=> Config | AdaDelta configuration |
-> (e -> p -> p) | Gradient on a training element |
-> SGD m e p |
Perform gradient descent using the AdaDelta algorithm. See Numeric.SGD.AdaDelta for more information.
:: (Monad m, ParamSet p) | |
=> Config | Adam configuration |
-> (e -> p -> p) | Gradient on a training element |
-> SGD m e p |
Perform gradient descent using the Adam algorithm. See Numeric.SGD.Adam for more information.
Pure SGD
:: ParamSet p | |
=> SGD Identity e p | Selected SGD method |
-> [e] | Training data stream |
-> p | Initial parameters |
-> p |
Traverse all the elements in the training data stream in one pass, calculate the subsequent gradients, and apply them progressively starting from the initial parameter values.
Consider using runIO
if your training dataset is large.
IO-based SGD
High-level IO-based SGD configuration
Config | |
|
Instances
Eq Config Source # | |
Ord Config Source # | |
Show Config Source # | |
Generic Config Source # | |
Default Config Source # | |
Defined in Numeric.SGD | |
type Rep Config Source # | |
Defined in Numeric.SGD type Rep Config = D1 (MetaData "Config" "Numeric.SGD" "sgd-0.6.0.0-JHbBPHWTGdxDz4NNNmWXxw" False) (C1 (MetaCons "Config" PrefixI True) (S1 (MetaSel (Just "iterNum") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Natural) :*: (S1 (MetaSel (Just "batchRandom") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Bool) :*: S1 (MetaSel (Just "reportEvery") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Double)))) |
:: ParamSet p | |
=> Config | SGD configuration |
-> SGD IO e p | Selected SGD method |
-> (e -> p -> Double) | Value of the objective function on a sample element (needed for model quality reporting) |
-> DataSet e | Training dataset |
-> p | Initial parameter values |
-> IO p |
Perform SGD in the IO monad, regularly reporting the value of the objective function on the entire dataset. A higher-level wrapper which should be convenient to use when the training dataset is large.
An alternative is to use the simpler function run
, or to build a custom
SGD pipeline based on lower-level combinators (pipeSeq
, adaDelta
,
every
, result
, etc.).
Combinators
:: Monad m | |
=> p | Default value (in case the stream is empty) |
-> Producer p m () | Stream of parameter sets |
-> m p |
Extract the result of the SGD calculation (the last parameter set flowing downstream).
every :: Monad m => Int -> (p -> m ()) -> Pipe p p m x Source #
Apply the given function every k
param sets flowing downstream.