From 4cf5f1555506a84bc1b21e6a8c24fffddc3c0c0d Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Mon, 27 Jul 2026 13:57:46 +0200 Subject: [PATCH] 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 Claude-Session: https://claude.ai/code/session_016K8Gu7Qejd11JbdiHZqYAs --- source/Rbm.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/source/Rbm.cpp b/source/Rbm.cpp index c1642a7..7e5fe87 100644 --- a/source/Rbm.cpp +++ b/source/Rbm.cpp @@ -265,18 +265,17 @@ void Rbm::cd_jens(arma::mat const &v_states, arma::mat &dw, arma::mat &dbh, arma arma::mat h_probs = toHiddenProbs(v_states); arma::mat h_states; - // Sample hidden - if (m_params.doGaussianHidden) - { - h_states = h_probs + arma::randn(h_probs.n_rows, h_probs.n_cols); - } - else if (m_params.doRaoBlackwell) + // Sample hidden. Rao-Blackwellization uses the mean for the positive-phase + // gradient (lower variance) regardless of unit type; previously a Gaussian + // hidden unit always got the noisy sample here even with doRaoBlackwell + // set, ignoring the flag and adding avoidable gradient variance. + if (m_params.doRaoBlackwell) { h_states = h_probs; } else { - h_states = sample(h_probs); + h_states = sampleHidden(h_probs); } // Update weights (positive phase)