# Simple CNN

> Simple Convolutional Neural Network for image classification

Pick as a fast baseline for small images (≤64px, e.g. CIFAR). Trains in minutes, easy to debug — use before reaching for ResNet.

- Category: Computer Vision
- Layers: 9
- Parameters: 804.6K
- Input shape (batchless): 1 × 28 × 28
- Output shape: 10
- Verifier verdict: pass
- Graph JSON: https://neurarch.com/templates/simple-cnn/model.json
- Open on the canvas: https://neurarch.com/?template=simple-cnn

## Structure

| # | Layer | Type | Parameters | Output shape |
| --- | --- | --- | --- | --- |
| 1 | Input | Input | shape=[1, 28, 28] | 1 × 28 × 28 |
| 2 | Conv2D_1 | Conv2D | outChannels=32, kernelSize=3, stride=1 | 32 × 28 × 28 |
| 3 | ReLU_1 | ReLU |  | 32 × 28 × 28 |
| 4 | MaxPool2D_1 | MaxPool2D | kernelSize=2, stride=2 | 32 × 14 × 14 |
| 5 | Flatten | Flatten |  | 6272 |
| 6 | Linear_1 | Linear | outFeatures=128 | 128 |
| 7 | ReLU_2 | ReLU |  | 128 |
| 8 | Linear_2 | Linear | outFeatures=10 | 10 |
| 9 | Output | Output |  | 10 |

## Verifier findings

- **info** `deep-no-norm`: 7 layers with no BatchNorm, LayerNorm, or GroupNorm. Without normalization, activations can explode or vanish across layers, causing slow or unstable training. Fix: Add BatchNorm after Conv2d (CV tasks), LayerNorm after attention/FFN (NLP/LLM), or GroupNorm for small batch sizes.

## Exported PyTorch

```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 SimpleCNN(nn.Module):
    def __init__(self):
        super().__init__()

        self.conv2d_1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)
        self.maxpool2d_1 = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)
        self.linear_1 = nn.Linear(6272, 128)
        self.linear_2 = nn.Linear(128, 10)

    def forward(self, x):
        # Input shape: [1,28,28]
        conv2d_nv2d_1 = self.conv2d_1(x)
        relu_relu_1 = F.relu(conv2d_nv2d_1)
        maxpool2d_ol2d_1 = self.maxpool2d_1(relu_relu_1)
        flatten_tten_1 = torch.flatten(maxpool2d_ol2d_1, 1)
        linear_near_1 = self.linear_1(flatten_tten_1)
        relu_relu_2 = F.relu(linear_near_1)
        linear_near_2 = self.linear_2(relu_relu_2)
        # Output
        return linear_near_2


if __name__ == '__main__':
    model = SimpleCNN()
    model.eval()

    x = torch.randn(1, 28, 28)  # (batch, seq_len, embed_dim)
    with torch.no_grad():
        output = model(x)

    print(f'Input  shape : {tuple(x.shape)}')
    print(f'Output shape : {tuple(output.shape)}')
    total = sum(p.numel() for p in model.parameters())
    trainable = sum(p.numel() for p in model.parameters() if p.requires_grad)
    print(f'Parameters   : {total:,} total, {trainable:,} trainable')
```

## 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
