Repository navigation
Keep zero convolutional and local kernels finite during normalization - #814
Hananel-Hazan merged 3 commits into
Conversation
Co-authored-by: OpenAI Codex <codex@openai.com>
Review follow-up to BindsNET#814. One tensor operation replaces the per-kernel loop in Conv1d/2d/3d and LocalConnection1D/2D/3D, and LocalConnection gets the same guard. Kernels whose weights sum to zero keep their weights instead of becoming NaN or infinite. CPU results match the old loop bit for bit; CUDA float32 can differ by rounding for kernels of 81+ weights. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for finding this. A kernel whose weights sum to zero turns into NaN on the next The guard you added runs inside the existing Python loop over kernels, and it makes
I took your fix and pushed 6720b51 on top of it:
The full suite passes (250 tests). Seeded training runs of all six connection classes plus Can you run it on your side and confirm it works for you? |
Resolve CHANGELOG.md: keep the zero-sum kernel entry at the end of Fixed and master's new Added section after it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Confirmed on merged commit 78ec02b: the complete local suite passes (255 passed, 1 skipped; PyTorch 2.14.0+cpu). This includes the vectorized-vs-loop CPU equivalence checks, signed zero-sum kernels staying finite and unchanged, and the LocalConnection zero-column case. I did not run CUDA or reproduce the timing measurements. |
Zero kernels in
Conv1dConnection,Conv2dConnection,Conv3dConnectionand the corresponding dimensionalLocalConnectionclasses become NaN during normalization: the weight sum is zero, so the in-place multiplication evaluates0 * (norm / 0). A zero normalization target also causes this on subsequent calls after it has zeroed nonzero weights.Use denominator 1 only for genuinely all-zero kernel groups, keeping those weights zero. Each nonzero group's existing signed-sum normalization is retained; a nonzero signed kernel whose values cancel is not silently treated as an empty kernel. The six method docstrings and Unreleased changelog describe zero-kernel handling. No extra weight parameters or dependencies are introduced.
Forty-two cases cover all six classes, float32/float64 normalization, disabled/zero/positive targets, mixed zero and nonzero groups, repeated calls, parameter identity, float32 public pre-activation computations and nonzero signed-cancellation controls. Unchanged master fails 24 cases and passes 18 controls.
Validation
Windows CPU / Python 3.12.14 / torch 2.14.0+cpu / torchvision 0.29.0+cpu:
GPU execution and a full documentation build were not run. CPU torch/torchvision and formatting tool versions follow the same verified project pins/profile reported in #813. No lockfile, dependency, workflow or sparse-check settings are changed. This PR targets master independently of #813.
Prepared and tested autonomously with OpenAI Codex. The account owner has not independently reviewed this patch before submission; no human-only authorship or review is claimed.
Local integration check: #813 and #814 apply together without conflicts, including both changelog entries. The full suite passes with 254 passed, 1 skipped, 8 warnings, sparse tensor invariant checks enabled, and the memory guard not triggered. Project-wide pre-commit checks also pass. The private integration branch was not pushed; each PR keeps its independent master base.