Vision Transformer › Image Patching: From Pixels to Sequences

Michael BrenndoerferFebruary 7, 20265 min read
Language AI HandbookAll chapters
Part 50 of 67Multimodal Models
Chapter 381Vision Transformer › Image Patching: From Pixels to Sequences
Reading section 2 of 14 · Image Patching: From Pixels to Sequences · 5 minSection 2 of 14 · 5 min

Book contents

Section 2 of 14 · 5 min read

Vision Transformer › Image Patching: From Pixels to SequencesOne section · Sections in this chapter2 / 14 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

The fundamental challenge in applying transformers to images is a dimensional mismatch between what the architecture expects and how visual data is structured. A standard transformer encoder expects input as a sequence of vectors X∈RN×D\mathbf{X} \in \mathbb{R}^{N \times D}, where NN is the sequence length and DD is the embedding dimension. A typical image, however, arrives as a 3D tensor I∈RH×W×C\mathbf{I} \in \mathbb{R}^{H \times W \times C} representing height and width plus color channels. This structural difference poses an immediate problem: transformers process sequences, while images are inherently two-dimensional grids with channel information.

The solution ViT adopts is elegant in its simplicity: reshape the image into a sequence by dividing it into a regular grid of fixed-size square patches. Each patch is flattened into a single vector by concatenating all pixel values across spatial locations and color channels. These flattened vectors then serve as the input sequence to the transformer, with each patch playing the role that a word token plays in a language model.

The Patching Operation in Detail

Consider a standard input image of size 224×224224 \times 224 pixels with 3 color channels (RGB). If we choose a patch size of P=16P = 16 pixels per side, the patching proceeds as follows. First, we divide the image into a 14×1414 \times 14 grid of non-overlapping patches, since 224/16=14224 / 16 = 14 patches fit along each spatial dimension. The total number of patches is:

N=HP×WP=22416×22416=14×14=196N = \frac{H}{P} \times \frac{W}{P} = \frac{224}{16} \times \frac{224}{16} = 14 \times 14 = 196

Each individual patch is a 16×16×316 \times 16 \times 3 sub-image containing 16×16×3=76816 \times 16 \times 3 = 768 values. We flatten this 3D sub-image into a 1D vector by concatenating all pixel values in row-major order across height and width for every channel. More precisely, for the patch at grid position (r,c)(r, c) where r,c∈{0,1,…,13}r, c \in \{0, 1, \ldots, 13\}, we extract:

x(r,c)=flatten ⁣(I[r⋅P:(r+1)⋅P,  c⋅P:(c+1)⋅P,  :])∈RP2⋅C\mathbf{x}^{(r,c)} = \text{flatten}\!\left(\mathbf{I}[r \cdot P : (r+1) \cdot P,\; c \cdot P : (c+1) \cdot P,\; :]\right) \in \mathbb{R}^{P^2 \cdot C}

where:

  • x(r,c)∈RP2⋅C\mathbf{x}^{(r,c)} \in \mathbb{R}^{P^2 \cdot C}: the flattened patch vector at grid row rr, grid column cc
  • I[r⋅P:(r+1)⋅P,c⋅P:(c+1)⋅P,:]\mathbf{I}[r \cdot P : (r+1) \cdot P, c \cdot P : (c+1) \cdot P, :]: the slice of the image tensor corresponding to the patch at position (r,c)(r, c), with all channels included
  • PP: the patch size (number of pixels per side, e.g., 16)
  • CC: the number of color channels (3 for RGB)
  • flatten(⋅)\text{flatten}(\cdot): the operation that reshapes a P×P×CP \times P \times C tensor into a vector of length P2⋅CP^2 \cdot C

We then flatten the 2D grid of patches into a 1D sequence by linearizing the grid positions. Conventionally, this is done in row-major order: patches in the first row of the grid appear first in the sequence, followed by patches in the second row, and so on. Patch (r,c)(r, c) gets sequence index i=r×(W/P)+ci = r \times (W/P) + c. We now have a sequence [x(1),x(2),…,x(N)][\mathbf{x}^{(1)}, \mathbf{x}^{(2)}, \ldots, \mathbf{x}^{(N)}] of N=196N = 196 vectors, each of dimension 768. This is a sequence length and dimensionality comparable to what standard language transformers process, making the same architecture applicable with minimal modification.

It is worth pausing to appreciate what has been lost and what has been retained in this transformation. We have retained the pixel values of every region of the image; no information has been discarded or aggregated. What we have lost is the explicit 2D spatial structure. The sequence representation no longer encodes the fact that patch 1 is adjacent to patch 2 horizontally, or that patch 15 lies directly below patch 1. The transformer receives an unordered bag of patch vectors with positional indices, and it must learn from those indices and from training data which patches are spatially related. This is the inductive bias gap that we will discuss in depth later.

Patch Size Trade-offs

The choice of patch size involves fundamental trade-offs that affect both computational efficiency and model capacity:

  • Smaller patches (e.g., 8×88 \times 8): Produce longer sequences (28×28=78428 \times 28 = 784 patches for a 224×224224 \times 224 image), capturing finer spatial resolution and preserving more detail. However, self-attention has O(N2)O(N^2) complexity, so quadrupling patch count leads to roughly 16 times more attention computation.
  • Larger patches (e.g., 32×3232 \times 32): Produce shorter sequences (7×7=497 \times 7 = 49 patches), reducing computational cost significantly, but at the expense of fine-grained spatial detail. Individual patches encompass more image area, potentially obscuring small objects or fine textures within a single token.

Standard ViT models use 16×1616 \times 16 patches as a balanced compromise. ViT variants optimized for high-resolution tasks (such as detection and segmentation) often use 8×88 \times 8 patches and pair them with efficient attention mechanisms to manage the quadratic cost.

The patching approach also imposes an implicit tokenization granularity. A word token in NLP typically carries semantic content: the word "cat" has a meaning that the model can use directly. A 16×1616 \times 16 patch of pixels, by contrast, often contains no clear semantic unit. It might span the boundary between a cat's ear and the background, or contain only a uniform textured region with no object at all. This means patch-level representations start at a much lower semantic level than word tokens, requiring the model to learn compositional semantics through attention across patches, rather than beginning with semantically meaningful units. This is another reason why ViT needs more data: it must learn both low-level visual features and their high-level composition, whereas NLP models begin with tokens that already carry semantic weight encoded by the vocabulary.