 # This is how to call finite difference gradcheck on a model

I learned of the undocumented `gradcheck` function in a recent question, but it was not clear how to apply it to a model (rather than an array). It requires the use of Flux.destructure., as mentioned in the recent pull request 1168.

Here is a self contained example for other beginners. It is based on these links,
https://github.com/FluxML/Flux.jl/issues/1168
https://github.com/FluxML/Zygote.jl/pull/464

``````using Flux
using Random

#----------------------------------------------------------------

struct Mymodel
W
b
end

function Mymodel(in::Integer, out::Integer)
return Mymodel(randn(out, in), randn(out))
end

Flux.@functor Mymodel

(m::Mymodel)(x) = m.W * x .+ m.b

#----------------------------------------------------------------

using FiniteDifferences

# from  https://github.com/FluxML/Zygote.jl/pull/464
end

for (x, Δ) in zip(xs, grads), i in 1:length(x)
δ = sqrt(eps())
tmp = x[i]
x[i] = tmp - δ/2
y1 = f(xs...)
x[i] = tmp + δ/2
y2 = f(xs...)
x[i] = tmp
Δ[i] = (y2-y1)/δ
end
end

function loss_restructure(θvec, re,  loss, x, y)
loss(x, y, re(θvec))
end

θvec, re = Flux.destructure(model)
loss_restructure(θvec, re, loss, lossargs...)
end
loss_restructure(θvec, re, loss, lossargs...)
end
@show typeof(g1) g1
@show typeof(g2) g2
@show maximum(abs, g1 .- g2)
end

#----------------------------------------------------------------

function loss(x,y, model=model)
ŷ = model(x)
#@show y ŷ
return Flux.mse(y,ŷ)
end

# example inputs
X = [1.,2.]
Y = [3.]
model = Mymodel(2,1)

# test evaluage model and loss
model(X)
loss(X,Y)