Commit Graph
81 Commits
Author SHA1 Message Date
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
jens cbadd106f4 - speed improvment: sample minibatch only on minibatch change
- refactored

git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@744 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-06 11:00:51 +00:00