pulsatrix
Loading...
Searching...
No Matches
pulsatrix::Reparameterize Class Reference

VAE reparameterization trick (Kingma & Welling 2013, arXiv:1312.6114), z[b,d] = mu[b,d] + exp(log_sigma[b,d]) * epsilon[b,d]. More...

#include <reparameterize.hpp>

Public Member Functions

 Reparameterize (DeviceBackend *backend)
 Constructs a reparameterization step.
 
Tensor forward (const Tensor &mu, const Tensor &log_sigma, const Tensor &epsilon)
 Computes z = mu + exp(log_sigma) * epsilon, caching log_sigma/epsilon for backward().
 
ReparamGrad backward (const Tensor &grad_z) const
 Gradients w.r.t. mu and log_sigma, given the gradient w.r.t. z. grad_mu = grad_z; grad_log_sigma = grad_z * exp(log_sigma) * epsilon.
 

Detailed Description

VAE reparameterization trick (Kingma & Welling 2013, arXiv:1312.6114), z[b,d] = mu[b,d] + exp(log_sigma[b,d]) * epsilon[b,d].

Note
Not a Module subclass. Module::forward is a single-tensor-in/single-tensor-out contract; this operation takes three tensors (two learned, one sampled) and would have to be deformed to fit. It therefore mirrors MSELoss's shape instead – forward(...) computes and caches, backward() consumes the cache – which is this codebase's established pattern for a computation that is genuinely not a layer. Deliberate design decision (mission_vae_module.md's "Design decision" section), not an oversight, and independent of the LRP note below.
No LRP rule. VAE's own research spike found that no credible native rule exists in the literature: stochastic reparameterization plus the dual (reconstruction + KL) loss structure breaks the single-deterministic-seed-point assumption every LRP rule in this codebase relies on. There is nothing to stub either, since this is not a Module. See the campaign's Phase 5 Amendment (2026-09-23).
epsilon is caller-supplied, never sampled internally. That keeps this class deterministic and therefore finite-difference testable; wiring real Gaussian sampling (e.g. std::normal_distribution) into a demo is separate, out-of-scope future work – the same disposition as RNNModule's h_0 = 0 being a scope cut, not a missing feature.

Constructor & Destructor Documentation

◆ Reparameterize()

pulsatrix::Reparameterize::Reparameterize ( DeviceBackend *  backend)
explicit

Constructs a reparameterization step.

Parameters
backendBackend to allocate/compute through. Not owned; must outlive this object.

Member Function Documentation

◆ backward()

ReparamGrad pulsatrix::Reparameterize::backward ( const Tensor &  grad_z) const

Gradients w.r.t. mu and log_sigma, given the gradient w.r.t. z. grad_mu = grad_z; grad_log_sigma = grad_z * exp(log_sigma) * epsilon.

Parameters
grad_zGradient w.r.t. this step's output. Must match the cached shape.
Returns
Both gradients, each the shape of the mu passed to forward().
Exceptions
std::logic_errorif forward() has never been called – uses the cached log_sigma/epsilon.
std::invalid_argumentif grad_z's shape doesn't match the cached forward shape.
Note
Device-generic: runs on Cpu, Cuda or Hip tensors (GPU-native-kernels Mission 1b); inputs must share one device.

◆ forward()

Tensor pulsatrix::Reparameterize::forward ( const Tensor &  mu,
const Tensor &  log_sigma,
const Tensor &  epsilon 
)

Computes z = mu + exp(log_sigma) * epsilon, caching log_sigma/epsilon for backward().

Parameters
muMean tensor, shape (N, latent_dim).
log_sigmaLog-standard-deviation tensor. Must match mu's shape.
epsilonSampled noise, supplied by the caller. Must match mu's shape.
Returns
The sampled latent z, same shape as mu.
Exceptions
std::invalid_argumentif the three shapes don't all match – external boundary, same classification as MSELoss::forward's prediction/target shape check.
Note
Device-generic: runs on Cpu, Cuda or Hip tensors (GPU-native-kernels Mission 1b); inputs must share one device.

The documentation for this class was generated from the following file: