liveBook · Manning

Decode

As explained in Causal AI

A neural decoder is a neural network component that maps a latent or compressed representation to an output representation.

How can a causal model generate an image when the effects of its causes are too complex for a simple conditional probability table? A neural decoder supplies a nonlinear mapping from causes to an output. In a variational autoencoder (VAE), it takes a latent encoding Z and observed labels, then produces parameters for an image distribution. It acts as a model of the image’s causal Markov kernel—not as proof that Z captures the image’s actual unobserved causes. section 5.2.2

Encoding runs in the opposite direction: an encoder uses an image and its labels to infer a distribution over Z. Decoding uses a sampled Z and the labels to reconstruct an image or generate a new one. The labels specify modeled causes; Z stands in for variation not explicitly modeled, such as differences among writers. section 5.2.2 section 5.2.3

Listing 5.4 Implement the decoder
from torch import nn

class Decoder(nn.Module):    #1
    def __init__(self, z_dim, hidden_dim):
        super().__init__()
        img_dim = 28 * 28     #2
        digit_dim = 10    #3
        is_handwritten_dim = 1    #4
        self.softplus = nn.Softplus()     #5
        self.sigmoid = nn.Sigmoid()    #5
        encoding_dim = z_dim + digit_dim + is_handwritten_dim     #6
        self.fc1 = nn.Linear(encoding_dim, hidden_dim)   #6
        self.fc2 = nn.Linear(hidden_dim, img_dim)    #7

    def forward(self, z, digit, is_handwritten):     #8
        input = torch.cat([z, digit, is_handwritten], dim=1) #9
        hidden = self.softplus(self.fc1(input))    #10
        img_param = self.sigmoid(self.fc2(hidden))    #11
        return img_param

The PyTorch implementation concatenates Z, a ten-component digit label, and a handwritten indicator. A hidden layer and sigmoid output yield 784 image parameters for a 28 × 28 image. section 5.2.2

A decoder’s output has different jobs in the workflow:

  • During training, the encoder’s approximate posterior supplies Z; the decoder’s output parameterizes the image likelihood. Stochastic variational inference trains both networks using negative ELBO, rather than reconstruction error alone. section 5.2.3
  • During evaluation, compare an original image with its reconstruction, inspect newly generated images, and track test loss. These checks reveal whether image quality improves during training. section 5.2.4
  • In a VAE-inspired causal inference model, separate decoders map a latent proxy and other inputs to distribution parameters for engagement and purchases; the decoder need not output an image. section 11.6.4

Changing a shape while retaining inferred variation

For a dSprites image, an encoder infers an image-specific exogenous representation from the image and its causal factors. A pretrained decoder maps that representation plus factors such as shape back toward an image. Counterfactual generation changes the shape factor to a heart and uses the decoder within the image assignment function. This is a proof of concept: the factors are independent and the images simple, so broader counterfactual use requires additional assumptions. section 9.4.1

Listing 9.29 Create an exogenous distribution and assignment function for the image
def p_n_image(n_image_params):    #1
    n_image_loc, n_image_scale, n_unif_upper = n_image_params     #2
    n_image_norm = dist.Normal(     #3
        n_image_loc, n_image_scale     #3
    ).to_event(1).sample()     #3
    n_image_unif = dist.Uniform(0, n_unif_upper).expand(     #4
        torch.Size([1, 64*64])    #4
    ).sample()    #4
    n_image = n_image_norm, n_image_unif    #5
    return n_image

def f_image(factor, n_image):    #6
    n_image_norm, n_image_unif = n_image     #7
    p_output = decoder.forward(     #8
        n_image_norm,     #8
        encode_one_hot(factor)     #8
    )
    sim_img = (n_image_unif <= p_output).int()     #9
    return sim_img

The assignment function shows a useful distinction: the decoder produces image probabilities, while additional sampled noise turns them into simulated pixel values. section 9.4.1

How Causal AI covers it

How deep it goes
Works through a PyTorch decoder, variational training, evaluation, and a pretrained counterfactual application; flags assumptions needed beyond simple images.
Examples
Uses labeled digit reconstruction, randomly generated images, dSprites shape changes, and engagement and purchase distribution models.
What it assumes
Builds on causal DAGs and conditional distributions while defining the VAE, encoder, decoder, and latent Z in context.
What you can do after
Build it from scratch with PyTorch and Pyro for labeled-image generation, then evaluate reconstructions and generated images.
How it connects
Connects variational autoencoders, encoders, latent variables, causal DAGs, causal Markov kernels, and counterfactual inference.

Also explained in

Compare how 15 books explain decode →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Causal AI. The section links point to the parts of the book it draws on.