Commit Graph
82 Commits
Author SHA1 Message Date
jensandClaude Sonnet 5 0149cdf7ce Rename weightDecay to l2Lambda
Rbm::Params::weightDecay is now applied directly to the weights outside
the momentum recursion (previous commit), exactly like the newly-added
l1Lambda and matching pyRBM's l2_lambda -- same lambda*W gradient form,
same decoupled-from-momentum treatment. The two are functionally the
same mechanism in this codebase, so name it accordingly. Renamed the
Params field, its JSON key, and the two GUI references in
MainComponent.cpp that read/write it (the "weightDecayLabel" widget
identifier and its JUCE-generated marker comment are left as-is --
cosmetic, not part of the actual API).

Existing .prj files still have a "weightDecay" JSON key; fromJson()
no longer reads it, so it's silently ignored on load. Harmless today
since every current project has it set to 0.0 (confirmed: unchanged
poet.elf output, unchanged test-suite results). Not migrating the .prj
files themselves in this change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 15:41:01 +02:00
jensandClaude Sonnet 5 cb20060732 Implement L1 regularization
Rbm::Params had no l1Lambda field at all -- L1 didn't exist anywhere in
the C++ codebase. Status::L1 was a dead field always -1 (never assigned
outside its constructor), and the GUI's "Lambda" control was explicitly
tooltipped "Unused" with an empty change-handler stub. Scaffolded, never
implemented.

Add Params::l1Lambda (default 0.0, inert unless set) with full toJson/
fromJson round-trip. Apply its subgradient (lambda*sign(W), matching
pyRBM's l1_lambda) directly to m_whv in Rbm::train, in the same place
and same decoupled-from-momentum manner as the weightDecay fix from the
previous commit -- folding it into inc_whv's momentum recursion would
cause the same momentum-amplification bug. Doesn't touch the biases,
matching pyRBM's state_adjust().

Also wire up Status::L1 to actually report something (the current L1
norm of the weights, sum(abs(W))) instead of permanently printing -1,
computed alongside status.err/err_total.

Inert by default (l1Lambda=0.0 in every existing .prj): confirmed via
unchanged poet.elf output and unchanged test-suite results (9 passed,
1 known issue, 2 failed).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 15:31:59 +02:00
jensandClaude Sonnet 5 0dd2b89cf0 Decouple weight decay from momentum in Rbm::train
inc_whv = momentum*inc_whv + lr*(dwhv/numcases - weightDecay*m_whv) folded
the weight-decay term into the momentum-accumulated velocity, so its
steady-state effective strength was amplified by roughly
weightDecay/(1-momentum) rather than the configured value -- e.g. ~2x at
momentum=0.5, ~10x at momentum=0.9. This is the same L2-regularization-
vs-momentum interaction that motivated decoupled weight decay (AdamW) in
the broader literature; pyRBM's state_adjust() already applies its
regularization terms directly to the weights outside the momentum
recursion, at full undiscounted strength every step.

Apply weightDecay directly to m_whv after the momentum-accumulated CD
update instead. weightDecay defaults to 0.0 in every .prj in this repo,
so this is currently inert in practice -- confirmed via unchanged
poet.elf output and unchanged test-suite results (9 passed, 1 known
issue, 2 failed) -- but anyone who sets it will now get the strength
they actually configured.

L1 regularization has no equivalent to fix: there's no l1Lambda field in
Rbm::Params at all, Status::L1 is a dead field always -1, and the GUI's
"Lambda" control is explicitly tooltipped "Unused" with an empty
change-handler stub -- it was scaffolded and never implemented.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 15:21:51 +02:00
jensandClaude Sonnet 5 4cf5f15555 Fix cd_jens positive phase using noisy sample instead of mean
doGaussianHidden took priority over doRaoBlackwell when deciding h_states
for the positive-phase gradient, so a Gaussian-hidden RBM always got the
noisy sample (h_probs + randn) for dw/dbh even with doRaoBlackwell set --
ignoring the flag and adding avoidable gradient variance. Standard CD
practice (and pyRBM's cd_gaussian_gaussian) uses the mean for the
weight/bias gradient when Rao-Blackwellizing, regardless of unit type.

Reordered so doRaoBlackwell is checked first (mean, any unit type) and
only samples otherwise, dispatching via the sampleHidden() helper added
in the previous commit so Gaussian/binary hidden units are each sampled
correctly. Behavior-preserving for poet (doRaoBlackwell=true,
doGaussianHidden=false already took the mean branch); only changes
behavior for a Gaussian-hidden RBM trained with doRaoBlackwell enabled.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 13:57:46 +02:00
jensandClaude Sonnet 5 eb29e33b81 Fix Bernoulli-only sample() applied to Gaussian visible/hidden units
Matutils::sample() always binary-thresholds (src > uniform(src)), but it
was the only sampler in the codebase and was called unconditionally on
h_probs/v_probs/miniBatch in several CD Gibbs-loop branches regardless
of doGaussianVisible/doGaussianHidden. Binary-thresholding a Gaussian
unit's continuous activation is meaningless -- it would corrupt any
Gaussian-visible/hidden RBM (image-domain experiments via the GUI or
TEST target); doesn't affect poet's plain BB-RBM path since both flags
are false there.

Add sample_gaussian() (mean + N(0,1) noise) alongside the existing
Bernoulli sample() in matutils.hpp, plus Rbm::sampleVisible/sampleHidden
helpers that dispatch to the right one per the RBM's configured type.
Replace every visible/hidden Gibbs-step sample() call in cd_jens (the
active path) and cd_hinton (compiled but currently unused, behind
USE_CD_HINTON) with the appropriate dispatch helper, and fix the same
issue in Rbm::train's doSampleBatch path.

Behavior is unchanged for any RBM with doGaussianVisible/doGaussianHidden
both false (confirmed: poet.elf f output identical before/after).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 13:45:03 +02:00
jensandClaude Sonnet 5 aabf7385ce Fix RBM training: invert epoch/mini-batch loop nesting, drop duplicate CD computation
Rbm::train had mini-batch chunks as the outer loop and epochs as the
inner loop: each fixed, never-reshuffled slice of the data got all
numEpochs gradient steps back-to-back before ever being revisited, so
"numEpochs" didn't mean "passes over the whole dataset" and training
was biased toward whatever data came last. Invert the nesting (epochs
outer, mini-batches inner, batch reshuffled via arma::shuffle at the
start of each epoch) so every epoch is an actual full pass over the
data in a fresh random order.

Also drop a redundant toHiddenProbs(v_states) call in cd_jens: the
positive-phase hidden probabilities were computed once unconditionally
and then discarded, recomputed a second time with identical input in
two of the three sampling branches. Same result, half the cost, on
every mini-batch of every epoch of every layer.

Both only affect training; inference (step_forward/generation) is
unchanged, confirmed by identical poet.elf f output before and after.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 13:39:58 +02:00
jens 324a56557b - use cd_jens() 2024-02-02 18:59:04 +01:00
jens 5321e01cca - improved cd_hinton()
- uniform() returns vector
2024-02-01 19:03:13 +01:00
jens 8e44aff7a5 - prepare cd_jens() for linear hidden units 2024-01-31 20:52:18 +01:00
jens ccc3e0ac87 - fixed total error calc 2024-01-31 12:52:29 +01:00
jens 2a2be76b2c - AStack:Load show mean and stddev 2024-01-31 12:20:15 +01:00
jens e211c568ac Rbm
- enable linear hidden : instead of prob(v_to_h()): use toHiddenProbs()
- enable linear visible: instead of prob(h_to_v()): use toVisibleProbs()
- make v_to_h() and h_to_v() private and force to use toHiddenProbs() and toVisibleProbs()
- use cd_jens or cd_hinton. cd_hinton_hid_lineaer is not of use anymre, since it is not capable of CDn
2024-01-31 12:03:47 +01:00
jens c0445f3bf8 - moved Rbm:prob() to Matutils::prob()
- Matutils::Normalize uses prob()
2024-01-29 13:04:13 +01:00
jens fe8142627d cd_hinton_hid_binary: added raoBlackwell, gibbs-sampling 2024-01-25 22:45:50 +01:00
jens 34b20f4fb3 - refactored
- switch between cd_hinton hid/linear and cd_jens using doGaussionVisible (temporary solution)
2024-01-24 19:22:57 +01:00
jens a5ed0be991 - added original implementation for binary RBM 2024-01-24 18:41:42 +01:00
jens 84a5dd4550 Refactored 2024-01-24 17:04:05 +01:00
jens 88f649e8f4 - refactored 2024-01-24 16:56:49 +01:00
jens 9a381c1899 - its gaussion hidden (not gaussian visible) 2024-01-24 15:14:30 +01:00
jens fe9b1951ea - Added gaussian hidden units 2024-01-24 14:47:21 +01:00
jens 938368f1fa - refactored
- constify
2024-01-22 12:26:03 +01:00
jens aef3049856 - refactored common functions into matutils
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@855 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-21 07:46:40 +00:00
jens ae81da610b - gibbsDoSampleHidden and gibbsDoSampleVisible onl used only training
- very good results

git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@852 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-20 18:16:35 +00:00
jens 78c05afbc2 - removed noise c-sources
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@812 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-15 09:23:57 +00:00
jens 4b7c29effd - refactored
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@811 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-15 09:19:50 +00:00
jens 1eb631d254 - use arma::randu for uniform
- use arma functions for sample()

git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@798 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-13 10:27:10 +00:00
jens be64a88e04 - Layer: do gibbs sampling in calcContextBatch()
- RBM: added Gibbs sampler
- Stack adjust training column vector according to needs

git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@797 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-13 07:19:47 +00:00
jens fa2014b4dd - trainingdata always contains context
- load / store training batch with context
- on load: add context part to  legacy training batches 
- removed Rbm::setBatch()

git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@790 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-12 08:12:35 +00:00
jens 5cb7b16d96 - added rms_error function
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@786 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-11 19:13:30 +00:00
jens 648d8a002e - added setBatch()
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@771 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-10 10:36:55 +00:00
jens e240eae073 - moved context awareness from Rbm to Layer (final)
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@770 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-10 10:03:43 +00:00
jens e9de02ac3d - moved context awareness from Rbm to Layer
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@769 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-10 08:09:49 +00:00
jens 967df2906d - removed flat train routine
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@768 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-10 07:24:32 +00:00
jens 238a6d9258 - context drawComponents are always visible
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@765 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-09 13:02:52 +00:00
jens 5427287838 - fixed gui wiring
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@764 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-09 12:36:45 +00:00
jens 56335914ea - train with context
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@762 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-09 08:34:59 +00:00
jens c2ffecd66a - pass numContext
- fixed crash when numContext == 0

git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@761 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-09 08:01:25 +00:00
jens 9fff2082d6 - use all-at-onec (v+c) method
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@759 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-08 15:24:07 +00:00
jens 3272899888 - train whv and whc separately
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@758 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-08 13:30:26 +00:00
jens b46e53f207 - prepared for context processing
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@757 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-08 11:52:01 +00:00
jens 1698ce0a1b - simplified initial v_states generation
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@756 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-08 11:23:31 +00:00
jens 91bfa0e6ec - fixed prototype for v_probs
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@755 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-08 11:16:20 +00:00
jens ef82ae7ea6 - refactored in gibbs
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@753 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-08 11:10:26 +00:00
jens be9a4a4d74 - refactored
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@752 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-08 10:56:36 +00:00
jens 637b237966 - refactored
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@751 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-08 10:41:41 +00:00
jens 9472bb0a36 - refactored Rbm
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@750 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-07 18:23:43 +00:00
jens deb5a9ce65 - use new weightUpdate()
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@748 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-07 12:49:56 +00:00
jens dc8db11d9a - constify
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@747 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-07 12:46:03 +00:00
jens 66fe4a018d - refactored Rbm
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@746 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-07 12:40:57 +00:00
jens 7f3535954b - prepared for context units
- simplified status report

git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@745 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-07 08:49:12 +00:00