-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document custom rrule trick for ComponentArray constructor #67
Comments
try defining a function like https://github.com/mohamed82008/DifferentiableFactorizations.jl/blob/main/src/DifferentiableFactorizations.jl#L68 to workaround the ComponentArrays issue |
@mohamed82008 can you explain why this works? it might be a good idea to document it |
I have an rrule defined for it. |
@mohamed82008 Did I do something wrong...? using ImplicitDifferentiation
using Flux
using Convex, ECOS
using ComponentArrays
using Random
Random.seed!(2024)
i_max = 10
n = 3
m = 2
model = Chain(
Dense(3, 64, Flux.leakyrelu),
Dense(64, i_max*(m+1)),
)
u_min = -2*ones(m)
u_max = +2*ones(m)
function minimise_logsumexp(θ; T, u_min, u_max, initial_guess, solver=() -> ECOS.Optimizer())
# A = θ[:, 1:end-1]
# B = θ[:, end]
(; A, B) = θ
m = size(A)[2]
u = Convex.Variable(m)
if initial_guess != nothing
u.value = initial_guess
end
obj = T * Convex.logsumexp((1/T)*(A*u + B))
prob = Convex.minimize(obj)
prob.constraints += [u >= u_min]
prob.constraints += [u <= u_max]
solve!(prob, solver(), silent_solver=true, verbose=false)
minimiser = typeof(u.value) <: Number ? [u.value] : u.value[:] # to make it a vector
return minimiser
end
function forward_cstr_optim(θ; kwargs...)
u = minimise_logsumexp(θ; kwargs...)
z = 0
return u, z
end
function proj_hypercube(u; u_min, u_max)
return max.(u_min, min.(u_max, u))
end
function conditions_cstr_optim(θ, u, z; kwargs...)
(; A, B) = θ
# A = θ[:, 1:end-1]
# B = θ[:, end]
∇₂f = A' * Flux.softmax(A*u+B)
η = 0.1
return u .- proj_hypercube(u .- η .* ∇₂f; kwargs...)
end
function implicit_cstr_optim_func(θ; T, u_min, u_max, initial_guess, solver)
tmp = ImplicitFunction(
θ -> forward_cstr_optim(θ; T, u_min, u_max, initial_guess, solver),
(θ, u, z) -> conditions_cstr_optim(θ, u, z; u_min, u_max),
)
tmp(θ)[1]
end
x = 100*(2*rand(n) .- 1)
val, grads = Flux.withgradient(model) do _model
AB = reshape(_model(x), i_max, m+1)
A = AB[:, 1:m]
B = AB[:, m+1]
θ = ComponentVector(; A=A, B=B)
# θ = reshape(_model(x), i_max, m+1)
u_star = implicit_cstr_optim_func(θ; T=1, u_min=-ones(m), u_max=+ones(m), initial_guess=nothing, solver=() -> ECOS.Optimizer())
sum(u_star)
end |
I can't seem to find exactly what you changed, but you still have the constructor
|
@gdalle Ah, I see. Thank you for your explanation! |
Fixed by #100 |
Regarding #23, I was trying to re-implement this
in Julia.
I found that the use of ComponentArrays may not work properly with Zygote when the optimization parameters are given from another source (here, a neural network) as the following (with
v0.5.0-DEV
).I think this is related to jonniedie/ComponentArrays.jl#176.
Therefore, it may be better to clarify the limitation of ComponentArrays for multiple arguments cases (or, just avoid this for now).
Case 1: with ComponentArrays (not working)
Code
Result
Case 2: without ComponentArrays (working)
Code
Result
The text was updated successfully, but these errors were encountered: