v9.1.1
Menu

Gram Matrix for Style

hardPRONeural Style TransferStyle TransferCV: Computational Photography

Implement a function to compute the Gram matrix for neural style transfer, which is a crucial component in capturing the style of an image. This task involves understanding how to represent the style of an image using feature maps extracted from a Convolutional Neural Network (CNN).

The Gram matrix is used to capture the style by computing correlations between feature maps, where the input features is a 3D array of shape (C,H,W)(C, H, W), the output of a CNN layer with CC channels, height HH, and width WW. Each channel's H×WH \times W grid is flattened into a vector, giving the feature map FF of shape (C,H×W)(C, H \times W). The Gram matrix GG is a 2D tensor that represents the correlations between these feature maps.

Here are the steps to compute the Gram matrix:

  1. Extract the feature map FF from a CNN layer.
  2. Compute the correlations between the feature maps. The Gram matrix GG can be computed using the formula Gij=∑kFikFjkG_{ij} = \sum_k F_{ik} F_{jk}, which represents the dot product of the ithi^{th} and jthj^{th} feature maps. The result is then normalized by the total number of elements C⋅H⋅WC \cdot H \cdot W:
Gij=1C⋅H⋅W∑kFikFjkG_{ij} = \frac{1}{C \cdot H \cdot W} \sum_k F_{ik} F_{jk}

Return GG as a (C,C)(C, C) array.

The style loss LstyleL_{style} is then computed as the squared difference between the Gram matrix of the content image and the Gram matrix of the style image: Lstyle=∥Gcontent−Gstyle∥2L_{style} = \|G_{content} - G_{style}\|^2.

This technique is widely used in image generation and editing tasks.

Example

Input
features = CNN activations shape (64, 32, 32)
Output
Gram matrix shape (64, 64)
Reasoning
  • features holds C=64C = 64 channels, each a 32×3232 \times 32 grid of activations. Read each channel's grid as one vector of H⋅W=1024H \cdot W = 1024 numbers; channel ii becomes row FiF_i, so FF is 64×102464 \times 1024.
  • Entry GijG_{ij} is the dot product of channel ii's vector with channel jj's: ∑k=11024FikFjk\sum_{k=1}^{1024} F_{ik} F_{jk}. It is large when the two channels fire at the same spatial positions.
  • Every pair (i,j)(i, j) of the 64 channels gets one entry, so the result is 64×6464 \times 64, matching the output Gram matrix shape (64, 64). The spatial size disappears entirely.
  • Divide by C⋅H⋅W=64⋅1024=65536C \cdot H \cdot W = 64 \cdot 1024 = 65536. Check with all-ones activations: each raw dot product is 10241024, and 1024/65536=0.015625=1/641024 / 65536 = 0.015625 = 1/64.
  • Notice GG is symmetric (Gij=GjiG_{ij} = G_{ji}) and its diagonal GiiG_{ii} is channel ii's energy, never negative. Shuffling pixel positions identically in all channels leaves GG unchanged, which is why it captures style rather than layout.

Constraints

  • features: Feature maps from CNN (C, H, W)
  • Return: Gram matrix (C, C)

Learn this in

More from CV: Computational Photography

PRO

Editor locked

The code editor is locked for Pro problems. It is only available for free problems. Please upgrade to gain access to the code editor for all problems.

solution.py

Test results

Sign in to run your code against the test cases.