22. ResNet, Residual Connections and TorchVision¶
Understand why very deep neural networks become difficult to optimize, how Residual Networks (ResNet) solve this problem using skip connections, how residual blocks work, and how pretrained ResNet models are implemented and adapted using TorchVision and PyTorch.
๐ฏ Learning Objectives¶
After completing this chapter, you will be able to:
- Understand the limitations of simply making CNNs deeper
- Explain the degradation problem in very deep networks
- Understand residual learning
- Explain skip connections
- Understand the mathematical formulation of a residual block
- Understand identity mappings
- Understand projection shortcuts
- Explain BasicBlock and Bottleneck architectures
- Understand ResNet-18, ResNet-34, ResNet-50, ResNet-101, and ResNet-152
- Compare ResNet architectures
- Understand why ResNet enabled much deeper CNNs
- Use pretrained ResNet models with TorchVision
- Replace the ResNet classification head
- Freeze and unfreeze ResNet layers
- Fine-tune ResNet for custom Computer Vision tasks
- Understand ResNet tensor shapes
- Understand Batch Normalization inside ResNet
- Understand the role of ReLU in residual blocks
- Build a custom residual block using PyTorch
- Use ResNet for feature extraction
- Use ResNet as a Transfer Learning backbone
- Understand ResNet training and optimization
- Analyze common ResNet mistakes
- Evaluate ResNet models for production workloads
- Understand the relationship between ResNet and modern CNN architectures
๐ Overview¶
As CNNs became deeper, researchers expected additional layers to provide greater representational power.
However, simply adding more layers did not always improve performance.
A deeper network could suffer from:
Residual Networks introduced a simple but powerful idea:
Instead of forcing a layer stack to learn an entire transformation, allow it to learn a residual function relative to its input.
This is implemented using:
The resulting architecture is known as:
Residual Network โ ResNet
๐ง Why Do We Need ResNet?¶
Consider:
Adding layers should theoretically allow:
But in practice, very deep plain networks can become harder to optimize.
This creates the:
โ The Degradation Problem¶
The degradation problem does not simply mean overfitting.
A deeper plain network may have:
even though it has:
This indicates an optimization problem.
๐ง Plain CNN vs ResNet¶
Plain CNN¶
Every layer must learn the transformation required to produce the next representation.
ResNet¶
โโโโโโโโโโโโโโโโโโโโโโโ
โ โ
Input โโโโโโโโโผโโโโโโโบ Addition โโโโโผโโโบ Output
โ โ โฒ โ
โ โ โ โ
โโโโบ Conv โโบ ReLU โโบ Conv โโโโโโโโ
The original input can bypass the convolutional layers.
๐ง Residual Learning¶
Instead of directly learning:
[ H(x) ]
the residual block learns:
[ F(x)=H(x)-x ]
Therefore:
[ H(x)=F(x)+x ]
where:
The network learns:
๐ง Core ResNet Idea¶
Input x
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โผ โ
Residual Function F(x) โ
โ โ
โผ โ
โโโโโโโโโโโโบ Add โโโโโโโโโ
โ
โผ
H(x)
This simple addition is the foundation of ResNet.
๐ง Residual Block¶
A basic residual block can be represented as:
Input
โ
โโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โผ โ
Conv โ
โ โ
BatchNorm โ
โ โ
ReLU โ
โ โ
Conv โ
โ โ
BatchNorm โ
โ โ
โโโโโโโโโโโโบ Add โโโโโโ
โ
โผ
ReLU
โ
โผ
Output
๐ง Residual Block Architecture¶
flowchart TD
INPUT["Input x"]
CONV1["3ร3 Convolution"]
BN1["Batch Normalization"]
RELU1["ReLU"]
CONV2["3ร3 Convolution"]
BN2["Batch Normalization"]
ADD["Addition"]
RELU2["ReLU"]
OUTPUT["Output"]
INPUT --> CONV1
CONV1 --> BN1
BN1 --> RELU1
RELU1 --> CONV2
CONV2 --> BN2
BN2 --> ADD
INPUT --> ADD
ADD --> RELU2
RELU2 --> OUTPUT
๐ง Skip Connection¶
The skip connection is the path that bypasses the residual transformation.
Input
โ
โโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โผ โ
Conv โ BN โ ReLU โ Conv โ BN
โ
โผ
Addition
โฒ
โ
Skip Connection
The skip connection is sometimes called:
๐ง Why Does the Skip Connection Help?¶
The shortcut provides a direct path for information and gradients.
Without a shortcut:
With a shortcut:
Input
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
Layers โโโโโโโโโโโโโโโโโโโโบ Add
โ
โผ
Output
This makes optimization easier for very deep networks.
๐ง Identity Mapping¶
When input and output dimensions are identical, the shortcut can simply be:
[ S(x)=x ]
Then:
[ y=F(x)+x ]
This is called an:
๐ง Projection Shortcut¶
Sometimes the residual branch changes:
The original input can no longer be added directly.
For example:
The dimensions do not match.
A projection shortcut can solve this.
๐ง Projection Shortcut¶
The shortcut can be represented as:
[ S(x)=W_s*x ]
Then:
[ y=F(x)+S(x) ]
๐ง Identity vs Projection Shortcut¶
| Identity Shortcut | Projection Shortcut |
|---|---|
S(x) = x |
S(x) = W_s * x |
| No learned parameters | Learnable parameters |
| Dimensions already match | Dimensions need transformation |
| Very efficient | Adds computation |
| Common inside same-resolution blocks | Used when changing dimensions |
๐ง Residual Block with Projection¶
flowchart TD
INPUT["Input"]
MAIN["Residual Transform"]
PROJ["1ร1 Projection"]
ADD["Addition"]
OUTPUT["Output"]
INPUT --> MAIN
INPUT --> PROJ
MAIN --> ADD
PROJ --> ADD
ADD --> OUTPUT
๐ง Downsampling in ResNet¶
ResNet stages commonly reduce spatial resolution.
For example:
At the same time, channels usually increase:
When this happens, the shortcut path must also transform the dimensions.
๐ง ResNet Stage Pattern¶
flowchart LR
INPUT["Input"]
STEM["Initial Conv"]
S1["Stage 1<br>64 Channels"]
S2["Stage 2<br>128 Channels"]
S3["Stage 3<br>256 Channels"]
S4["Stage 4<br>512 Channels"]
GAP["Global Average Pooling"]
FC["Classifier"]
INPUT --> STEM
STEM --> S1
S1 --> S2
S2 --> S3
S3 --> S4
S4 --> GAP
GAP --> FC
๐ง ResNet Architecture¶
A simplified ResNet architecture:
Input
โ
7 ร 7 Conv
โ
BatchNorm
โ
ReLU
โ
MaxPool
โ
Residual Stage 1
โ
Residual Stage 2
โ
Residual Stage 3
โ
Residual Stage 4
โ
Global Average Pooling
โ
Fully Connected Layer
โ
Output
๐ง ResNet Architecture Landscape¶
flowchart TD
RESNET["ResNet"]
BASIC["BasicBlock"]
BOTTLENECK["Bottleneck"]
R18["ResNet-18"]
R34["ResNet-34"]
R50["ResNet-50"]
R101["ResNet-101"]
R152["ResNet-152"]
RESNET --> BASIC
RESNET --> BOTTLENECK
BASIC --> R18
BASIC --> R34
BOTTLENECK --> R50
BOTTLENECK --> R101
BOTTLENECK --> R152
๐ง ResNet-18¶
ResNet-18 uses the simpler:
architecture.
A simplified stage configuration is:
with residual blocks distributed across these stages.
ResNet-18 is relatively lightweight and is often useful when inference cost matters.
๐ง ResNet-34¶
ResNet-34 also uses:
but contains more residual blocks than ResNet-18.
Conceptually:
This increases representational capacity and computation.
๐ง BasicBlock¶
A simplified BasicBlock contains:
๐ง BasicBlock Diagram¶
flowchart LR
INPUT["Input"]
C1["3ร3 Conv"]
BN1["BN"]
R1["ReLU"]
C2["3ร3 Conv"]
BN2["BN"]
ADD["Add"]
R2["ReLU"]
OUTPUT["Output"]
INPUT --> C1
C1 --> BN1
BN1 --> R1
R1 --> C2
C2 --> BN2
BN2 --> ADD
INPUT --> ADD
ADD --> R2
R2 --> OUTPUT
๐ง Bottleneck Block¶
Deeper ResNet variants such as:
use:
A bottleneck block uses:
๐ง Bottleneck Architecture¶
The first 1 ร 1 convolution reduces or transforms channel dimensions, while the final 1 ร 1 convolution expands them.
๐ง Bottleneck Block Diagram¶
flowchart TD
INPUT["Input"]
C1["1ร1 Conv"]
C2["3ร3 Conv"]
C3["1ร1 Conv"]
SHORT["Shortcut"]
ADD["Addition"]
OUTPUT["Output"]
INPUT --> C1
C1 --> C2
C2 --> C3
C3 --> ADD
INPUT --> SHORT
SHORT --> ADD
ADD --> OUTPUT
๐ง Why Use Bottleneck Blocks?¶
A bottleneck block allows deeper networks to increase depth without making every convolution operate at the highest channel dimension.
Conceptually:
This improves computational efficiency compared with simply stacking wide 3 ร 3 convolutions.
๐ง BasicBlock vs Bottleneck¶
| BasicBlock | Bottleneck |
|---|---|
3ร3 โ 3ร3 |
1ร1 โ 3ร3 โ 1ร1 |
| Used by ResNet-18 | Used by ResNet-50 |
| Used by ResNet-34 | Used by ResNet-101 |
| Simpler | More compute-efficient for deeper models |
| Suitable for shallower ResNets | Suitable for deeper ResNets |
๐ง ResNet Model Comparison¶
| Model | Main Block | Relative Depth | Relative Compute |
|---|---|---|---|
| ResNet-18 | BasicBlock | Low | Low |
| ResNet-34 | BasicBlock | Medium | Medium |
| ResNet-50 | Bottleneck | Higher | Higher |
| ResNet-101 | Bottleneck | Very High | High |
| ResNet-152 | Bottleneck | Extremely High | Very High |
The exact parameter counts and FLOPs depend on implementation and input resolution.
๐ง ResNet-18 vs ResNet-50¶
versus:
The architecture is not simply:
The block design also changes.
๐ง Why Residual Learning Helps¶
Suppose the desired mapping is:
[ H(x) ]
A plain network must directly approximate:
[ H(x) ]
A residual network learns:
[ F(x)=H(x)-x ]
and then:
[ H(x)=F(x)+x ]
If the desired transformation is close to identity:
then:
The residual branch only needs to learn a small modification.
This can make optimization easier.
๐ง Gradient Flow¶
During backpropagation, the shortcut provides a direct computational path.
Conceptually:
Forward:
Input
โ
โโโโโโโโโโโโโโโโบ Shortcut โโโโโโโโโ
โ โ
โผ โผ
Residual Layers โโโโโโโโโโโโโโโโโบ Add
โ
โผ
Output
and:
Backward:
Gradient
โ
โโโโโโโโโโโโโโโโบ Shortcut
โ
โผ
Residual Layers
This helps gradients propagate through deep networks.
๐ง ResNet and Vanishing Gradients¶
Very deep plain networks can suffer from gradient degradation.
Residual connections provide a direct path:
versus:
Residual Network
Layer โโโโโโโโโโโโโโโ
โ โ
Layer โโโโโโโโโโโโโโโค
โ โ
Layer โโโโโโโโโโโโโโโค
โ โ
Add โโโโโโโโโโโโโโโโโ
This architectural shortcut contributes to more stable optimization of deep networks.
๐ง ResNet as a Feature Extractor¶
A pretrained ResNet can be used without its classifier:
This representation can then feed:
๐ง ResNet Transfer Learning¶
flowchart LR
IMAGE["Input Image"]
RESNET["Pretrained ResNet Backbone"]
FEATURES["Feature Vector"]
HEAD["Custom Task Head"]
OUTPUT["Target Prediction"]
IMAGE --> RESNET
RESNET --> FEATURES
FEATURES --> HEAD
HEAD --> OUTPUT
๐ Part I โ TorchVision¶
TorchVision provides pretrained Computer Vision models and utilities for PyTorch.
A typical workflow is:
๐งช Load Pretrained ResNet-18¶
import torch
import torch.nn as nn
from torchvision import models
model = models.resnet18(
weights=models.ResNet18_Weights.DEFAULT
)
The exact weight enum depends on the TorchVision version.
๐ง Inspect the Model¶
You will see major components such as:
These correspond to the major stages of ResNet.
๐ง ResNet Components¶
flowchart LR
INPUT["Input"]
STEM["conv1 + bn1 + relu + maxpool"]
L1["layer1"]
L2["layer2"]
L3["layer3"]
L4["layer4"]
AVG["avgpool"]
FC["fc"]
INPUT --> STEM
STEM --> L1
L1 --> L2
L2 --> L3
L3 --> L4
L4 --> AVG
AVG --> FC
๐งช Replace the Classification Head¶
Suppose the target task contains:
Replace:
๐ง Freeze the Backbone¶
Then:
Now:
๐งช Optimizer¶
This ensures the optimizer updates the classification head only.
๐ง Fine-Tune ResNet Layer 4¶
After the classification head converges:
Now the optimizer can include the trainable parameters:
optimizer = torch.optim.AdamW(
filter(
lambda p: p.requires_grad,
model.parameters()
),
lr=1e-5,
weight_decay=1e-4
)
๐ง ResNet Fine-Tuning Strategy¶
Stage 1
Backbone
โ
Frozen
Head
โ
Trainable
Stage 2
layer4
โ
Trainable
Head
โ
Trainable
Stage 3
More Backbone Layers
โ
Optional Fine-Tuning
๐ง Why Fine-Tune Layer 4 First?¶
Later ResNet layers generally contain more task-specific representations than early layers.
Therefore:
while:
Unfreezing later layers first provides a controlled way to adapt the model.
๐งช TorchVision Preprocessing¶
TorchVision pretrained weights often provide an associated preprocessing configuration.
For example:
Then:
This helps ensure that the input follows the preprocessing expectations of the pretrained weights.
๐ง Why Preprocessing Matters¶
A pretrained model expects a particular input distribution.
Incorrect:
can reduce model performance.
Therefore:
The preprocessing pipeline is part of the model contract.
๐ง ResNet Input Pipeline¶
flowchart LR
IMAGE["Raw Image"]
TRANSFORM["TorchVision Transform"]
TENSOR["Tensor"]
RESNET["ResNet"]
PRED["Prediction"]
IMAGE --> TRANSFORM
TRANSFORM --> TENSOR
TENSOR --> RESNET
RESNET --> PRED
๐ง ResNet Tensor Shapes¶
For a typical ResNet with input:
the internal representation approximately follows:
while channels generally increase:
๐ง ResNet Shape Flow¶
flowchart TD
A["224 ร 224 ร 3"]
B["112 ร 112 ร 64"]
C["56 ร 56 ร 64"]
D["28 ร 28 ร 128"]
E["14 ร 14 ร 256"]
F["7 ร 7 ร 512"]
G["Global Average Pooling"]
H["512 Features"]
A --> B
B --> C
C --> D
D --> E
E --> F
F --> G
G --> H
The exact tensor shapes can vary with architecture and implementation details.
๐ง Global Average Pooling in ResNet¶
Before the final classifier, ResNet uses global average pooling.
Conceptually:
This creates one feature value per channel.
๐ง ResNet Classification¶
Feature Maps
โ
Global Average Pooling
โ
Feature Vector
โ
Fully Connected Layer
โ
Class Logits
๐ง Logits vs Probabilities¶
ResNet's final fc layer produces logits.
For example:
During training with:
you normally provide the raw logits.
Do not apply softmax before CrossEntropyLoss.
๐งช PyTorch Classification Setup¶
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.AdamW(
filter(
lambda p: p.requires_grad,
model.parameters()
),
lr=1e-3,
weight_decay=1e-4
)
๐ง ResNet Training Loop¶
for epoch in range(
epochs
):
model.train()
for images, labels in train_loader:
images = images.to(
device
)
labels = labels.to(
device
)
optimizer.zero_grad()
logits = model(
images
)
loss = criterion(
logits,
labels
)
loss.backward()
optimizer.step()
๐ง ResNet Validation¶
model.eval()
correct = 0
total = 0
with torch.no_grad():
for images, labels in val_loader:
images = images.to(
device
)
labels = labels.to(
device
)
logits = model(
images
)
predictions = logits.argmax(
dim=1
)
correct += (
predictions == labels
).sum().item()
total += labels.size(0)
accuracy = correct / total
๐ง Custom Residual Block¶
Understanding the residual block is more important than simply knowing how to call resnet50().
class ResidualBlock(
nn.Module
):
def __init__(
self,
in_channels,
out_channels,
stride=1
):
super().__init__()
self.conv1 = nn.Conv2d(
in_channels,
out_channels,
kernel_size=3,
stride=stride,
padding=1,
bias=False
)
self.bn1 = nn.BatchNorm2d(
out_channels
)
self.relu = nn.ReLU(
inplace=True
)
self.conv2 = nn.Conv2d(
out_channels,
out_channels,
kernel_size=3,
padding=1,
bias=False
)
self.bn2 = nn.BatchNorm2d(
out_channels
)
if (
stride != 1
or in_channels != out_channels
):
self.shortcut = nn.Sequential(
nn.Conv2d(
in_channels,
out_channels,
kernel_size=1,
stride=stride,
bias=False
),
nn.BatchNorm2d(
out_channels
)
)
else:
self.shortcut = nn.Identity()
def forward(
self,
x
):
identity = self.shortcut(
x
)
out = self.conv1(
x
)
out = self.bn1(
out
)
out = self.relu(
out
)
out = self.conv2(
out
)
out = self.bn2(
out
)
out += identity
out = self.relu(
out
)
return out
๐ง Custom Residual Block Flow¶
flowchart TD
INPUT["Input"]
MAIN1["Conv 3ร3"]
BN1["BatchNorm"]
RELU["ReLU"]
MAIN2["Conv 3ร3"]
BN2["BatchNorm"]
SHORT["Identity / Projection"]
ADD["Add"]
OUTPUT["ReLU Output"]
INPUT --> MAIN1
MAIN1 --> BN1
BN1 --> RELU
RELU --> MAIN2
MAIN2 --> BN2
BN2 --> ADD
INPUT --> SHORT
SHORT --> ADD
ADD --> OUTPUT
๐ง Identity Shortcut in Code¶
When dimensions match:
This means:
No parameters are introduced.
๐ง Projection Shortcut in Code¶
When dimensions differ:
This performs:
๐ง ResNet Block Invariants¶
For residual addition:
must hold.
For example:
But:
This is one of the most important implementation rules for residual networks.
๐ง Residual Addition¶
The addition operation is element-wise:
[ y_i=F(x)_i+x_i ]
Both tensors must have compatible shapes.
๐ง ResNet and Transfer Learning¶
ResNet became one of the most widely used pretrained CNN backbones.
Typical workflow:
Pretrained ResNet
โ
Remove Original Classifier
โ
Add Custom Head
โ
Freeze Backbone
โ
Train Head
โ
Unfreeze Selected Layers
โ
Fine-Tune
๐ง ResNet Transfer Learning Lifecycle¶
flowchart LR
BASE["Pretrained ResNet"]
HEAD["Replace FC"]
FREEZE["Freeze Backbone"]
TRAIN["Train Head"]
UNFREEZE["Unfreeze Layer 4"]
FINETUNE["Fine-Tune"]
EVAL["Evaluate"]
DEPLOY["Deploy"]
BASE --> HEAD
HEAD --> FREEZE
FREEZE --> TRAIN
TRAIN --> UNFREEZE
UNFREEZE --> FINETUNE
FINETUNE --> EVAL
EVAL --> DEPLOY
๐ง ResNet vs Plain CNN¶
| Plain CNN | ResNet |
|---|---|
| Sequential transformations | Residual transformations |
| No shortcut by default | Skip connections |
| Deep networks harder to optimize | Deep networks easier to optimize |
| More susceptible to degradation | Residual learning addresses degradation |
| Simple architecture | More sophisticated architecture |
๐ง ResNet Advantages¶
ResNet provides:
- Better optimization of deep networks
- Effective gradient flow
- Strong feature representations
- Reusable pretrained models
- Strong Computer Vision baseline
- Good Transfer Learning performance
- Multiple depth variants
- Mature ecosystem support
โ ResNet Limitations¶
ResNet is not always the optimal architecture.
Potential limitations include:
- Higher computation than lightweight CNNs
- Larger memory requirements
- Higher inference latency
- More expensive deployment
- Possible overkill for simple tasks
- Newer architectures may provide better efficiency
- CNN inductive biases may be limiting for some global-context tasks
For constrained environments, architectures such as:
may be more appropriate.
๐ง ResNet vs Lightweight Models¶
| ResNet | Lightweight CNN |
|---|---|
| Strong general-purpose backbone | Optimized for constrained environments |
| More computation | Lower computation |
| Larger model | Smaller model |
| Strong accuracy baseline | Strong efficiency |
| Useful for server-side inference | Useful for edge/mobile |
The correct choice depends on:
๐ง ResNet and Vision Transformers¶
ResNet represents a major CNN milestone.
The Computer Vision architecture landscape later expanded toward:
Vision Transformers are covered in:
23. Vision Transformers and CNN-ViT Hybrids.
๐ง ResNet Architecture Landscape¶
flowchart LR
CNN["Classic CNN"]
RESNET["ResNet"]
EFFICIENT["Efficient CNNs"]
VIT["Vision Transformers"]
HYBRID["CNN + ViT"]
CNN --> RESNET
RESNET --> EFFICIENT
RESNET --> VIT
VIT --> HYBRID
EFFICIENT --> HYBRID
๐ง ResNet as a General Vision Backbone¶
ResNet can provide feature representations for:
Image Classification
Object Detection
Semantic Segmentation
Instance Segmentation
Image Retrieval
Visual Similarity
Metric Learning
Anomaly Detection
๐ง ResNet in Object Detection¶
A simplified detection architecture may use:
Image
โ
ResNet Backbone
โ
Feature Maps
โ
Detection Head
โ
Bounding Boxes
+
Class Predictions
The backbone learns reusable visual representations.
๐ง ResNet in Segmentation¶
For segmentation:
ResNet can act as the encoder/backbone.
๐ง ResNet Feature Extraction¶
A pretrained ResNet can generate embeddings:
These vectors can be used for:
๐งช Extract Features with PyTorch¶
import torch
model.eval()
with torch.no_grad():
features = model.avgpool(
model.layer4(
model.layer3(
model.layer2(
model.layer1(
model.maxpool(
model.relu(
model.bn1(
model.conv1(
images
)
)
)
)
)
)
)
)
)
features = torch.flatten(
features,
1
)
In production, prefer a dedicated feature-extractor interface rather than depending on deeply nested internal calls that may vary between architectures.
๐ง Better Feature Extractor Design¶
A cleaner approach is to define a model that explicitly exposes the representation:
class ResNetFeatureExtractor(
nn.Module
):
def __init__(
self,
backbone
):
super().__init__()
self.backbone = backbone
self.backbone.fc = nn.Identity()
def forward(
self,
x
):
return self.backbone(
x
)
Now:
This is easier to integrate into production systems.
๐ง Production ResNet Architecture¶
A production system might look like:
Client
โ
API Gateway
โ
Inference Service
โ
Image Preprocessing
โ
ResNet Model
โ
Prediction
โ
Business Service
๐ข Enterprise ResNet Architecture¶
flowchart TD
CLIENT["Client / Application"]
API["API Gateway"]
SERVICE["Vision Inference Service"]
PREP["Image Preprocessing"]
MODEL["ResNet Model"]
PRED["Prediction"]
BUSINESS["Business Decision"]
MONITOR["Observability"]
CLIENT --> API
API --> SERVICE
SERVICE --> PREP
PREP --> MODEL
MODEL --> PRED
PRED --> BUSINESS
SERVICE --> MONITOR
MODEL --> MONITOR
๐ข Production ResNet Considerations¶
Important concerns include:
Model¶
Inference¶
Infrastructure¶
Operations¶
๐ง ResNet Model Optimization¶
Possible techniques include:
Input Resolution Reduction
Quantization
Pruning
Knowledge Distillation
Batching
GPU Acceleration
Mixed Precision
Model Compilation
These techniques should be evaluated against the required accuracy.
๐ง Accuracy vs Latency Trade-Off¶
Higher Accuracy
โ
โ
โ Large ResNet
โ
โ
โ Medium ResNet
โ
โ Lightweight Model
โโโโโโโโโโโโโโโโโโโโโโ
Latency
The optimal model depends on the application.
For:
higher compute may be acceptable.
For:
latency and memory may dominate.
๐ง ResNet Monitoring¶
A production ResNet system should monitor:
Inference Latency
Throughput
Error Rate
Prediction Distribution
Input Quality
Data Drift
Model Accuracy
Class Distribution
GPU Utilization
Memory Usage
๐ง Model Drift¶
A deployed ResNet can degrade if production images differ from training data.
Examples:
New Camera
Different Lighting
Different Product
New Background
Seasonal Variation
Resolution Change
New Customer Segment
This creates:
๐ง ResNet Retraining¶
flowchart TD
PRODUCTION["Production Images"]
MONITOR["Monitor Predictions"]
DRIFT["Detect Drift"]
LABEL["Collect / Label Data"]
TRAIN["Fine-Tune ResNet"]
VALIDATE["Validate"]
DEPLOY["Deploy New Version"]
PRODUCTION --> MONITOR
MONITOR --> DRIFT
DRIFT --> LABEL
LABEL --> TRAIN
TRAIN --> VALIDATE
VALIDATE --> DEPLOY
DEPLOY --> PRODUCTION
๐งช Practical Exercise 1 โ Load ResNet-18¶
Use TorchVision:
Inspect:
๐งช Practical Exercise 2 โ Replace the Classifier¶
Adapt ResNet-18 for:
Replace:
and verify:
๐งช Practical Exercise 3 โ Feature Extraction¶
Freeze:
Train:
Compare training time and validation performance.
๐งช Practical Exercise 4 โ Fine-Tune Layer 4¶
Unfreeze:
Use a lower learning rate.
Compare:
๐งช Practical Exercise 5 โ Compare ResNet Variants¶
Train:
Compare:
๐งช Practical Exercise 6 โ Residual Block¶
Implement:
from scratch using:
Verify that tensor shapes are compatible before addition.
๐งช Practical Exercise 7 โ Projection Shortcut¶
Create a residual block where:
Implement the projection shortcut.
Verify:
๐งช Practical Exercise 8 โ Feature Extraction¶
Use a pretrained ResNet to generate embeddings.
Then perform:
between image embeddings.
Explore:
๐งช Practical Exercise 9 โ Transfer Learning¶
Build:
Then progressively fine-tune:
and compare performance.
๐งช Practical Exercise 10 โ Production Benchmark¶
Benchmark:
on your target hardware.
Measure:
Determine which architecture provides the best production trade-off.
๐ง Interview Questions¶
Beginner¶
1. What is ResNet?¶
ResNet is a family of Deep CNN architectures that use residual connections to make very deep networks easier to optimize.
2. What is a residual connection?¶
A residual connection provides a shortcut path that adds the input to the output of a learned transformation.
3. What is the basic residual equation?¶
[ y=F(x)+x ]
4. What problem does ResNet address?¶
It primarily addresses the optimization degradation encountered when making plain CNNs increasingly deep.
5. What is a BasicBlock?¶
A residual block typically containing two 3 ร 3 convolutions with normalization and activation.
6. What is a Bottleneck block?¶
A residual block typically using:
to make deeper networks more computationally practical.
Intermediate¶
7. What is a skip connection?¶
A shortcut that bypasses one or more layers and is combined with the residual branch.
8. When is an identity shortcut possible?¶
When the residual branch and input have compatible dimensions.
9. When is a projection shortcut required?¶
When spatial dimensions or channel dimensions need to change.
10. Why is a 1 ร 1 convolution used in projection shortcuts?¶
It can transform channel dimensions and, with stride, perform spatial downsampling.
11. Why are ResNet-50 and deeper models based on bottleneck blocks?¶
Bottleneck blocks provide a computationally efficient way to build much deeper networks.
12. What is the difference between ResNet-18 and ResNet-50?¶
ResNet-18 uses BasicBlocks, while ResNet-50 uses Bottleneck blocks and is substantially deeper and more computationally expensive.
Advanced¶
13. Why does residual learning make optimization easier?¶
It provides shortcut paths for information and gradients and allows the residual branch to learn modifications relative to the input rather than necessarily learning the complete mapping directly.
14. What happens if the residual branch learns zero?¶
Then:
[ F(x)=0 ]
and:
[ y=x ]
The block can therefore represent an identity mapping.
15. Why must tensor shapes match before residual addition?¶
Element-wise addition requires compatible tensor dimensions.
16. Why can ResNet still overfit?¶
Residual connections improve optimization, but they do not eliminate the fundamental risk of excessive model capacity relative to the target dataset.
17. Why is fine-tuning ResNet usually done with a small learning rate?¶
Because the pretrained backbone already contains useful representations and large updates may destroy them.
18. Why might ResNet-18 be preferable to ResNet-152?¶
When:
are more important than the additional representational capacity of a much deeper model.
19. What is the purpose of Global Average Pooling?¶
It converts spatial feature maps into one representative value per channel, reducing the need for a large fully connected classification head.
20. How would you use ResNet for image similarity?¶
Remove or bypass the classification head, extract feature embeddings, and compare embeddings using an appropriate similarity metric such as cosine similarity.
21. How would you optimize ResNet for production inference?¶
Consider:
Input Resolution
Batching
Quantization
Mixed Precision
Model Compilation
Hardware
Model Variant
Memory
Latency
Throughput
22. How would you detect whether a deployed ResNet is becoming unreliable?¶
Monitor:
Input Distribution
Prediction Distribution
Data Drift
Model Performance
Latency
Error Rate
Class Distribution
๐ข Enterprise Perspective¶
ResNet is important not only because of its architecture but because it became a highly reusable Computer Vision backbone.
A single pretrained ResNet can support many enterprise applications:
Image Classification
โ
Object Detection
โ
Image Retrieval
โ
Similarity Search
โ
Visual Inspection
โ
Anomaly Detection
This makes ResNet a useful bridge between:
๐ข Enterprise ResNet Platform¶
A reusable enterprise vision platform can expose the model behind a capability interface:
The ResNet implementation becomes one model adapter behind the capability.
Conceptually:
flowchart LR
APP["Enterprise Application"]
API["Vision Capability"]
PROVIDER["Vision Model Provider"]
RESNET["ResNet Adapter"]
OTHER["Other Vision Model"]
APP --> API
API --> PROVIDER
PROVIDER --> RESNET
PROVIDER --> OTHER
This separates:
from:
and makes model replacement easier.
๐ข Model Versioning¶
A production ResNet deployment should track:
Model Architecture
Model Version
Pretrained Weight Version
Fine-Tuning Dataset
Dataset Version
Training Configuration
Code Version
Evaluation Metrics
Deployment Version
For example:
๐ข Production ResNet Lifecycle¶
flowchart TD
REQUIREMENTS["Business Requirements"]
DATA["Enterprise Image Data"]
BASE["Select Pretrained ResNet"]
TRAIN["Feature Extraction / Fine-Tuning"]
VALIDATE["Offline Validation"]
BENCHMARK["Latency / Cost Benchmark"]
REGISTRY["Model Registry"]
DEPLOY["Production Deployment"]
MONITOR["Production Monitoring"]
DRIFT["Drift Detection"]
RETRAIN["Retraining"]
REQUIREMENTS --> DATA
DATA --> BASE
BASE --> TRAIN
TRAIN --> VALIDATE
VALIDATE --> BENCHMARK
BENCHMARK --> REGISTRY
REGISTRY --> DEPLOY
DEPLOY --> MONITOR
MONITOR --> DRIFT
DRIFT --> RETRAIN
RETRAIN --> TRAIN
Production Insight
ResNet is more than a CNN architecture. It is a reusable representation-learning backbone.
In production, the right question is not:
but:
```text Which model provides the required
Accuracy +
Latency + Throughput + Memory Efficiency + Cost + Reliability ```
for the actual production workload?
ResNet-18 may be the right choice for a latency-sensitive application, while ResNet-50 may provide a better accuracy/compute balance for server-side inference.
๐ Key Takeaways¶
- ResNet introduced residual learning to make very deep CNNs easier to optimize.
- Residual blocks learn a transformation relative to the input.
- The core formulation is
y = F(x) + x. - Skip connections provide direct information and gradient paths.
- Identity shortcuts are used when tensor dimensions already match.
- Projection shortcuts use learnable transformations when dimensions need to change.
1 ร 1convolutions are commonly used for projection and channel transformation.- ResNet commonly reduces spatial resolution while increasing channel depth.
- ResNet-18 and ResNet-34 use BasicBlocks.
- ResNet-50, ResNet-101, and ResNet-152 use Bottleneck blocks.
- Bottleneck blocks use
1 ร 1 โ 3 ร 3 โ 1 ร 1convolutions. - Global Average Pooling reduces feature maps to compact representations.
- ResNet models are widely useful for Transfer Learning.
- TorchVision provides pretrained ResNet implementations for PyTorch.
- The original classification head can be replaced for custom tasks.
- Feature extraction can freeze the ResNet backbone.
- Fine-tuning can progressively unfreeze later layers.
- Fine-tuning generally requires smaller learning rates than head training.
- Correct preprocessing is part of the pretrained model contract.
- ResNet can serve as a backbone for classification, detection, segmentation, and embedding applications.
- Production ResNet systems should be evaluated for accuracy, latency, throughput, memory, and cost.
- Model monitoring should include input drift and prediction behavior.
- ResNet provides an important foundation for understanding modern Computer Vision architectures.
๐ Further Reading¶
Continue with:
- 23. Vision Transformers and CNN-ViT Hybrids
- 35. GPU-Accelerated Deep Learning
- 36. Deep Learning Training and Model Lifecycle
- 37. Building Production Deep Learning Systems
The next chapter explores Vision Transformers (ViT) and CNN-ViT hybrid architectures, introducing the transition from convolution-based visual representation learning toward attention-based Computer Vision models.
โก๏ธ Next Chapter¶
23. Vision Transformers and CNN-ViT Hybrids
Enterprise AI Engineering Handbook
Building Production-Grade Enterprise AI Systems โ One Chapter at a Time.