FluxML / FluxML/Optimisers.jl

`destructure` doesn't work correctly with certain functors

Open
#62 3 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Julia
Stars
96
Forks
30
PR merge metrics
No merged PRs in 30d

Description

```julia
using Flux
using Functors
using Optimisers

struct Custom
abc::Tuple
end
Functors.@functor Custom (abc,)

function (f::Custom)(x)
x .* f.abc[1] .+ f.abc[2]
end

function Custom(;dim::Int)
abc = (randn(Float32, dim), randn(Float32, dim))
return Custom(abc)
end

model = Flux.Chain(Dense(4, 16), Custom(;dim=16), Dense(16, 4))
p, re = Optimisers.destructure(model)
re(p)(randn(Float32, 4, 1))
```

leads to

```julia
ERROR: LoadError: type Tuple has no field layers
Stacktrace:
[1] getproperty
@ ./Base.jl:42 [inlined]
[2] functor(#unused#::Type{Chain{Tuple{Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Custom, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}}}}, c::Tuple{NamedTuple{(:weight, :bias, :σ), Tuple{Int64, Int64, Tuple{}}}, NamedTuple{(:abc,), Tuple{Tuple{Int64, Int64}}}, NamedTuple{(:weight, :bias, :σ), Tuple{Int64, Int64, Tuple{}}}})
@ Flux ~/.julia/packages/Flux/qAdFM/src/layers/basic.jl:44
[3] _trainable_biwalk(f::Function, x::Chain{Tuple{Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Custom, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}}}, aux::Tuple{NamedTuple{(:weight, :bias, :σ), Tuple{Int64, Int64, Tuple{}}}, NamedTuple{(:abc,), Tuple{Tuple{Int64, Int64}}}, NamedTuple{(:weight, :bias, :σ), Tuple{Int64, Int64, Tuple{}}}})
@ Optimisers ~/.julia/packages/Optimisers/UAVzc/src/destructure.jl:94
[4] #fmap#30
@ ~/.julia/packages/Functors/qBIlC/src/functor.jl:78 [inlined]
[5] _rebuild(x::Chain{Tuple{Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Custom, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}}}, off::Tuple{NamedTuple{(:weight, :bias, :σ), Tuple{Int64, Int64, Tuple{}}}, NamedTuple{(:abc,), Tuple{Tuple{Int64, Int64}}}, NamedTuple{(:weight, :bias, :σ), Tuple{Int64, Int64, Tuple{}}}}, flat::Vector{Float32}, len::Int64; walk::Function, kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ Optimisers ~/.julia/packages/Optimisers/UAVzc/src/destructure.jl:83
[6] _rebuild
@ ~/.julia/packages/Optimisers/UAVzc/src/destructure.jl:82 [inlined]
[7] (::Optimisers.Restructure{Chain{Tuple{Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}, Custom, Dense{typeof(identity), Matrix{Float32}, Vector{Float32}}}}, Tuple{NamedTuple{(:weight, :bias, :σ), Tuple{Int64, Int64, Tuple{}}}, NamedTuple{(:abc,), Tuple{Tuple{Int64, Int64}}}, NamedTuple{(:weight, :bias, :σ), Tuple{Int64, Int64, Tuple{}}}}})(flat::Vector{Float32})
@ Optimisers ~/.julia/packages/Optimisers/UAVzc/src/destructure.jl:51

```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the _rebuild and _trainable_biwalk entry points in src/destructure.jl, then run the Julia reproducer from the issue with Flux, Functors, and Optimisers. Trace how the tuple-shaped Chain auxiliary data is rebuilt; done means re(p) completes and the model runs on the provided input without the Tuple field error.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
machine-learning
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.