Lecture 12
Department of Intelligent Systems, University of Lahore
This lecture is the hinge between classical CV (weeks 1–11) and deep learning (weeks 13–15).
Before deep networks, detection was solved by scanning a classifier over the image at many positions and scales — the sliding-window paradigm.
Complexity: for an W×H image, S scales and a w×h window, you evaluate on the order of S·W·H windows — this is why classical detectors demanded very cheap per-window features and classifiers.
Gx, Gy) and per-pixel orientation/magnitude.import cv2
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
boxes, weights = hog.detectMultiScale(
frame, winStride=(8, 8), padding=(8, 8), scale=1.05)
cv2.HOGDescriptor_getDefaultPeopleDetector() ships a pretrained linear SVM in OpenCV.O(pixels); the integral image \(I_\Sigma(x,y)=\sum_{x'\le x,\,y'\le y} I(x',y')\) lets any rectangle sum be computed in O(1) with 4 lookups.face_cascade = cv2.CascadeClassifier(
cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
Note: cv2.CascadeClassifier's constructor signature changes in OpenCV 5.0 — see Lecture 14.
K clusters — the cluster centres form a visual vocabulary / codebook.K-bin histogram of codeword occurrences — this is the image's feature vector, fed to a classifier (SVM, k-NN).BoVW discards all spatial layout — two images with the same features scattered differently look identical to it.
HOG / Haar / BoVW Neural network
engineer designs the network LEARNS the
feature extractor → feature extractor
(fixed, by hand) (trained, from data)
The rest of this lecture builds the machinery — perceptron, MLP, loss, back-propagation, optimisers — that lets a network learn its own features. Lecture 13 scales this up to convolutional networks.
loss.backward()) implements exactly this.error
│ \ ___ val error (overfit gap)
│ \ ___-''
│ \__ ___-----
│ ''---___--- ___ train error
│____________________________________ model capacity / epochs
under-fit ↑ sweet spot over-fit
class SmallCNN(nn.Module):
def __init__(self, num_classes):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 16, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(16, 32, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(32, 64, 3, padding=1), nn.ReLU(), nn.AdaptiveAvgPool2d(1))
self.head = nn.Linear(64, num_classes)
def forward(self, x):
return self.head(self.features(x).flatten(1))
crit = nn.CrossEntropyLoss()
opt = torch.optim.Adam(model.parameters(), lr=1e-3)
for x, y in train_loader:
opt.zero_grad()
loss = crit(model(x), y)
loss.backward() # back-propagation
opt.step() # Adam update
Full trainer with a real train/val loop: applied-cv-course/code/ml/train_classifier_pytorch.py.
optimizer.zero_grad() — gradients silently accumulate across batches.model.eval() / torch.no_grad() at validation time — dropout/batch-norm behave differently in train vs. eval mode, and you waste memory tracking gradients you'll never use.Lab 12 — Deep Learning: Classification & YOLO Detection.
Deliverable: a trained custom classifier + a custom YOLO detector running on the Raspberry Pi.
Intelligent Vision Systems; University of Lahore | Dr. Muhammad Kazim