Standard library · Machine learning

optim

Neural network optimisers: SGD, Adam, RMSProp and learning rate schedules.

import optim
On this page
  1. Types
  2. Functions

An optimiser updates the model parameters from the gradients. A training loop always has this shape: reset the autograd tape, zero the gradients of the ParamStore, work out the loss, call Backward, and then the step of the optimiser.

The ...LR functions work out the learning rate for a given step; put it in the lr field of the optimiser before step.

Types

Adam

struct Adam
The Adam optimiser; a good default for most networks.
NameTypeDescription
lrf64 = 0.001The learning rate.
beta1f64 = 0.9The coefficient of the gradient average.
beta2f64 = 0.999The coefficient of the squared gradient average.
epsf64 = 1e-08A small number that keeps a division by zero from happening.
weight_decayf64 = 0Weight decay.
decoupledbool = falseApply the weight decay apart from the gradient, meaning AdamW.
optim-Train.salam
import optim
import nn
import autograd
import tensor

func train(method: int, steps: int, target &: tensor.Tensor): f64:
    mut store := nn.ParamStore {}
    handle := store.add("w", tensor.Zeros1(4))
    mut adam := optim.Adam { lr = 0.1 }
    mut adamw := optim.NewAdamW(0.1, 0.01)
    mut rms := optim.RMSProp { lr = 0.05 }
    mut sgd := optim.SGD { lr = 0.05, momentum = 0.9 }
    mut tape := autograd.NewTape(1)
    repeat steps:
        tape.reset()
        store.zero_grad()
        w := nn.Bind(tape, store, handle)
        t := autograd.Input(tape, target)
        loss := autograd.Sum(tape, autograd.Square(tape, autograd.Sub(tape, w, t)))
        autograd.Backward(tape, loss)
        _ := optim.ClipGradNorm(store, 10.0)
        optim.ClipGradValue(store, 5.0)
        if method == 0:
            adam.step(store)
        else method == 1:
            adamw.step(store)
        else method == 2:
            rms.step(store)
        else:
            sgd.step(store)
        end
    end
    mut p := store.at(handle)
    result := p.value.at(3)
    tape.free()
    adam.free()
    adamw.free()
    rms.free()
    sgd.free()
    store.free()
    ret result
end

func main:
    mut target := tensor.Arange(4)
    each method in [0, 1, 2, 3]:
        rounded := (train(method, 400, target) * 100.0 + 0.5) as int
        println method, rounded
    end
    tensor.Free(target)
    println optim.StepLR(1.0, 25, 10, 0.5), optim.CosineLR(1.0, 50, 100, 0.0), optim.WarmupCosine(1.0, 0, 10, 110, 0.0)
end
Output0 300 1 299 2 300 3 300 0.25 0.5 0.1

step

func step(ps &: nn.ParamStore)
One update step.

The example for this item is shown with the ones above: optim-Train.salam

free

func free()
Frees the internal state.

The example for this item is shown with the ones above: optim-Train.salam

RMSProp

struct RMSProp
The RMSProp optimiser.
NameTypeDescription
lrf64 = 0.01The learning rate.
alphaf64 = 0.99The coefficient of the squared gradient average.
epsf64 = 1e-08A small number that keeps a division by zero from happening.
weight_decayf64 = 0Weight decay.

The example for this item is shown with the ones above: optim-Train.salam

step

func step(ps &: nn.ParamStore)
One update step.

The example for this item is shown with the ones above: optim-Train.salam

free

func free()
Frees the internal state.

The example for this item is shown with the ones above: optim-Train.salam

SGD

struct SGD
Stochastic gradient descent, with optional momentum and Nesterov.
NameTypeDescription
lrf64 = 0.01The learning rate.
momentumf64 = 0The momentum; zero means none.
weight_decayf64 = 0Weight decay, meaning an L2 penalty.
nesterovbool = falseNesterov momentum.

The example for this item is shown with the ones above: optim-Train.salam

step

func step(ps &: nn.ParamStore)
One update step over every parameter in the store, from the current gradients.

The example for this item is shown with the ones above: optim-Train.salam

free

func free()
Frees the internal state.

The example for this item is shown with the ones above: optim-Train.salam

Functions

NewAdamW

func NewAdamW(lr: f64, weight_decay: f64): Adam
Adam with decoupled weight decay, meaning AdamW.

The example for this item is shown with the ones above: optim-Train.salam

ClipGradNorm

func ClipGradNorm(ps &: nn.ParamStore, max_norm: f64): f64
Shrinks the gradients so their total norm does not pass the limit, and returns the norm before clipping; it keeps gradients from exploding.

The example for this item is shown with the ones above: optim-Train.salam

ClipGradValue

func ClipGradValue(ps &: nn.ParamStore, limit: f64)
Holds every gradient within minus the limit to the limit.

The example for this item is shown with the ones above: optim-Train.salam

StepLR

func StepLR(base: f64, step: i64, every: i64, gamma: f64): f64
A step learning rate: every so many steps it is multiplied by gamma.

The example for this item is shown with the ones above: optim-Train.salam

CosineLR

func CosineLR(base: f64, step: i64, total: i64, min_lr: f64): f64
A cosine learning rate: it falls from the base rate to the minimum along half a cosine wave.

The example for this item is shown with the ones above: optim-Train.salam

WarmupCosine

func WarmupCosine(base: f64, step: i64, warmup: i64, total: i64, min_lr: f64): f64
A linear warmup over the first steps, then a cosine decay; the usual choice for training transformers.

The example for this item is shown with the ones above: optim-Train.salam