# ViT-B/16

> Vision Transformer — patch embedding stem + 1 encoder block (768D, 12 heads)

Pick for 224px+ images when pretrained weights are available, or when dataset is large enough (>1M images) to train from scratch.

- Category: Computer Vision
- Layers: 13
- Parameters: 8.45M
- Input shape (batchless): 3 × 224 × 224
- Output shape: 196 × 1000
- Verifier verdict: pass
- Graph JSON: https://neurarch.com/templates/vit-b16/model.json
- Open on the canvas: https://neurarch.com/?template=vit-b16

## Structure

| # | Layer | Type | Parameters | Output shape |
| --- | --- | --- | --- | --- |
| 1 | image | Input | shape=[3, 224, 224] | 3 × 224 × 224 |
| 2 | patch_embed | Patch Embed | embedDim=768, patchSize=16 | 196 × 768 |
| 3 | pos_embed | Positional Encoding | embedDim=768, maxLen=197 | 196 × 768 |
| 4 | dropout | Dropout | p=0 | 196 × 768 |
| 5 | norm_1 | LayerNorm | normalizedShape=768 | 196 × 768 |
| 6 | attn | Multi-Head Attention | embedDim=768, numHeads=12 | 196 × 768 |
| 7 | residual_1 | Add |  | 196 × 768 |
| 8 | norm_2 | LayerNorm | normalizedShape=768 | 196 × 768 |
| 9 | mlp | Feed Forward | ffDim=3072 | 196 × 768 |
| 10 | residual_2 | Add |  | 196 × 768 |
| 11 | norm_final | LayerNorm | normalizedShape=768 | 196 × 768 |
| 12 | head | Linear | outFeatures=1000 | 196 × 1000 |
| 13 | class_logits | Output |  | 196 × 1000 |

## Verifier findings

- **info** `dropout-before-bn` at `dropout`: "dropout" → "norm_1": BatchNorm re-normalizes the random zeros introduced by Dropout, nullifying most of its regularization effect. Fix: Reorder to Conv → BN → Activation → Dropout.

## Exported PyTorch (first 46 lines)

```python
# Architecture designed with Neurarch: https://neurarch.com
# PyTorch: compatible with Python 3.8+ and torch>=1.12
# Colab: pip install torch torchvision  (usually pre-installed)

import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Tuple

class ViT_B16(nn.Module):
    def __init__(self):
        super().__init__()

        self.patchEmbed_1 = nn.Conv2d(3, 768, kernel_size=16, stride=16)  # Patch embedding (ViT-style)
        self.dropout_1 = nn.Dropout(p=0.5)
        self.layerNorm_1 = nn.LayerNorm(768)
        self.multiHeadAttention_1 = nn.MultiheadAttention(embed_dim=768, num_heads=12, batch_first=True)
        self.layerNorm_2 = nn.LayerNorm(768)
        self.feedForward_1 = nn.Sequential(
            nn.Linear(768, 3072),
            nn.ReLU(),
            nn.Linear(3072, 768)
        )
        self.layerNorm_3 = nn.LayerNorm(768)
        self.linear_1 = nn.Linear(768, 1000)

    def forward(self, x):
        # image shape: [3,224,224]
        patch_embed_mbed_1 = self.patchEmbed_1(x).flatten(2).transpose(1, 2)  # [B, num_patches, embed_dim]
        # positionalEncoding: add positional encoding externally (e.g. sinusoidal or learned PE)
        dropout_pout_1 = self.dropout_1(patch_embed_mbed_1)
        layer_norm_Norm_1 = self.layerNorm_1(dropout_pout_1)
        multi_head_attention_tion_1 = self.multiHeadAttention_1(layer_norm_Norm_1, layer_norm_Norm_1, layer_norm_Norm_1)[0]
        add_add_1 = multi_head_attention_tion_1 + dropout_pout_1
        layer_norm_Norm_2 = self.layerNorm_2(add_add_1)
        feed_forward_ward_1 = self.feedForward_1(layer_norm_Norm_2)
        add_add_2 = feed_forward_ward_1 + add_add_1
        layer_norm_Norm_3 = self.layerNorm_3(add_add_2)
        linear_near_1 = self.linear_1(layer_norm_Norm_3)
        # Output
        return linear_near_1


if __name__ == '__main__':
    model = ViT_B16()
    model.eval()
```

## Machine access

- Every architecture: https://neurarch.com/a/index.json
- Verify a graph of your own: `POST https://www.neurarch.com/api/v1/check` (see https://neurarch.com/developer.html)
- MCP server, so an agent edits the graph with the checks in the loop: https://neurarch.com/docs/mcp.md
