Skip to content
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

error when trying to futher differentiate using Zygote #176

Open
btx0424 opened this issue Jun 15, 2021 · 2 comments
Open

error when trying to futher differentiate using Zygote #176

btx0424 opened this issue Jun 15, 2021 · 2 comments

Comments

@btx0424
Copy link

btx0424 commented Jun 15, 2021

Summary: it seems that the finite difference can't be further differentiated by Zygote
Example: If I do

dif(x) = central_fdm(2, 1)(sin, x)

and then call

dif'(0)

I get the following error message:

setindex!(::StaticArrays.SVector{3, Float64}, value, ::Int) is not defined.

error(::String)@error.jl:33
setindex!(::StaticArrays.SVector{3, Float64}, ::Float64, ::Int64)@indexing.jl:3
#637@array.jl:318[inlined]
#2710#back@adjoint.jl:59[inlined]
Pullback@methods.jl:385[inlined]
(::typeof((_estimate_magnitudes)))(::Tuple{Float64, Nothing})@interface2.jl:0
Pullback@methods.jl:365[inlined]
(::typeof((estimate_step)))(::Tuple{Float64, Nothing})@interface2.jl:0
Pullback@methods.jl:193[inlined]
(::typeof((λ)))(::Float64)@interface2.jl:0
Pullback@Other: 1[inlined]
(::typeof((dif)))(::Float64)@interface2.jl:0
(::Zygote.var"#41#42"{typeof((dif))})(::Float64)@interface.jl:41
gradient(::Function, ::Int64)@interface.jl:59
(::Zygote.var"#43#44"{typeof(Main.workspace50.dif)})(::Int64)@interface.jl:62
top-level scope@Local: 1[inlined]

The actual use case is that I'm trying to train a NN where I need to compute the gradient of its parameters w.r.t a loss function that involves finite differences given by central_fdm. Is this possible?

@simeonschaub
Copy link
Member

Can you just use it the other way, i.e. FiniteDifferences over Zygote instead of Zygote over FiniteDifferences? You could actually define a custom adjoint for FiniteDifferenceMethod which does this automatically for cases like this.

@wesselb
Copy link
Member

wesselb commented Jun 15, 2021

Step size adaptation appears to be not working well with Zygote. Unfortunately, I'm not familiar enough with the inner workings of Zygote to see what precisely breaks down. Perhaps @willtebbutt or @oxinabox could provide some insight. From the error message, if appears that a pullback attempts to modify a StaticArray in-place, which won't work.

Once you turn off step size adaptation, things seem to work:

julia> fdm = central_fdm(5, 1; adapt=0);

julia> cos_(x) = fdm(sin, x)
cos_ (generic function with 1 method)

julia> cos_'(1)
-0.8414709848079269

julia> -sin(1)
-0.8414709848078965

I would be careful with AD-ing through finite difference estimates, though. I second @simeonschaub's suggestion of taking finite differences of gradients computed by AD.

EDIT: If we wanted to make this work, we could do something like

using FiniteDifferences, Zygote

function (m::FiniteDifferences.AdaptedFiniteDifferenceMethod)(f::TF, x::Real) where TF<:Function
    x = float(x)  # Assume that converting to float is desired, if it isn't already.
    step = Zygote.dropgrad(first(FiniteDifferences.estimate_step(m, f, x)))
    return m(f, x, step)
end

Then

julia> fdm = central_fdm(5, 1; adapt=1);

julia> cos_(x) = fdm(sin, x)
cos_ (generic function with 1 method)

julia> cos_'(1)
-0.8414709848078701

julia> -sin(1)
-0.8414709848078965

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants