Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
kernelSize: 5,
strides: 2,
padding: 'same',
activation: 'tanh',
kernelInitializer: 'glorotNormal'
}));
// Unlike most TensorFlow.js models, the generator part of an ACGAN has
// two inputs:
// 1. The latent vector that is used as the "seed" of the fake image
// generation.
// 2. A class label that controls which of the ten MNIST digit classes
// the generated fake image is meant to belong to.
// This is the z space commonly referred to in GAN papers.
const latent = tf.input({shape: [latentSize]});
// The desired label of the generated image, an integer in the interval
// [0, NUM_CLASSES).
const imageClass = tf.input({shape: [1]});
// The desired label is converted to a vector of length `latentSize`
// through embedding lookup.
const classEmbedding = tf.layers.embedding({
inputDim: NUM_CLASSES,
outputDim: latentSize,
embeddingsInitializer: 'glorotNormal'
}).apply(imageClass);
// Hadamard product between z-space and a class conditional embedding.
const h = tf.layers.multiply().apply([latent, classEmbedding]);
kernelInitializer: 'glorotNormal'
}));
// Unlike most TensorFlow.js models, the generator part of an ACGAN has
// two inputs:
// 1. The latent vector that is used as the "seed" of the fake image
// generation.
// 2. A class label that controls which of the ten MNIST digit classes
// the generated fake image is meant to belong to.
// This is the z space commonly referred to in GAN papers.
const latent = tf.input({shape: [latentSize]});
// The desired label of the generated image, an integer in the interval
// [0, NUM_CLASSES).
const imageClass = tf.input({shape: [1]});
// The desired label is converted to a vector of length `latentSize`
// through embedding lookup.
const classEmbedding = tf.layers.embedding({
inputDim: NUM_CLASSES,
outputDim: latentSize,
embeddingsInitializer: 'glorotNormal'
}).apply(imageClass);
// Hadamard product between z-space and a class conditional embedding.
const h = tf.layers.multiply().apply([latent, classEmbedding]);
const fakeImage = cnn.apply(h);
return tf.model({inputs: [latent, imageClass], outputs: fakeImage});
}
cnn.add(tf.layers.leakyReLU({alpha: 0.2}));
cnn.add(tf.layers.dropout({rate: 0.3}));
cnn.add(tf.layers.conv2d(
{filters: 128, kernelSize: 3, padding: 'same', strides: 2}));
cnn.add(tf.layers.leakyReLU({alpha: 0.2}));
cnn.add(tf.layers.dropout({rate: 0.3}));
cnn.add(tf.layers.conv2d(
{filters: 256, kernelSize: 3, padding: 'same', strides: 1}));
cnn.add(tf.layers.leakyReLU({alpha: 0.2}));
cnn.add(tf.layers.dropout({rate: 0.3}));
cnn.add(tf.layers.flatten());
const image = tf.input({shape: [IMAGE_SIZE, IMAGE_SIZE, 1]});
const features = cnn.apply(image);
// Unlike most TensorFlow.js models, the discriminator has two outputs.
// The 1st output is the probability score assigned by the discriminator to
// how likely the input example is a real MNIST image (as versus
// a "fake" one generated by the generator).
const realnessScore =
tf.layers.dense({units: 1, activation: 'sigmoid'}).apply(features);
// The 2nd output is the softmax probabilities assign by the discriminator
// for the 10 MNIST digit classes (0 through 9). "aux" stands for "auxiliary"
// (the namesake of ACGAN) and refers to the fact that unlike a standard GAN
// (which performs just binary real/fake classification), the discriminator
// part of ACGAN also performs multi-class classification.
const aux = tf.layers.dense({units: NUM_CLASSES, activation: 'softmax'})
.apply(features);
function buildCombinedModel(latentSize, generator, discriminator, optimizer) {
// Latent vector. This is one of the two inputs to the generator.
const latent = tf.input({shape: [latentSize]});
// Desired image class. This is the second input to the generator.
const imageClass = tf.input({shape: [1]});
// Get the symbolic tensor for fake images generated by the generator.
let fake = generator.apply([latent, imageClass]);
let aux;
// We only want to be able to train generation for the combined model.
discriminator.trainable = false;
[fake, aux] = discriminator.apply(fake);
const combined =
tf.model({inputs: [latent, imageClass], outputs: [fake, aux]});
combined.compile({
optimizer,
loss: ['binaryCrossentropy', 'sparseCategoricalCrossentropy']
});
combined.summary();
return combined;
}
function buildCombinedModel(latentSize, generator, discriminator, optimizer) {
// Latent vector. This is one of the two inputs to the generator.
const latent = tf.input({shape: [latentSize]});
// Desired image class. This is the second input to the generator.
const imageClass = tf.input({shape: [1]});
// Get the symbolic tensor for fake images generated by the generator.
let fake = generator.apply([latent, imageClass]);
let aux;
// We only want to be able to train generation for the combined model.
discriminator.trainable = false;
[fake, aux] = discriminator.apply(fake);
const combined =
tf.model({inputs: [latent, imageClass], outputs: [fake, aux]});
combined.compile({
optimizer,
loss: ['binaryCrossentropy', 'sparseCategoricalCrossentropy']
});
combined.summary();