Replace non-overlapping stride=32 with stride=16 (50% overlap) throughout.
Add assemble_overlapping() which accumulates reconstructed patches into a
float buffer and averages contributions per pixel, eliminating blocking artefacts.
Update load_image_patches to return nx_steps/ny_steps for correct reassembly.
Add start parameter to load_patches for held-out test image selection.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extracts non-overlapping 32x32 RGB patches from face images using SubImage,
trains a GB-RBM (3072 visible, 128 hidden), and visualises learned filters,
patch reconstructions, and full image reconstruction.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- train.py: grad_zero() was called inside the epoch loop, resetting momentum
to zero before every update — momentum had no effect in the default full-batch
case. Moved outside the loop so momentum accumulates across epochs.
- train.py: cd_gaussian_gaussian: use mean h for weight updates and sampled h
to drive the negative visible reconstruction (same pattern as cd_gaussian_binary fix).
Remove spurious Gaussian noise added to data_neg before computing h_probs_neg.
- matrix.py: rms_error divided by d_err_squared[1] (row 1) instead of
d_err_squared.shape[1] (column count).
- label.py: _dec_binary used reversed() on a CuPy array — replaced with np.flip().
label2vec_onehot now returns np.stack() array instead of a Python list.
vec2label_onehot implemented via np.argmax (was returning None).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In cd_gaussian_binary, two CD formulation bugs:
1. Gaussian noise was incorrectly added to data_neg before computing h_probs_neg
2. Negative visible reconstruction used h_probs_pos (soft probabilities) instead
of sampled binary hidden states, biasing the fantasy particle toward the mean
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>