struct Dcgan {
struct ConvNet gen;
struct ConvNet genEma;
struct ConvNet disc;
struct Optimizer optG;
struct Optimizer optD;
struct GanConfig cfg;
struct Rng rng;
struct TensorArena stepArena;
unsigned long steps;
}Gan with a ConvNet generator and discriminator you build (convnet.h). G takes the latent batch as a latent x 1 x 1 input and must output the data's size; D takes a data row ([CHW], CHW order) and must output one score. Reads latent, loss, lrG, lrD, nCritic, clip, classes, emaDecay and seed from the config (hidden, hiddenLayers, genAct and outAct describe the nets you built and are ignored). classes > 0 makes it a conditional DCGAN: G gets the one-hot label appended to its noise (latent + classes inputs), D gets it as 'classes' extra input channels, one constant plane per class (tensor_append_label_channels) -- so for C-channel images D takes C + classes channels. Takes ownership of both nets. Training steps run the nets in training mode (batch norm on batch statistics); Dcgan::sample and Dcgan::score in inference mode.
struct ConvNet gen = ConvNet::new(latent, 1UL, 1UL);
gen.deconv(64UL, 4UL, 1UL, 0UL, ACT_NONE, &rng); // 64 x 4 x 4
gen.batchnorm(ACT_RELU);
gen.deconv(32UL, 4UL, 2UL, 1UL, ACT_NONE, &rng); // 32 x 8 x 8
gen.batchnorm(ACT_RELU);
gen.deconv(1UL, 4UL, 2UL, 1UL, ACT_TANH, &rng); // 1 x 16 x 16
struct ConvNet disc = ConvNet::new(1UL, 16UL, 16UL);
disc.conv(32UL, 4UL, 2UL, 1UL, ACT_LEAKY, &rng); // 32 x 8 x 8
disc.conv(64UL, 4UL, 2UL, 1UL, ACT_NONE, &rng); // 64 x 4 x 4
disc.batchnorm(ACT_LEAKY);
disc.conv(1UL, 4UL, 1UL, 0UL, ACT_NONE, &rng); // 1 x 1 x 1
struct Dcgan g = Dcgan::new(gen, disc, &cfg);
Fields
Methods
'labels' (m class indices) for a conditional DCGAN, else null -- as for Gan.
struct GanLosses train(const &Dataset data, unsigned long epochs, unsigned long batchSize)source · definitionheap tensor, caller frees
Parameterized (module.h): G's and D's parameters; the state adds the averaged generator (and a Dcgan's buffers).
= drop()