MLP components
Layers
Dense layer can be used to construct MLP. Its parameters are handled explicitly, meaning after instantiation d = Dense(1=>2), parameters are obtained with θ = NerfUtils.init(d, Backend). Where you pass one of the supported Backends to initialize the model directly on the device.
You can then pass inputs to the layer y = d(x, θ).
Chain can be used to stack multiple dense layers. Its parameters are handled in the same manner:
c = Chain(Dense(1=>2), Dense(2=>1))
θ = NerfUtils.init(c, Backend)
x = ...
y = c(x, θ)NerfUtils.Dense — Typefunction Dense(
mapping::Pair{Int64, Int64}, activation::F = identity,
) where FRegular dense layer with activation.
NerfUtils.init — Methodinit(d::Dense, kab)Create parameters for the Dense layer on the given backend kab.
NerfUtils.reset! — Methodreset!(::Dense, θ)Reinitialize parameters θ in-place.
NerfUtils.Chain — TypeChain(layers...)Sequentially chain multiple layers.
NerfUtils.init — Methodinit(c::Chain, kab)Create parameters for the Chain on the given backend kab.
NerfUtils.reset! — Methodreset!(c::Chain, θ)Reinitialize chain parameters in-place.
Optimizer
There's only one optimizer available - Adam. It handles parameters that are either tuples (or named tuples) or plain arrays.
c = Chain(Dense(1 => 2), Dense(2 => 1))
θ = NerfUtils.init(c, Backend)
opt = Adam(Backend, θ; lr=1f-3)After computing gradients ∇, applying the update rule can be done with NerfUtils.step! function.
NerfUtils.step!(opt, θ, ∇; dispose=true) # Free immediately gradient memory afterwards.
NerfUtils.step!(opt, θ, ∇; dispose=false) # Do not free.NerfUtils.Adam — TypeAdam(kab, θ; kwargs...)Adam optimizer.
θ must be either plain array or a tuple (or named tuple).
NerfUtils.reset! — Methodreset!(opt::Adam)Reset the optimizer state.
NerfUtils.step! — Methodstep!(opt::Adam, θ, ∇; dispose::Bool)Apply update rule to parameters θ with gradients ∇.
Arguments:
dispose::Bool: Free memory taken by gradients∇after update.