Hello.
I understand from the documentation of ForwardDiff.jl that the package uses a Tag type parameter to avoid something called ‘perturbation confusion’:
http://www.juliadiff.org/ForwardDiff.jl/stable/dev/how_it_works.html
From experimenting I have noticed that the Tag parameter is somehow used to identify the function where the dual values are used.
Suppose I have roughly a function like this:
function construct_objective(model::SomeModel, data::SomeData, params::Parameter{Float64})
params_dual = ForwardDiff.Dual{*what goes here?*}(params);
function obj!(x::AbstractArray{T, 1}) where T <: Real
set_parameter_values!(x, params_dual, Val(:estimated)); # Set estimated parameters to match x.
compute_objective_value(model, y, data, params_dual);
end
Optim.TwiceDifferentiable(obj!, construct_array(params_dual); autodiff = :forward);
end
which creates an objective I can optimize using Optim.jl. Here the argument ‘params’ contains model parameters, some of which I want to estimate.
On the line where I convert my parameters to Parameter{Dual{…}}, is it possible for me to specify the Tag parameter myself and not internally by ForwardDiff?
There is no explanation for this in the documentation for ForwardDiff.jl.
The reason I would like to specify it myself (and have everything working correctly), is that then I could specify at run time which of the parameters in ‘params’ are estimated and which are left at fixed values.
My idea is that I would like to write code like this:
par = get_initial_params(...); # Get initial parameter values for all parameters (fixed and estimated).
fixed_names = (:a, :b); # Specify which parameters will be left fixed i.e optimization won't modify them.
set_fixed!(par, fixed_names);
obj = construct_objective(model, data, par); # Construct objective estimating only estimated parameters, and compatible with ForwardDiff.
res = Optim.optimize(obj, construct_array(par), ...); # Optimise.
Note that without autodifferentiation the above can be made to work by removing the ‘params_dual = …’ line from the code snippet and changing ‘params_dual’ to ‘params’.
All help is greatly appreciated.
Edit: added backticks for readability, thanks @Tamas_Papp