ResNet50 is a 50-layer convolutional neural network that turns images into increasingly abstract visual features. Its defining feature is the residual connection: a shortcut carries an input around one or more layers and adds it to their output. This helps preserve information and makes deep networks easier to train when vanishing gradients would otherwise interfere. section 13.3.1
An image passes through an initial convolution and max pooling, then four groups of residual blocks built from bottleneck units. Each bottleneck contains three convolutions and a shortcut. Average pooling and a fully connected layer follow. In its original ImageNet classifier, the output is 1,000 class logits; softmax converts them to probabilities. section 13.3.1
There are two practical ways to reuse those learned features:
- For a CLIP-style image encoder, load pretrained ResNet50 through timm with its classification head removed and average pooling enabled. Freeze its parameters, obtain one 2,048-value feature vector per image, then use a projection head to make a 256-value image embedding. Contrastive learning aligns those embeddings with text embeddings from DistilBERT. section 8.1.1 section 8.3.2
- For real-versus-fake classification, retain the pretrained feature extractor but replace its 1,000-class head with a two-logit head. Freeze the original weights and train the new head on labeled images; this avoids learning general visual features from scratch. section 13.3.2 section 13.4
Listing 13.7 Replacing the output head in ResNet50
for param in model.parameters():
param.requires_grad = False #1
model.fc= torch.nn.Sequential(
torch.nn.Linear(2048,1000),
torch.nn.ReLU(),
torch.nn.Linear(1000,500),
torch.nn.Dropout(),
torch.nn.Linear(in_features=500,
out_features=2,
bias=True)).to(device) #2
num_trainable=sum([p.numel() for p in model.parameters()
if p.requires_grad])
print(f"Number of trainable parameters: {num_trainable}")
non_trainable=sum([p.numel() for p in model.parameters()
if not p.requires_grad])
print(f"""Number of untrainable parameters:
{non_trainable}""") #3
The replacement-head listing shows the key operation: disable gradients for existing parameters, assign a new `model.fc`, and check which parameters remain trainable. Its final layer produces two logits. section 13.4.2
To run the pretrained classifier, load the default torchvision weights, call `eval()`, and apply the transforms paired with those weights. Add a batch dimension, run inference without gradients, apply softmax, and map the highest-scoring index to an ImageNet label. For the new two-class head, train with cross-entropy, monitor validation loss, and stop if it fails to improve for three consecutive epochs. section 13.3.3 section 13.4.2
What a prediction does—and does not—say
A sample fish image receives the label “goldfish.” Other predictions can reflect the limits of ImageNet’s 1,000 categories: a bird resembling a kingfisher may be labeled “bee eater” when “kingfisher” is unavailable. Read the probability alongside the available labels, not as a guarantee that every possible object was considered. section 13.3.3
