My original intention was to use Zygote to achieve the gradient of gradients, but there were a lot of problems with twice automatic differentiation in reverse mode. So I used Zygote.hessian to achieve the mixing forward + reverse mode, and then some problems occurred. The following is my example
using GenericLinearAlgebra
using Zygote
function f(x)
A = reshape(sin.(collect(1:25)*x),5,5)
u, s,_= GenericLinearAlgebra.svd(A)
A = u *A *u
A = A / maximum(abs.(A))
return sum(A)
end
function test()
x0=0.5
@show gradient(f,x0)
@show hessian(f,x0)
end
test()
It give
gradient(f, x0) = (64.0,)
ERROR: LoadError: MethodError: convert(::Type{ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}}, ::ChainRulesCore.ZeroTangent) is ambiguous. Candidates:
convert(::Type{T}, x::ChainRulesCore.AbstractZero) where T<:Number in ChainRulesCore at ~\.julia\packages\ChainRulesCore\ctmSK\src\tangent_types\abstract_zero.jl:31
convert(::Type{ForwardDiff.Dual{T, V, N}}, x) where {T, V, N} in ForwardDiff at ~\.julia\packages\ForwardDiff\pDtsf\src\dual.jl:432
Possible fix, define
convert(::Type{ForwardDiff.Dual{T, V, N}}, ::ChainRulesCore.AbstractZero) where {T, V, N}
Stacktrace:
[1] fill!(dest::Matrix{ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}}, x::ChainRulesCore.ZeroTangent)
@ Base .\array.jl:351
[2] _setindex_zero(::Matrix{ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}}, ::ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}, ::Int64, ::Vararg{Int64})
@ ChainRules ~\.julia\packages\ChainRules\DUopG\src\rulesets\Base\indexing.jl:104
[3] ∇getindex(x::Matrix{ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}}, dy::ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}, inds::CartesianIndex{2})
@ ChainRules ~\.julia\packages\ChainRules\DUopG\src\rulesets\Base\indexing.jl:89
[4] (::ChainRules.var"#1564#1566"{Matrix{ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}}, ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}, Tuple{CartesianIndex{2}}})()
@ ChainRules ~\.julia\packages\ChainRules\DUopG\src\rulesets\Base\indexing.jl:74
[5] unthunk
@ ~\.julia\packages\ChainRulesCore\ctmSK\src\tangent_types\thunks.jl:199 [inlined]
[6] unthunk(x::ChainRulesCore.InplaceableThunk{ChainRulesCore.Thunk{ChainRules.var"#1564#1566"{Matrix{ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}}, ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}, Tuple{CartesianIndex{2}}}}, ChainRules.var"#1563#1565"{Matrix{ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}}, ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1}, Tuple{CartesianIndex{2}}}})
@ ChainRulesCore ~\.julia\packages\ChainRulesCore\ctmSK\src\tangent_types\thunks.jl:232
[7] wrap_chainrules_output
@ ~\.julia\packages\Zygote\xGkZ5\src\compiler\chainrules.jl:105 [inlined]
[8] map
@ .\tuple.jl:222 [inlined]
[9] wrap_chainrules_output
@ ~\.julia\packages\Zygote\xGkZ5\src\compiler\chainrules.jl:106 [inlined]
[10] ZBack
@ ~\.julia\packages\Zygote\xGkZ5\src\compiler\chainrules.jl:206 [inlined]
[11] Pullback
@ ~\Desktop\Ising_test\test.jl:8 [inlined]
[12] (::typeof(∂(f)))(Δ::ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1})
@ Zygote ~\.julia\packages\Zygote\xGkZ5\src\compiler\interface2.jl:0
[13] (::Zygote.var"#60#61"{typeof(∂(f))})(Δ::ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1})
@ Zygote ~\.julia\packages\Zygote\xGkZ5\src\compiler\interface.jl:45
[14] gradient(f::Function, args::ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1})
@ Zygote ~\.julia\packages\Zygote\xGkZ5\src\compiler\interface.jl:97
[15] (::Zygote.var"#104#105"{typeof(f)})(x::ForwardDiff.Dual{ForwardDiff.Tag{Zygote.var"#104#105"{typeof(f)}, Float64}, Float64, 1})
@ Zygote ~\.julia\packages\Zygote\xGkZ5\src\lib\grad.jl:66
[16] derivative(f::Zygote.var"#104#105"{typeof(f)}, x::Float64)
@ ForwardDiff ~\.julia\packages\ForwardDiff\pDtsf\src\derivative.jl:14
[17] hessian_dual(f::Function, x::Float64)
@ Zygote ~\.julia\packages\Zygote\xGkZ5\src\lib\grad.jl:66
[18] hessian(f::Function, x::Float64)
@ Zygote ~\.julia\packages\Zygote\xGkZ5\src\lib\grad.jl:62
[19] macro expansion
@ .\show.jl:1047 [inlined]
[20] test()
@ Main ~\Desktop\Ising_test\test.jl:14
[21] top-level scope
@ ~\Desktop\Ising_test\test.jl:20
in expression starting at ~\Desktop\Ising_test\test.jl:20
It seems that there is a problem when calling ForwardDiff, but I don’t know how to fix it