Commit Graph
246 Commits
Author SHA1 Message Date
jensandClaude Sonnet 5 af35c0902d Add mnist to the test suite
Single-layer Deep stack (28x28->256), has saved weights and a larger
training batch than the other mnist variants (test run took noticeably
longer). Passes: reconstruction error 0.005 vs. mean-baseline 0.067.
9/12 pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 15:01:31 +02:00
jensandClaude Sonnet 5 10cdd6fb9b Add mnist_21 to the test suite
3-layer Deep stack (28x28->256->512->64), has saved weights for all
three layers. Passes: reconstruction error 0.039 vs. mean-baseline
0.063. 8/11 pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 14:59:43 +02:00
jensandClaude Sonnet 5 db7eb72174 Add mnist_h32 to the test suite
Single-layer Deep stack (28x28->32), weights load fine but genuinely
fail the reconstruction check: error 0.231 vs. mean-baseline 0.067,
worse than the 1.5x tolerance. Unlike norb_small_16h_v2/many (which fail
because no current-format weights exist at all), this one has weights
that load successfully but just don't reconstruct well -- training
params look ordinary (RaoBlackwell, 1000 epochs) and the training data
looks like normal-scale MNIST pixels, so this looks like a genuinely
under-trained or abandoned saved snapshot rather than a test bug.
7/11 pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 14:58:04 +02:00
jensandClaude Sonnet 5 86764bb261 Add mnist_deep to the test suite
3-layer Deep stack (28x28->256->256->16), has saved weights for all
three layers. Passes: reconstruction error 0.039 vs. mean-baseline 0.067.
7/9 pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 14:54:54 +02:00
jensandClaude Sonnet 5 7b842ea50c Add many to the test suite
101-layer Deep stack (64->64 x100). Fails the same way as
norb_small_16h_v2: only legacy *.weights.dat files exist (the pre-split
combined-weights format current code never reads), no .w/.bh/.bv.dat for
any layer -- a pre-existing data gap, not a bug. 6/8 pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 14:52:13 +02:00
jensandClaude Sonnet 5 1acc05bc24 Add count to the test suite
Single-layer Deep stack (4x2->16), has saved weights and training data.
Passes: reconstruction error ~0.000000 vs. mean-baseline 0.16.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 14:51:27 +02:00
jensandClaude Sonnet 5 82d019ba48 Add prims_deep to the test suite
2-layer DeepStack (9x9->24, 24->4), has saved weights and training data.
Passes: reconstruction error 0.0007 vs. mean-baseline 0.14 -- exercises
upDownPass through more than one layer for the first time in the suite.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 14:50:14 +02:00
jensandClaude Sonnet 5 156babeb49 Add norb_small_16h to the test suite
Has saved weights and training data (unlike norb_small_16h_v2, which
still has none). Passes: reconstruction error 0.0003 vs. mean-baseline
0.54.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 14:49:15 +02:00
jensandClaude Sonnet 5 834723dcad Replace stale main.cpp with a minimal project test suite
The old main.cpp (TEST target) called APIs that no longer exist
(DeepStack::load()/loadWeights()/loadTrainingBatch() with no args,
Layer::upDownPass()) -- it hadn't compiled against the current AStack/
Layer API in a long time and was a manual smoke-test script, not an
actual test suite.

Replace it with a small dependency-free runner matching this repo's
existing no-framework style: for each named project, load it, load
weights and training batch, run a full up-pass/down-pass reconstruction
via DeepStack::upDownPass, and check the reconstruction error is finite
and beats the trivial per-feature-mean baseline (a project-agnostic sanity
bound, rather than a hardcoded threshold). Prints PASS/FAIL per project.

Starting coverage: 1-hot, prims, norb_small_16h_v2, mnist_2. 3/4 pass;
norb_small_16h_v2 fails because it has no saved weight files at all
(only .prj/.training.dat/.test.dat) -- a pre-existing gap in that
fixture's data, not a bug introduced here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 14:47:32 +02:00
jensandClaude Sonnet 5 ca27e1e705 Route project files through prj/<name>/ instead of flat at repo root
Repo root had ~35 groups of .prj/.dat files loose alongside the build
system and source, all sharing one flat namespace. Centralize the new
prj/<name>/ convention inside AStack::loadWeights/saveWeights/
loadTrainingBatch/saveTrainingBatch and StackCreator::fromFile/toFile
(via a new AStack::projectDir() helper) -- these already have access to
the project name, so callers (poet.cpp, the GUI) need no changes at all;
they keep passing the same base directory they always did.

Filenames inside each project folder are unchanged (e.g.
prj/mnist_2/mnist_2.prj, prj/mnist_2/mnist_2.Layer.0.w.dat) -- only the
directory moves. Added Matutils::ensureDir() (mkdir -p equivalent; no
std::filesystem in C++11) since ofstream won't create directories, used
wherever a project is saved for the first time.

File migration for existing projects is a separate commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 14:41:05 +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
jensandClaude Sonnet 5 656a0252d3 Wire up temperature-based sampling for poet text generation
Greedy argmax decoding in RbmListener::forward always produces the
exact same character sequence and quickly falls into short repeating
loops once the 5-character lookback state revisits a prior cycle.

Add an optional temperature argument (poet f <seed> [temperature]) that
switches decoding to RnnStack::sample_one_hot, which now does proper
categorical sampling (temperature-scaled, renormalized draw) instead of
the old per-code Bernoulli approach that could leave the result as a
non-one-hot probability vector. Also seed Armadillo's RNG in main(),
since it otherwise defaults to a fixed seed and every run would sample
identically.

Add docs/RNN_ARCHITECTURE.md documenting how the RnnStack/Layer stack
implements the RNN (context chaining across layers, training/generation
data flow, and the decoding behavior above).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs
2026-07-27 12:34:44 +02:00
jens f805b571d9 commit stale changes 2026-07-26 21:49:32 +02:00
jens 32c3526ba7 - Rbm::Params: Momentum default 0.9 2024-02-03 09:49:13 +01: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 861e03decf - DrawComponent: fixed normalizing to screen 2024-01-31 16:55:41 +01:00
jens 75e71bd060 - use auto detect for training data load 2024-01-31 15:29:38 +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 285be92cdb - finally return normalized data 2024-01-31 11:40:41 +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 b467180535 Initialize buttons rbmUseVisibleGaussianToggleButton and rbmUseHiddenGaussianToggleButton 2024-01-24 17:02:46 +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 fb5ac6d124 Fixed normalization 2024-01-24 14:44:20 +01:00
jens 4a7fcb387c - fixed normalization
- added sigmoid after normalization
2024-01-23 21:05:13 +01:00
jens 4a16926030 - improved training data normalization 2024-01-22 19:53:12 +01:00
jens 44445d3fd2 - fixed JUCE includes 2024-01-22 13:55:51 +01:00
jens 938368f1fa - refactored
- constify
2024-01-22 12:26:03 +01:00
jens d296ca5a1d - fixed crash 2024-01-21 20:44:56 +01:00
jens 6eb76febdc - added ToolTips for RBM windows 2024-01-21 15:26:48 +01:00
jens d5a64f6e6b - DeppeStack: simplified upPass, downPass 2024-01-21 15:25:50 +01:00
jens 3e819d32a8 - fixed crashes 2024-01-21 14:10:37 +01:00
jens 46ded370f6 - Layer: fixed privacy 2024-01-21 14:10:01 +01:00
jens aca008d4ff - refactored 2024-01-21 14:09:30 +01:00
jens f2f03479e2 - don't print training text after training
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@861 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-21 16:46:53 +00:00
jens e58593973d - refactored
- create training one th e fly from file name

git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@860 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-21 16:41:11 +00:00
jens 97c9dcce7c - added char2vec and vec2char
- refactored

git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@859 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-21 15:27:30 +00:00
jens a967f08874 - added DEFAULT_START_WORD
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@858 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-21 13:22:06 +00:00
jens 632a538bff - provide start text
git-svn-id: http://moon:8086/svn/software/trunk/projects/Rbm@857 b431acfa-c32f-4a4a-93f1-934dc6c82436
2022-01-21 13:13:12 +00:00