Repository navigation
Conversation
JaxMLP.setup() dropped "linear" entries from activation_funs while __call__ indexed that list by layer position, so any "linear" before the output layer raised IndexError, or silently applied the wrong activation when activations was longer than layer_sizes. Map "linear" to an identity and keep one activation per layer. The identity adds nothing to the traced graph, so the exported ONNX for existing configs is byte-identical. Closes #105 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LRVhzVTfUsMkPu83XJbh8E
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests.
🚀 New features to boost your workflow:
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #105.
Problem
JaxMLP.setup()dropped"linear"entries fromactivation_funs, but__call__indexes that list by layer position. So any"linear"before the output layer moved every later activation one layer earlier:IndexError: tuple index out of range, e.g.["tanh", "linear", "linear"].activationslist longer thanlayer_sizes, it runs but applies the wrong activation. For example,["linear", "tanh", "linear", "tanh"]on 3 layers appliestanhto layer 0.jaxtraincan hit this:_get_train_network_configappends the output activation to the YAML'sACTIVATIONS, soACTIVATIONS: [["tanh", "linear"]]crashes.Fix
Following the recipe in the issue thread: map
"linear"to an identity inactivations_dict, keep one entry per activation inactivation_funs, and collapse the forward loop tox = self.activation_funs[i](lyr(x)). This also removes the now-obsoleteTODO: Warn if linear activation is used before final layer.Two deliberate choices:
lambda x: x, notjax.nn.identity.jax.nn.identityis jitted, so it would add a nested jit call to the traced graph. The lambda adds nothing, so the exported ONNX for existing configs is unchanged.zip. Plainzipwould silently drop layers ifactivationswere too short.zip(strict=True)would reject over-long lists that work today (a YAML that already lists the output activation gets a second one appended by the CLI). Indexing keeps current behaviour for both.Tests
test_mlp_jax_activations_stay_layer_alignedruns 4 configs: the default plus three with a hidden"linear". It compares each output with the per-layer maths computed from the initialized params, because a shape check alone can't tell whether each layer got its own activation. Onmainthe three hidden-"linear"cases fail withIndexError; with the fix all four pass.Also checked locally:
JaxMLPorjaxtrainpass:test_jax_mlp.py,onnx/test_jax_export.py,test_end_to_end_jax.py,test_jax_lr_dict_else.py,test_run_identity.py,test_mlflow_integration.py,cli/test_cli_entry_points.py.ruff check src/lanfactoryandruff format --check .are clean. mypy reports the same pre-existing errors as onmain, none in changed code.[100, 100, 1],tanh, tanh, linear): the traced jaxpr and the exported ONNX are byte-identical before and after. Parameter names are unchanged, so existing*_train_state.jaxfiles still load."linear"layer exports, passesassert_single_trial_contract, and onnxruntime matches JAX.Not in this PR
TorchMLPrejects the same config withKeyError: 'linear'because its activation dict has no"linear". Adding"linear": torch.nn.Identity()would make the two backends match; left for a follow-up.len(activations) == len(layer_sizes)check would catch the over-long case, but it would break YAMLs that already list the output activation, so it needs a decision first.🤖 Generated with Claude Code
https://claude.ai/code/session_01LRVhzVTfUsMkPu83XJbh8E
Generated by Claude Code