computer_vision.vision_transformer¶
Vision Transformer (ViT) for Image Classification
This module implements the Vision Transformer architecture as described in the paper “An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale” by Dosovitskiy et al. (2020)
Paper: https://arxiv.org/abs/2010.11929
The Vision Transformer splits an image into fixed-size patches, linearly embeds each patch, adds position embeddings, and feeds the resulting sequence of vectors to a standard Transformer encoder. For classification, a learnable classification token is prepended to the sequence.
Author: devvratpathak
Attributes¶
Functions¶
|
Add learnable positional encodings to patch embeddings. |
|
Compute scaled dot-product attention. |
|
Split an image into non-overlapping patches. |
|
Apply position-wise feed-forward network. |
|
Apply Layer Normalization. |
|
Linearly project flattened patches to embedding dimension. |
|
Apply a single Transformer encoder block. |
|
Apply Vision Transformer for image classification. |
Module Contents¶
- computer_vision.vision_transformer.add_positional_encoding(embeddings: numpy.ndarray, num_positions: int | None = None) numpy.ndarray¶
Add learnable positional encodings to patch embeddings.
- Args:
embeddings: Embedded patches of shape (num_patches, embedding_dim) num_positions: Number of positions (if None, uses num_patches + 1 for CLS token)
- Returns:
Embeddings with positional encoding of shape (num_positions, embedding_dim)
- Examples:
>>> embeddings = np.random.rand(4, 768) >>> pos_embeddings = add_positional_encoding(embeddings) >>> pos_embeddings.shape (5, 768)
>>> embeddings = np.random.rand(196, 512) >>> pos_embeddings = add_positional_encoding(embeddings) >>> pos_embeddings.shape (197, 512)
- computer_vision.vision_transformer.attention_mechanism(query: numpy.ndarray, key: numpy.ndarray, value: numpy.ndarray, mask: numpy.ndarray | None = None) tuple[numpy.ndarray, numpy.ndarray]¶
Compute scaled dot-product attention.
Attention(Q, K, V) = softmax(QK^T / sqrt(d_k))V
- Args:
query: Query matrix of shape (seq_len, d_k) key: Key matrix of shape (seq_len, d_k) value: Value matrix of shape (seq_len, d_v) mask: Optional attention mask
- Returns:
A tuple containing: - output: Attention output of shape (seq_len, d_v) - attention_weights: Attention weights of shape (seq_len, seq_len)
- Examples:
>>> q = np.random.rand(10, 64) >>> k = np.random.rand(10, 64) >>> v = np.random.rand(10, 64) >>> output, weights = attention_mechanism(q, k, v) >>> output.shape (10, 64) >>> weights.shape (10, 10) >>> np.allclose(weights.sum(axis=1), 1.0) True
- computer_vision.vision_transformer.create_patches(image: numpy.ndarray, patch_size: int = 16) tuple[numpy.ndarray, tuple[int, int]]¶
Split an image into non-overlapping patches.
- Args:
image: Input image array of shape (height, width, channels) patch_size: Size of each square patch (default: 16)
- Returns:
A tuple containing: - patches: Array of shape (num_patches, patch_size, patch_size, channels) - grid_size: Tuple (height_patches, width_patches) representing the grid
- Examples:
>>> img = np.random.rand(32, 32, 3) >>> patches, grid = create_patches(img, patch_size=16) >>> patches.shape (4, 16, 16, 3) >>> grid (2, 2)
>>> img = np.random.rand(224, 224, 3) >>> patches, grid = create_patches(img, patch_size=16) >>> patches.shape (196, 16, 16, 3) >>> grid (14, 14)
- computer_vision.vision_transformer.feedforward_network(embeddings: numpy.ndarray, hidden_dim: int = 3072) numpy.ndarray¶
Apply position-wise feed-forward network.
FFN(x) = max(0, xW1 + b1)W2 + b2
- Args:
embeddings: Input array of shape (seq_len, embedding_dim) hidden_dim: Hidden dimension size (default: 3072, typically 4x embedding_dim)
- Returns:
Output array of shape (seq_len, embedding_dim)
- Examples:
>>> embeddings = np.random.rand(10, 768) >>> output = feedforward_network(embeddings, hidden_dim=3072) >>> output.shape (10, 768)
>>> embeddings = np.random.rand(197, 512) >>> output = feedforward_network(embeddings, hidden_dim=2048) >>> output.shape (197, 512)
- computer_vision.vision_transformer.layer_norm(embeddings: numpy.ndarray, epsilon: float = 1e-06) numpy.ndarray¶
Apply Layer Normalization.
- Args:
embeddings: Input array of shape (seq_len, embedding_dim) epsilon: Small constant for numerical stability (default: 1e-6)
- Returns:
Normalized array of same shape as input
- Examples:
>>> embeddings = np.random.rand(10, 768) >>> normalized = layer_norm(embeddings) >>> normalized.shape (10, 768) >>> np.allclose(normalized.mean(axis=1), 0.0, atol=1e-6) True >>> np.allclose(normalized.std(axis=1), 1.0, atol=1e-6) True
- computer_vision.vision_transformer.patch_embedding(patches: numpy.ndarray, embedding_dim: int = 768) numpy.ndarray¶
Linearly project flattened patches to embedding dimension.
- Args:
- patches: Array of patches with shape
(num_patches, patch_size, patch_size, channels)
embedding_dim: Dimension of the embedding space (default: 768)
- Returns:
Embedded patches of shape (num_patches, embedding_dim)
- Examples:
>>> patches = np.random.rand(4, 16, 16, 3) >>> embeddings = patch_embedding(patches, embedding_dim=768) >>> embeddings.shape (4, 768)
>>> patches = np.random.rand(196, 16, 16, 3) >>> embeddings = patch_embedding(patches, embedding_dim=512) >>> embeddings.shape (196, 512)
- computer_vision.vision_transformer.transformer_encoder_block(embeddings: numpy.ndarray, num_heads: int = 12, hidden_dim: int = 3072) numpy.ndarray¶
Apply a single Transformer encoder block.
The block consists of: 1. Multi-head self-attention with residual connection and layer norm 2. Feed-forward network with residual connection and layer norm
- Args:
embeddings: Input array of shape (seq_len, embedding_dim) num_heads: Number of attention heads (default: 12, kept for API) hidden_dim: Hidden dimension for FFN (default: 3072)
- Returns:
Output array of shape (seq_len, embedding_dim)
- Examples:
>>> embeddings = np.random.rand(197, 768) >>> output = transformer_encoder_block( ... embeddings, num_heads=12, hidden_dim=3072 ... ) >>> output.shape (197, 768)
>>> embeddings = np.random.rand(50, 512) >>> output = transformer_encoder_block( ... embeddings, num_heads=8, hidden_dim=2048 ... ) >>> output.shape (50, 512)
- computer_vision.vision_transformer.vision_transformer(image: numpy.ndarray, patch_size: int = 16, embedding_dim: int = 768, num_layers: int = 12, num_heads: int = 12, hidden_dim: int = 3072, num_classes: int = 1000) numpy.ndarray¶
Apply Vision Transformer for image classification.
Architecture: 1. Split image into patches 2. Linear projection of flattened patches 3. Add positional embeddings 4. Pass through Transformer encoder layers 5. Extract CLS token and apply classification head
- Args:
image: Input image array of shape (height, width, channels) patch_size: Size of each patch (default: 16) embedding_dim: Embedding dimension (default: 768) num_layers: Number of Transformer layers (default: 12) num_heads: Number of attention heads (default: 12) hidden_dim: Hidden dimension in FFN (default: 3072) num_classes: Number of output classes (default: 1000)
- Returns:
Class logits of shape (num_classes,)
- Examples:
>>> img = np.random.rand(224, 224, 3) >>> logits = vision_transformer(img, patch_size=16, num_classes=10) >>> logits.shape (10,)
>>> img = np.random.rand(32, 32, 3) >>> logits = vision_transformer( ... img, patch_size=16, embedding_dim=512, num_layers=6, num_classes=100 ... ) >>> logits.shape (100,)
- computer_vision.vision_transformer.rng¶