Flux.jl icon indicating copy to clipboard operation
Flux.jl copied to clipboard

Add a macro to opt-in to fancy printing, and to everything else

Open mcabbott opened this issue 3 years ago • 8 comments

Originally, @big_show

This adds a macro which lets you tell Flux to treat some container type much the same way as it treats Chain, starting the recursive printing walk over all children.

Prompted by #1929. Closes #2044

Metalhead also has show methods for top-level layers which enable the recursive printing, which could be replaced by this macro:

https://github.com/FluxML/Metalhead.jl/blob/aba6fb832093d88dc2d2b4d5b1d2d63a0f21eb9c/src/Metalhead.jl#L53-L57

https://github.com/FluxML/Metalhead.jl/blob/c8f0a88e4d24274c53b62c2b740822aa6a781709/src/utilities.jl#L49-L52

Searching for other uses on github, I see only two:

https://github.com/avik-pal/ExplicitFluxLayers.jl/blob/8e1cff447afda225bc12144ff27ae1370e8fc3da/src/show_layers.jl

https://github.com/maxfreu/SegmentationModels.jl/blob/7bfdbaa438910baf49543f03f2931de765dbd761/src/unet.jl#L99-L112

Later, @layer

Now aims to also replace @functor, in addition to handling show.

Discussed at https://github.com/FluxML/Flux.jl/pull/2028 -- a layer supertype is another way to make opting into pretty printing easier. (We wouldn't do both, so this closes https://github.com/FluxML/Flux.jl/pull/2028 .)

PR Checklist

  • [x] Tests are added
  • [x] Entry in NEWS.md
  • [ ] Documentation, if applicable

mcabbott avatar Apr 07 '22 00:04 mcabbott

Looks reasonable, so if you'd let me indulge in some light bikeshedding how about @show_expanded over @big_show?

ToucheSir avatar Apr 07 '22 15:04 ToucheSir

Not at all set on the name.

Another question is whether there should be a matching way to disable recursion. Overloading _show_leaflike(::Diagonal) to make LayerNorm not expand is slightly weird. It's a hack to re-use the fact that layers all of whose children area leaflike aren't expanded, and has side-effects like this:

julia> Chain(Flux.Scale(2), Flux.Scale(2))
Chain(Scale(2), Scale(2))  # 8 parameters

julia> Chain(Flux.Scale(2), Flux.Scale(2), Dense(2=>2))
Chain(
  Scale(2),                             # 4 parameters
  Scale(2),                             # 4 parameters
  Dense(2 => 2),                        # 6 parameters
)                   # Total: 6 arrays, 14 parameters, 440 bytes.

If this needs a public face, then perhaps it should be more like @show_noexpand LayerNorm i.e. a property of the container, not the contents.

mcabbott avatar Apr 07 '22 16:04 mcabbott

show_leaflike(x::MyType) = true allowing to customize on the specific object seems more flexible and it feels ok to me as an interface, I would prefer that over a macro.

We could also merge this PR now since it seems ready and expose that interface later

CarloLucibello avatar Jun 02 '22 07:06 CarloLucibello

6370374 upgrades this to a replacement for @functor. The idea is to have just one magic macro do several things for us, maybe that's less confusing. It would also allow any back-end changes later, once Flux owns the macro. Discussed at https://github.com/FluxML/Flux.jl/pull/2028 (as an alternative to the supertype idea there).

Still WIP, but roughly works, I think.

mcabbott avatar Aug 23 '22 20:08 mcabbott

Doctest failure looks real, but I'm not sure why it's only showing up now.

ToucheSir avatar Aug 26 '22 15:08 ToucheSir

Doc failure seems to be that this doesn't work on 1.6, where the first argument is a vector:

julia> Dense([3.3;;], false)
Dense(1 => 1; bias=false)  # 1 parameters

Downstream tests didn't run, not sure why.

mcabbott avatar Aug 26 '22 20:08 mcabbott

Failures look unrelated:

  • GeometricFlux.jl I see only create_bias failures, https://github.com/FluxML/Flux.jl/issues/2049
  • FastAI.jl has failures like "Expression: isempty(stderr_content) [1105] Evaluated: isempty("┌ Warning: ignore(f) is deprecated, use ChainRulesCore.ignore_derivatives(f) instead.\n│ caller ="
  • AtomicGraphNets.jl has failures like "MethodError: no method matching needs_concrete_A(::Nothing) Closest candidates are: needs_concrete_A(::LinearSolve.AbstractFactorization) at ~/.julia/packages/LinearSolve/AoYJI/src/LinearSolve.jl:34"
  • OperatorLearning.jl has create_bias only

mcabbott avatar Aug 26 '22 23:08 mcabbott

So just the doctest fixup for 1.6?

ToucheSir avatar Aug 27 '22 02:08 ToucheSir

Shall we do this?

Making Functors opt-out instead isn't going to happen tomorrow. And having an official way to opt-in to show would still be worth something.

mcabbott avatar Nov 21 '22 22:11 mcabbott

Codecov Report

Attention: Patch coverage is 70.19231% with 31 lines in your changes are missing coverage. Please review.

Project coverage is 73.91%. Comparing base (20d516b) to head (63e10f6).

Files Patch % Lines
src/layers/attention.jl 9.52% 19 Missing :warning:
src/layers/macro.jl 81.66% 11 Missing :warning:
src/layers/normalise.jl 0.00% 1 Missing :warning:
Additional details and impacted files
@@             Coverage Diff             @@
##           master    #1932       +/-   ##
===========================================
+ Coverage   42.55%   73.91%   +31.35%     
===========================================
  Files          31       32        +1     
  Lines        1786     1909      +123     
===========================================
+ Hits          760     1411      +651     
+ Misses       1026      498      -528     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Feb 29 '24 14:02 codecov[bot]

Rebased in 2024. We should just do this, right?

The biggest questions is: Should this support children at all? Or can we simply forbid that... do we really need 4 ways to customise things, alla #2385? Maybe if you want to hack things with Functors.jl directly you are welcome, but Flux.jl can pretend this doesn't exist.

mcabbott avatar Feb 29 '24 15:02 mcabbott

I agree. Given that you almost never want to set children, having to support and explain children vs trainable is just confusing for users. Anyone wanting to restrict children probably needs to take a minute to understand @functor first.

darsnack avatar Feb 29 '24 18:02 darsnack

OK, children is gone.

This should be ready to merge, I think. As always there may be further cleaning up of the docs possible.

mcabbott avatar Mar 02 '24 20:03 mcabbott