module Synapse.NN.LearningRates
(
LearningRateFn
, LearningRate (LearningRate, unLearningRate)
, exponentialDecay
, inverseTimeDecay
, polynomialDecay
, cosineDecay
, piecewiseConstantDecay
) where
type LearningRateFn a = Int -> a
newtype LearningRate a = LearningRate
{ forall a. LearningRate a -> LearningRateFn a
unLearningRate :: LearningRateFn a
}
exponentialDecay :: Num a => a -> Int -> a -> LearningRateFn a
exponentialDecay :: forall a. Num a => a -> Int -> a -> LearningRateFn a
exponentialDecay a
initial Int
steps a
rate Int
step = a
initial a -> a -> a
forall a. Num a => a -> a -> a
* a
rate a -> Int -> a
forall a b. (Num a, Integral b) => a -> b -> a
^ (Int
step Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
steps)
inverseTimeDecay :: Fractional a => a -> Int -> a -> LearningRateFn a
inverseTimeDecay :: forall a. Fractional a => a -> Int -> a -> LearningRateFn a
inverseTimeDecay a
initial Int
steps a
rate Int
step = a
initial a -> a -> a
forall a. Fractional a => a -> a -> a
/ (a
1.0 a -> a -> a
forall a. Num a => a -> a -> a
+ a
rate a -> a -> a
forall a. Num a => a -> a -> a
* Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
step Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
steps))
polynomialDecay :: Floating a => a -> Int -> a -> a -> LearningRateFn a
polynomialDecay :: forall a. Floating a => a -> Int -> a -> a -> LearningRateFn a
polynomialDecay a
initial Int
steps a
power a
end Int
step
| Int
step Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
steps = a
initial a -> a -> a
forall a. Num a => a -> a -> a
* Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
step Int
steps Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
steps) a -> a -> a
forall a. Floating a => a -> a -> a
** a
power
| Bool
otherwise = a
end
cosineDecay :: Floating a => a -> Int -> a -> Maybe (Int, a) -> LearningRateFn a
cosineDecay :: forall a.
Floating a =>
a -> Int -> a -> Maybe (Int, a) -> LearningRateFn a
cosineDecay a
initial Int
steps a
alpha Maybe (Int, a)
warmup Int
step =
((a
1.0 a -> a -> a
forall a. Num a => a -> a -> a
- a
alpha) a -> a -> a
forall a. Num a => a -> a -> a
* (a
0.5 a -> a -> a
forall a. Num a => a -> a -> a
* (a
1.0 a -> a -> a
forall a. Num a => a -> a -> a
+ a -> a
forall a. Floating a => a -> a
cos (a
forall a. Floating a => a
pi a -> a -> a
forall a. Num a => a -> a -> a
* Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
step Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
steps)))) a -> a -> a
forall a. Num a => a -> a -> a
+ a
alpha) a -> a -> a
forall a. Num a => a -> a -> a
*
case Maybe (Int, a)
warmup of
Maybe (Int, a)
Nothing -> a
initial
Just (Int
warmupSteps, a
warmupLR) -> if Int
step Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
warmupSteps
then (a
warmupLR a -> a -> a
forall a. Num a => a -> a -> a
- a
initial) a -> a -> a
forall a. Num a => a -> a -> a
* Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
step Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
warmupSteps)
else a
warmupLR
piecewiseConstantDecay :: [(Int, a)] -> a -> LearningRateFn a
piecewiseConstantDecay :: forall a. [(Int, a)] -> a -> LearningRateFn a
piecewiseConstantDecay [] a
lastRate Int
_ = a
lastRate
piecewiseConstantDecay ((Int
stepBound, a
rateValue):[(Int, a)]
xs) a
lastRate Int
step
| Int
step Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
stepBound = a
rateValue
| Bool
otherwise = [(Int, a)] -> a -> LearningRateFn a
forall a. [(Int, a)] -> a -> LearningRateFn a
piecewiseConstantDecay [(Int, a)]
xs a
lastRate Int
step