JuliaAPlavin / AccessibleOptimization.jl

MIT License
3 stars 0 forks source link
fitting optimization statistics

AccessibleOptimization.jl

Combining Accessors.jl + Optimization.jl to enable function optimization with arbitrary structs. Vary struct parameters, combinations and transformations of them. Uniform and composable, zero overhead.

Defining features of AccessibleOptimization:

Usage

Suppose you want to fit a model to data. Here, our model is a sum of squared exponentials.

First, define your model and a way to evaluate it. Regular Julia code, no special types or functions. This is not Accessors/Optimization specific at all, you may have model definitions already!

struct ExpModel{A,B}
    scale::A
    shift::B
end

struct SumModel{T <: Tuple}
    comps::T
end

(m::ExpModel)(x) = m.scale * exp(-(x - m.shift)^2)
(m::SumModel)(x) = sum(c -> c(x), m.comps)

loss(m, data) = @p data |> sum(abs2(_.y - m(_.x)))

Then, load AccessibleOptimization, define optimization parameters, and perform optimization:

using AccessibleOptimization

# which parameters to optimize, what are their bouds?
vars = OptArgs(
    (@o _.comps[∗].shift) => 0..10.,  # shifts of both components: values from 0..10
    (@o log10(_.comps[∗].scale)) => -1..1,  # component scales: positive-only (using log10 transformation), from 10^-1 to 10^1
)
# create and solve the optimization problem, interface very similar to Optimization.jl
ops = OptProblemSpec(Base.Fix2(loss, data), mod0, vars)
sol = solve(ops, ECA(), maxiters=300)
sol.uobj::SumModel  # the optimal model

We use Accessors.jl and AccessorsExtra.jl optics to specify parameters to vary during optimization. Basic @optic syntax demonstrated in the above example includes property and index access (_.prop, _[1]) and selecting all elements of a collection with _[∗] (type with \ast<tab>). Refer to the Accessors[Extra] documentation for more details.

See a Pluto notebook with a walkthrough, more examples and explanations.

Related packages

AccessibleOptimization gains its composability and generality powers (and half its name!) from Accessors and AccessorsExtra packages.

The optimization part is directly delegated to Optimization. Other backends are possible, but best to add them as methods to Optimization proper and use from AccessibleOptimization.

These packages have generally similar goals, but neither provides all features AccessibleOptimization or Accessors do: