Files
Rbm/source/matutils.hpp
T
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

107 lines
2.4 KiB
C++

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: matutils.hpp
* Author: jens
*
* Created on 21. Januar 2022, 08:28
*/
#ifndef MATUTILS_HPP
#define MATUTILS_HPP
#include "RnnTextHelper.hpp"
#include <math.h>
namespace Matutils
{
const size_t NORMALIZING_DIM = 1;
inline arma::mat uniform(arma::mat const & sizeMat, double stdDev=1.0, double mu=0.5)
{
return stdDev*(arma::randu(arma::size(sizeMat)) + mu - 0.5);
}
inline arma::mat sample(const arma::mat &src)
{
arma::umat res = (src > uniform(src));
return arma::conv_to<arma::mat>::from(res);
}
// src holds a Gaussian unit's mean; returns a stochastic sample around it.
// Binary-thresholding a continuous Gaussian activation (via sample() above)
// is meaningless, so Gaussian-visible/hidden units need this instead.
inline arma::mat sample_gaussian(const arma::mat &src)
{
return src + arma::randn(arma::size(src));
}
inline arma::mat prob(const arma::mat &src)
{
return 1 / (1 + (arma::exp(-src)));
}
inline arma::mat normalize(const arma::mat& src)
{
std::cout << "Normalizing Training Data ..." << std::endl;
// Dim = 0: Normalize over training all training pattern
// Dim = 1: Normalize over single training pattern
double k = 1;
arma::mat mean = arma::mean(src, NORMALIZING_DIM);
arma::mat stddev = arma::stddev(src, 0, NORMALIZING_DIM);
arma::mat mean_mat;
arma::mat std_mat;
if (NORMALIZING_DIM==0)
{
mean_mat = arma::repmat(mean, src.n_rows, 1);
std_mat = arma::repmat(stddev, src.n_rows, 1);
}
else
{
mean_mat = arma::repmat(mean, 1, src.n_cols);
std_mat = arma::repmat(stddev, 1, src.n_cols);
}
arma::mat xn = src - mean_mat;
arma::mat y = xn/(std_mat + 1e-9);
return y;
}
inline arma::mat mean(const arma::mat& src)
{
return arma::mean(src, NORMALIZING_DIM);
}
inline arma::mat stddev(const arma::mat& src)
{
return arma::stddev(src, 0, NORMALIZING_DIM);
}
inline arma::mat char2vec(char c, size_t len)
{
arma::mat result = arma::zeros(1, len);
int idx = RnnTextHelper::ch2idx(c);
result[idx] = 1;
return result;
}
inline char vec2char(arma::mat const &vec)
{
char result = RnnTextHelper::idx2ch(vec.index_max());
return result;
}
}
#endif /* MATUTILS_HPP */