Pulse2Pulse GAN — Visual Guide¶
Pulse2Pulse is a WaveGAN-style GAN. It turns noise with the same shape as an ECG into an ECG,
using a 1-D U-Net generator. A large convolutional critic scores real and generated ECGs, and
training uses the WGAN-GP objective. Code: src/ecgen/families/gan/pulse2pulse.py.
Written reference: Pulse2Pulse GAN.
Adversarial setup¶
Generator: a 1-D U-Net¶
Six strided convolutions (kernel 25) compress the noise from length 5000 down to 2. The decoder upsamples it back, and at four resolutions it concatenates the encoder features of the same length (skip connections). Hover over a layer:
model_size = 50, num_channels = 8. The total stride is 2·5·2·5·5·5 = 2500, so seq_length must be a multiple of 2500.Critic: WaveGANDiscriminator¶
Phase shuffle¶
After each of the first six critic convolutions, PhaseShuffle(2) shifts every example in the batch
by a random k ∈ {−2, …, 2} samples and fills the gap with reflection padding. This stops the critic
from judging ECGs by the exact sample-level phase of upsampling artefacts:
How the losses are computed¶
Training uses manual optimisation with two Adam optimisers (lr = 1e-4, betas = (0.5, 0.9)).
The gradient-penalty interpolation¶
The penalty is evaluated at random points on straight lines between real and generated ECGs:
Update schedule¶
Validation does not update anything. It logs val/d_wasserstein = D(x) − D(G(z)) and
val_loss = −val/d_wasserstein, which is used for checkpointing.