Skip to content

Remove the recurrent and LSTM architectures - #247

Merged
michakraus merged 2 commits into
mainfrom
remove-recurrent-architectures
Aug 23, 2026
Merged

Remove the recurrent and LSTM architectures#247
michakraus merged 2 commits into
mainfrom
remove-recurrent-architectures

Conversation

@michakraus

Copy link
Copy Markdown
Member

Removes RecurrentNeuralNetwork and LSTMNeuralNetwork, along with src/architectures/recurrent_neural_network.jl, src/architectures/LSTM_neural_network.jl and the driver scripts under scripts/Script_using_fully_GML/{RNN,LSTM}/.

They were already unusable

Chain(::RecurrentNeuralNetwork) returned an AbstractNeuralNetworks.GridCell rather than a Chain, and the cells it held still defined the pre-0.6 initialparameters(cell, backend, T; init, rng) signature — so constructing a NeuralNetwork from either architecture errored out. Nothing in the test suite referenced either one, which is why nothing noticed.

Why now

AbstractNeuralNetworks 0.7 deleted src/cells/ outright — Recurrent, LSTM, GRU, IdentityCell and GridCell (AbstractNeuralNetworks.jl#34) — so these imports at the top of GeometricMachineLearning.jl have to go regardless of what happens to the architectures that used them:

import AbstractNeuralNetworks: Architecture, Model, AbstractExplicitLayer,
                               AbstractExplicitCell, ...
import AbstractNeuralNetworks: Chain, GridCell
import AbstractNeuralNetworks: Dense, Linear, Recurrent

Doing it here, against main and the current AbstractNeuralNetworks 0.6.4, keeps the removal independent of the 0.7 bump — #246 then only has to be a dependency change, not a dependency change carrying a behavioural one.

Concretely: #246 as it stands still imports all three removed names, and loading it against 0.7.0 emits

WARNING: Imported binding AbstractNeuralNetworks.AbstractExplicitCell was undeclared at import time
WARNING: Imported binding AbstractNeuralNetworks.GridCell was undeclared at import time
WARNING: Imported binding AbstractNeuralNetworks.Recurrent was undeclared at import time

Julia downgrades those to warnings so the module still loads, but they should not survive the merge. Once this lands on main, #246 picks it up on its next merge from main.

Docs

The footnote in docs/src/architectures/neural_network_integrators.md had flagged the LSTM implementation as likely to be deprecated since it was written; it now says it is gone. The transformer-derived architectures are what GML maintains for time series.

Verification

  • Pkg.test() on this branch against AbstractNeuralNetworks 0.6.4 — 56 testsets, zero failures, zero errors.
  • Loads with no undeclared-binding warnings, and RecurrentNeuralNetwork/LSTMNeuralNetwork are no longer defined.
  • grep -rniE "RecurrentNeuralNetwork|LSTMNeuralNetwork|GridCell|AbstractExplicitCell|IdentityCell" over *.jl/*.md/*.toml returns nothing outside the CHANGELOG entry documenting the removal.

Separately confirmed while preparing this: with this removal applied on top of #246's branch, GML's full suite also passes against the released AbstractNeuralNetworks 0.7.0 (with a dev'd SymbolicNeuralNetworks, which needed its own QPTOATArrayOrNamedTuple fix), zero failures.

🤖 Generated with Claude Code

`RecurrentNeuralNetwork` and `LSTMNeuralNetwork` go, with
`src/architectures/recurrent_neural_network.jl`, `src/architectures/LSTM_neural_network.jl` and the
driver scripts under `scripts/Script_using_fully_GML/{RNN,LSTM}/`.

Both were already unusable, and had been for some time. `Chain(::RecurrentNeuralNetwork)` returned
an `AbstractNeuralNetworks.GridCell` rather than a `Chain`, and the cells it held still defined the
pre-0.6 `initialparameters(cell, backend, T; init, rng)` signature, so constructing a
`NeuralNetwork` from either architecture errored out. Nothing in the test suite referenced them, so
nothing noticed.

AbstractNeuralNetworks 0.7 deleted `src/cells/` outright -- `Recurrent`, `LSTM`, `GRU`,
`IdentityCell` and `GridCell` (JuliaGNI/AbstractNeuralNetworks.jl#34) -- so the imports at the top
of `GeometricMachineLearning.jl` have to go regardless of what happens to the architectures that
used them. Removing them here means the 0.7 bump does not have to carry a behavioural change on top
of a dependency change.

The transformer-derived architectures are what GML maintains for time series; the footnote in
`docs/src/architectures/neural_network_integrators.md` had flagged the LSTM implementation as
likely to be deprecated since it was written, and now says it is gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 23, 2026 04:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@codecov

codecov Bot commented Aug 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 65.19%. Comparing base (33d76f2) to head (df89a6e).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #247      +/-   ##
==========================================
- Coverage   65.59%   65.19%   -0.40%     
==========================================
  Files         101       99       -2     
  Lines        2985     2931      -54     
==========================================
- Hits         1958     1911      -47     
+ Misses       1027     1020       -7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

`import AbstractNeuralNetworks: IdentityActivation, ZeroVector` had `Chain(::RecurrentNeuralNetwork)`
as its only reader for `IdentityActivation`, and `ZeroVector`'s last use in `src/` moved to
`legacy/` in `ec8e8fa5`. Neither is exported by GML, and `IdentityActivation` is an
`AbstractNeuralNetworks` export that the blanket `using` at the top of the module already provides,
so `GeometricMachineLearning.IdentityActivation` keeps resolving without it.

The footnote in `docs/src/architectures/neural_network_integrators.md` had grown a second half that
repeated the sentence it hangs off -- the body already says transformer-derived architectures are
what gets used for time series -- so it now records only the fact it is there for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@michakraus michakraus left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 30f47127. The removal is correct and complete — I could not find a way for it to break anything, and I checked the premise rather than taking it on trust. Two minor cleanups, both now pushed as df89a6e6.

What I verified

The two architectures really were unconstructible. Against main + AbstractNeuralNetworks 0.6.4:

julia> Chain(RecurrentNeuralNetwork(4, 4, (1,1)))
GridCell{1, 1, Matrix{Any}, Vector{Vector{Float64}}}

julia> NeuralNetwork(RecurrentNeuralNetwork(4, 4, (1,1)), CPU(), Float32)
ERROR: initialparameters not implemented for model type GridCell{1, 1, Matrix{Any}, Vector{Vector{Float64}}}

Same error for LSTMNeuralNetwork(4, (1,1)). So the description is accurate: nothing could have been depending on these, and no deprecation shim is owed.

No dangling references. git grep -l -in "RecurrentNeuralNetwork|LSTMNeuralNetwork|GridCell|AbstractExplicitCell|IdentityCell" across the whole tree — every file type, not just .jl/.md/.toml — returns CHANGELOG.md and nothing else: the new removal entry plus the historical 0.3.0 line. src/, test/, docs/, scripts/, legacy/ and .github/ are clean, and docs/make.jl never referenced them.

The import removal is forced, not merely tidy. src/cells/{abstract,grid,gru,identity,lstm,recurrent}.jl are present in AbstractNeuralNetworks 0.6.4 and absent from 0.7.0, so AbstractExplicitCell, GridCell and Recurrent had to go either way. None of the three was ever re-exported by GML, so RecurrentNeuralNetwork and LSTMNeuralNetwork are the only public names this drops.

Findings

1. The IdentityActivation / ZeroVector import is left dead — minor

src/GeometricMachineLearning.jl:71

import AbstractNeuralNetworks: IdentityActivation, ZeroVector

Chain(::RecurrentNeuralNetwork) was the only thing in src/ that named IdentityActivation, so this PR is what makes it dead. ZeroVector was dead already — its last src/ use moved to legacy/ in ec8e8fa5.

Worth saying why this is a nit and not a bug, since it cuts both ways:

  • It is not a source of undeclared-binding warnings under 0.7 — both names survive there (ZeroVector in src/utils/zero_vector.jl, IdentityActivation still exported), so leaving it would not have undone what the PR set out to do.
  • Removing it is not observable either. IdentityActivation is an AbstractNeuralNetworks export and line 3 is a blanket using AbstractNeuralNetworks, so GeometricMachineLearning.IdentityActivation still resolves without the explicit import. The two scripts/loss/write_loss_*.jl occurrences spell it fully qualified as AbstractNeuralNetworks.IdentityActivation and never depended on the line.

So: redundant, and this PR is the one in a position to notice. Deleted.

2. The reworded footnote repeats the sentence it hangs off — minor

docs/src/architectures/neural_network_integrators.md:42

The body already ends "…we almost always use a transformer-derived architecture when dealing with time series[^2]", and the new footnote then said "It was removed in favour of the transformer-derived architectures, which are the ones maintained for time series here" — the same claim twice, one line apart. Cut to the fact the footnote exists to record:

[^2]: `GeometricMachineLearning` used to ship an LSTM implementation. It has been removed.

Checked and dismissed

  • Trailing whitespace on the footnote line — the entire file is written that way; not this PR's business.
  • Project.toml still at 0.5.0 — this repo bumps at release, and ## [Unreleased] already carries other breaking entries.
  • Open Issues C8 ("scripts/ has been dead since SymbolicNeuralNetworks 0.2") — deleting six of those scripts does not close it; the entry still stands as written.
  • C10 (ten undefined exported names) — unaffected; both removed names were defined.

Verification of the follow-up

  • Pkg.test() on df89a6e6: 56 testsets, zero failures, zero errors (twice, plus the pre-push hook run).
  • Loads with no undeclared-binding warnings; isdefined is false for RecurrentNeuralNetwork, LSTMNeuralNetwork and ZeroVector, and IdentityActivation still resolves through the blanket using, as above.

🤖 Generated with Claude Code

@michakraus
michakraus merged commit d908c26 into main Aug 23, 2026
11 of 15 checks passed
@michakraus
michakraus deleted the remove-recurrent-architectures branch August 23, 2026 07:47
michakraus added a commit that referenced this pull request Aug 23, 2026
…ings

`SymbolicNeuralNetworks = "0.5"` caps `AbstractNeuralNetworks` at `0.6.4 - 0.6`,
so together with `AbstractNeuralNetworks = "0.7"` the `[compat]` block was not
merely pointing at unregistered versions, it was unsatisfiable. The bound is
`"0.6"`, and the CHANGELOG now spells out the release chain the branch waits on:
ANN 0.7.0 registered, then GeometricOptimizers 0.4.1 tagged and registered, then
SymbolicNeuralNetworks fixed — its `abstractneuralnetworks-0.7` branch still
imports `AbstractNeuralNetworks.QPTOAT`, which 0.7 replaced — bumped to 0.6.0 and
registered.

The docs build was broken: `abstract_neural_networks.md` lists four `@docs`
signatures and this branch had merged four docstrings into two, so Documenter
would have errored on `save(::AbstractString, ::NeuralNetwork)` and
`load(::Type{NeuralNetwork}, ::AbstractString, ::Architecture)` — `docs/make.jl`
passes `HDF5Ext` in `modules` and sets no `warnonly`. Each of the four methods
carries its own docstring again, and the prose above them says who does the work
now instead of claiming this package still handles the structured types itself.

Also:

  * `load(NeuralNetwork, …, args...)` took untyped varargs where one optional
    prototype was meant. Explicit methods instead, so a wrong arity is a
    `MethodError` at the call site and the `@docs` signatures name real methods.

  * the prototype form had no test, and the old-layout test covered only
    `SymmetricMatrix` — `GeometricOptimizers` normalises the two old shapes
    through different helpers, so the `StiefelManifold` leg is read back too.

  * `save`/`load` are `NeuralNetworkParameters`' generics; 0.7 only re-binds
    them. Imported from the owner, in `src/` and in the extension.

  * seven `NeuralNetworkParameters` the rename missed, in `scripts/`.

  * `save(filename, nn)` returning `filename`, and the new prototype `load`,
    recorded in the CHANGELOG under *Changed* and *Added* rather than left
    unmentioned and filed under *Removed*.

The `RecurrentNeuralNetwork`/`LSTMNeuralNetwork` removal this commit originally
carried is gone: #247 landed the same removal on main, more thoroughly — it also
drops the `IdentityActivation, ZeroVector` import the removal left dead and
updates the docs footnote — so the rebase takes main's.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
michakraus added a commit that referenced this pull request Aug 23, 2026
…ings

`SymbolicNeuralNetworks = "0.5"` caps `AbstractNeuralNetworks` at `0.6.4 - 0.6`,
so together with `AbstractNeuralNetworks = "0.7"` the `[compat]` block was not
merely pointing at unregistered versions, it was unsatisfiable. The bound is
`"0.6"`, and the CHANGELOG now spells out the release chain the branch waits on:
ANN 0.7.0 registered, then GeometricOptimizers 0.4.1 tagged and registered, then
SymbolicNeuralNetworks fixed — its `abstractneuralnetworks-0.7` branch still
imports `AbstractNeuralNetworks.QPTOAT`, which 0.7 replaced — bumped to 0.6.0 and
registered.

The docs build was broken: `abstract_neural_networks.md` lists four `@docs`
signatures and this branch had merged four docstrings into two, so Documenter
would have errored on `save(::AbstractString, ::NeuralNetwork)` and
`load(::Type{NeuralNetwork}, ::AbstractString, ::Architecture)` — `docs/make.jl`
passes `HDF5Ext` in `modules` and sets no `warnonly`. Each of the four methods
carries its own docstring again, and the prose above them says who does the work
now instead of claiming this package still handles the structured types itself.

Also:

  * `load(NeuralNetwork, …, args...)` took untyped varargs where one optional
    prototype was meant. Explicit methods instead, so a wrong arity is a
    `MethodError` at the call site and the `@docs` signatures name real methods.

  * the prototype form had no test, and the old-layout test covered only
    `SymmetricMatrix` — `GeometricOptimizers` normalises the two old shapes
    through different helpers, so the `StiefelManifold` leg is read back too.

  * `save`/`load` are `NeuralNetworkParameters`' generics; 0.7 only re-binds
    them. Imported from the owner, in `src/` and in the extension.

  * seven `NeuralNetworkParameters` the rename missed, in `scripts/`.

  * `save(filename, nn)` returning `filename`, and the new prototype `load`,
    recorded in the CHANGELOG under *Changed* and *Added* rather than left
    unmentioned and filed under *Removed*.

The `RecurrentNeuralNetwork`/`LSTMNeuralNetwork` removal this commit originally
carried is gone: #247 landed the same removal on main, more thoroughly — it also
drops the `IdentityActivation, ZeroVector` import the removal left dead and
updates the docs footnote — so the rebase takes main's.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

2 participants