PyTorch allows users to build neural networks and evaluate their performance using different loss functions like MAE, MSE, and KL Divergence. The Kullback-Leibler (KL) Divergence loss measures the distance between the probability distributions of correct and incorrect predictions. PyTorch provides torch.nn.KLDivLoss() for this purpose, while Keras provides the equivalent kl_divergence loss argument in compile().

Quick Answer: To calculate KL Divergence loss in PyTorch, use nn.KLDivLoss() with an MLP model, or pass loss='kl_divergence' to Keras’ model.compile() for a Sequential model. Both approaches measure how closely the predicted probability distribution matches the true distribution.

Sequential vs MLP Neural Network for KL Divergence

This guide covers two model architectures for computing KL Divergence loss. Here’s a quick comparison before diving in:

Feature Sequential Model MLP Model (nn.Module)
Framework Keras/TensorFlow PyTorch (torch.nn)
Loss function compile(loss='kl_divergence') nn.KLDivLoss()
Architecture style Linear stack — one input, one output per step Fully connected layers with feedforward pass
Best for Streaming data, time series, quick prototyping Image data, custom architectures, full PyTorch pipelines
Optimizer used Adam via string argument torch.optim.Adam()

Model 1: Using Sequential Neural Network

The Sequential model processes data in a strict sequence — one input produces one output. It works efficiently for streaming data like time series and strings.

Step 1: Access Python Notebook

Open a Python environment using Jupyter or Google Colab. This guide uses Google Colaboratory:

Google Colaboratory homepage for creating a new Python notebook to run the KL Divergence loss code

Step 2: Import Libraries

import torch
from keras.layers import Dense
from sklearn.datasets import make_circles
from keras.models import Sequential
from matplotlib import pyplot
from numpy import where
  • torch — deep learning library with methods for model training and loss computation.
  • Keras — Google-built API for building and stacking neural network layers.
  • sklearn — Python machine learning library for dataset generation and splitting.
  • Matplotlib — visualization library for plotting loss and accuracy curves.
  • NumPy — array library used here to build conditional logic on the dataset.

Step 3: Build the Dataset

a, b = make_circles(n_samples=1000, noise=0.1, random_state=1)
for i in range(2):
    samples_ix = where(b == i)
    pyplot.scatter(a[samples_ix, 0], a[samples_ix, 1])
pyplot.show()
Scatter plot of make_circles dataset showing two concentric rings of data points in different colors

Step 4: Split into Training and Testing Samples

n_test = 500
traina = a[:n_test]
testa = a[n_test:]
trainb = b[:n_test]
testb = b[n_test:]

Step 5: Build the Sequential Model

model = Sequential()
model.add(Dense(100, input_shape=(2,), activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='kl_divergence', optimizer='adam', metrics=['accuracy'])
  • A 100-neuron hidden layer with ReLU activation introduces non-linearity.
  • The output layer uses Sigmoid to produce a probability in the range [0, 1].
  • The kl_divergence loss measures how far predictions diverge from true labels.
  • Adam optimizer adapts the learning rate dynamically during training.

Step 6: Fit and Evaluate the Model

result = model.fit(traina, trainb, validation_data=(testa, testb), epochs=30, verbose=0)

_, train_acc = model.evaluate(traina, trainb, verbose=1)
_, test_acc = model.evaluate(testa, testb, verbose=1)
Sequential model evaluation showing training and test loss values close to zero and near-equal — model is well balanced

Similar training and test loss values close to zero indicate a well-balanced, accurate model — both key indicators of good generalization.

Step 7: Plot the Loss Curve

pyplot.subplot(211)
pyplot.title('Loss')
pyplot.plot(result.history['loss'], label='train')
pyplot.plot(result.history['val_loss'], label='test')
pyplot.legend()
pyplot.show()
Line graph showing Sequential model KL Divergence training and validation loss converging toward zero over 30 epochs

Model 2: Using MLP Neural Network

The MultiLayer Perceptron (MLP) model uses fully connected neurons across all layers. Each layer’s output feeds as the next layer’s input in a feedforward approach.

Step 1: Import Libraries

import torch
from torch import nn
from torchvision.datasets import FakeData
from torch.utils.data import DataLoader
from torchvision import transforms

Step 2: Configure the MLP Model

class MLP(nn.Module):

  def __init__(self):
    super().__init__()
    self.layers = nn.Sequential(
      nn.Flatten(),
      nn.Linear(28 * 28 * 3, 64),
      nn.ReLU(),
      nn.Linear(64, 32),
      nn.ReLU(),
      nn.Linear(32, 1),
      nn.Sigmoid()
    )

  def forward(self, x):
    return self.layers(x)

Step 3: Build and Load the Dataset

if __name__ == '__main__':
    torch.manual_seed(42)
    dataset = FakeData(size=15000, image_size=(3, 28, 28), num_classes=2, transform=transforms.ToTensor())
    trainloader = torch.utils.data.DataLoader(dataset, batch_size=64, shuffle=True, num_workers=4, pin_memory=True)

Step 4: Initialize the KLDivLoss Function

mlp = MLP()
kl = nn.KLDivLoss()
optimizer = torch.optim.Adam(mlp.parameters(), lr=1e-4)

Step 5: Train the Model

for epoch in range(0, 3):
    print(f'Starting epoch {epoch+1}')
    current_loss = 0

    for i, data in enumerate(trainloader, 0):
      inputs, targets = data
      targets = targets \
                .type(torch.FloatTensor) \
                .reshape((targets.shape[0], 1))

      optimizer.zero_grad()
      outputs = mlp(inputs)
      loss = kl(outputs, targets)
      loss.backward()
      optimizer.step()
      current_loss += loss.item()
      if i % 10 == 0:
          print('Loss after mini-batch %5d: %.3f' %
                (i + 1, current_loss / 500))
          current_loss = 0.0

print('\n Training process has finished')
MLP model training output showing KL Divergence loss values per mini-batch decreasing over 3 epochs toward zero

Loss values near zero confirm that the MLP model’s predictions closely match the true probability distribution.

Conclusion

To calculate KL Divergence loss of neural networks in PyTorch, use nn.KLDivLoss() with an MLP model or Keras’ compile(loss='kl_divergence') for a Sequential model. Both approaches evaluate how far the model’s predicted probability distribution deviates from the true distribution — loss values close to zero indicate accurate, well-generalized predictions. Use the Sequential model for quick prototyping with Keras, and the MLP with nn.KLDivLoss() for full PyTorch control over training loops and architectures.