Computer Vision mit PyTorch 2026: CNNs, Transfer Learning und Fragen im Vorstellungsgespräch

Computer Vision mit PyTorch: CNNs entwickeln, Transfer Learning mit vortrainierten Modellen anwenden und auf technische Interviews vorbereiten.

Computer Vision mit PyTorch 2026: CNNs, Transfer Learning und Fragen im Vorstellungsgespräch

Computer Vision mit PyTorch hat sich 2026 als dominierender Ansatz für Bildklassifizierung, Objekterkennung und visuelle Erkennungsaufgaben etabliert. Dieses Tutorial behandelt den Aufbau von CNNs von Grund auf, die Anwendung von Transfer Learning mit vortrainierten Modellen und die Vorbereitung auf technische Interviewfragen.

PyTorch 2.4 Performance

PyTorch 2.4 führt torch.compile() standardmäßig für CNN-Operationen ein und liefert 30-50% Geschwindigkeitssteigerungen auf modernen GPUs ohne Codeänderungen. Alle Beispiele in diesem Artikel sind mit PyTorch 2.4+ kompatibel.

Convolutional Neural Networks für Bildklassifizierung verstehen

Convolutional Neural Networks extrahieren hierarchische Merkmale aus Bildern durch lernbare Filter. Im Gegensatz zu vollständig verbundenen Netzwerken bewahren CNNs räumliche Beziehungen zwischen Pixeln, was sie ideal für visuelle Aufgaben macht. Die Architektur besteht aus Faltungsschichten, die Kanten und Muster erkennen, Pooling-Schichten, die die Dimensionalität reduzieren, und vollständig verbundenen Schichten, die die Klassifizierung durchführen.

Eine Faltungsoperation schiebt einen kleinen Filter (typischerweise 3x3 oder 5x5) über das Eingabebild und berechnet Skalarprodukte an jeder Position. Dies erzeugt Feature Maps, die spezifische Muster wie Kanten, Texturen oder Formen hervorheben. Tiefere Schichten kombinieren diese Low-Level-Merkmale zu komplexen Repräsentationen—Gesichter, Objekte oder Szenen.

python
# cnn_architecture.py
import torch
import torch.nn as nn

class SimpleCNN(nn.Module):
    """Basic CNN for CIFAR-10 classification (32x32 RGB images, 10 classes)"""
    
    def __init__(self, num_classes: int = 10):
        super().__init__()
        # First conv block: 3 input channels (RGB) -> 32 feature maps
        self.conv1 = nn.Sequential(
            nn.Conv2d(3, 32, kernel_size=3, padding=1),  # Output: 32x32x32
            nn.BatchNorm2d(32),  # Normalize activations for stable training
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2, 2)  # Output: 16x16x32
        )
        # Second conv block: increase depth for richer features
        self.conv2 = nn.Sequential(
            nn.Conv2d(32, 64, kernel_size=3, padding=1),  # Output: 16x16x64
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2, 2)  # Output: 8x8x64
        )
        # Third conv block: capture high-level patterns
        self.conv3 = nn.Sequential(
            nn.Conv2d(64, 128, kernel_size=3, padding=1),  # Output: 8x8x128
            nn.BatchNorm2d(128),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2, 2)  # Output: 4x4x128
        )
        # Classifier head
        self.classifier = nn.Sequential(
            nn.Flatten(),
            nn.Linear(128 * 4 * 4, 256),
            nn.ReLU(inplace=True),
            nn.Dropout(0.5),  # Prevent overfitting
            nn.Linear(256, num_classes)
        )
    
    def forward(self, x: torch.Tensor) -> torch.Tensor:
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        return self.classifier(x)

Diese Architektur erhöht progressiv die Anzahl der Filter (32 → 64 → 128) während sie die räumlichen Dimensionen durch Pooling reduziert. BatchNorm stabilisiert das Training durch Normalisierung der Schichtausgaben, während Dropout verhindert, dass der Klassifikator Trainingsbeispiele auswendig lernt.

Training eines CNN mit PyTorch DataLoaders

Effizientes Laden von Daten ist entscheidend für die GPU-Auslastung während des Trainings. PyTorchs DataLoader übernimmt automatisch Batching, Shuffling und paralleles Laden von Daten. Geeignete Datenaugmentation—zufällige Ausschnitte, Spiegelungen und Farbanpassungen—verbessert die Generalisierung auf ungesehene Bilder erheblich.

python
# train_cnn.py
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

# Data augmentation for training (reduces overfitting)
train_transform = transforms.Compose([
    transforms.RandomHorizontalFlip(p=0.5),
    transforms.RandomCrop(32, padding=4),  # Random crop with padding
    transforms.ColorJitter(brightness=0.2, contrast=0.2),
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465),  # CIFAR-10 mean
                         (0.2470, 0.2435, 0.2616))  # CIFAR-10 std
])

# No augmentation for validation (deterministic evaluation)
val_transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465),
                         (0.2470, 0.2435, 0.2616))
])

def train_model(model: nn.Module, epochs: int = 20) -> dict:
    """Train CNN with standard best practices"""
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = model.to(device)
    
    # Load CIFAR-10 dataset
    train_data = datasets.CIFAR10(root="./data", train=True, 
                                   download=True, transform=train_transform)
    val_data = datasets.CIFAR10(root="./data", train=False,
                                 transform=val_transform)
    
    # DataLoaders with num_workers for parallel loading
    train_loader = DataLoader(train_data, batch_size=128, shuffle=True,
                              num_workers=4, pin_memory=True)
    val_loader = DataLoader(val_data, batch_size=256, shuffle=False,
                            num_workers=4, pin_memory=True)
    
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4)
    scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=epochs)
    
    best_acc = 0.0
    for epoch in range(epochs):
        model.train()
        for images, labels in train_loader:
            images, labels = images.to(device), labels.to(device)
            optimizer.zero_grad()
            outputs = model(images)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
        
        scheduler.step()
        
        # Validation
        model.eval()
        correct, total = 0, 0
        with torch.no_grad():
            for images, labels in val_loader:
                images, labels = images.to(device), labels.to(device)
                outputs = model(images)
                _, predicted = outputs.max(1)
                total += labels.size(0)
                correct += predicted.eq(labels).sum().item()
        
        acc = 100. * correct / total
        best_acc = max(best_acc, acc)
        print(f"Epoch {epoch+1}/{epochs} - Val Acc: {acc:.2f}%")
    
    return {"best_accuracy": best_acc}

Wichtige Trainingsoptimierungen umfassen: pin_memory=True für schnellere CPU-zu-GPU-Übertragungen, num_workers für paralleles Laden von Daten, AdamW-Optimizer mit Weight Decay für Regularisierung und Cosine-Annealing-Lernratenplanung für sanfte Konvergenz.

Transfer Learning mit vortrainierten ResNet- und EfficientNet-Modellen

Transfer Learning nutzt Modelle, die auf ImageNet (1,2 Millionen Bilder, 1000 Klassen) vortrainiert wurden, und passt sie an benutzerdefinierte Datensätze an. Dieser Ansatz erreicht höhere Genauigkeit mit weniger Trainingsdaten und Rechenzeit. PyTorchs torchvision.models bietet State-of-the-Art-Architekturen mit vortrainierten Gewichten.

Der Standardansatz friert frühe Faltungsschichten ein (die universelle Merkmale wie Kanten erkennen) und passt spätere Schichten sowie einen neuen Klassifizierungskopf für die Zielaufgabe an.

python
# transfer_learning.py
import torch
import torch.nn as nn
from torchvision import models
from torchvision.models import ResNet50_Weights, EfficientNet_B0_Weights

def create_transfer_model(
    model_name: str = "resnet50",
    num_classes: int = 10,
    freeze_backbone: bool = True
) -> nn.Module:
    """Create a pretrained model with custom classification head"""
    
    if model_name == "resnet50":
        # Load ResNet50 with ImageNet weights
        model = models.resnet50(weights=ResNet50_Weights.IMAGENET1K_V2)
        # Replace final fully connected layer
        in_features = model.fc.in_features  # 2048 for ResNet50
        model.fc = nn.Sequential(
            nn.Dropout(0.3),
            nn.Linear(in_features, num_classes)
        )
        
    elif model_name == "efficientnet_b0":
        # EfficientNet: better accuracy/compute tradeoff
        model = models.efficientnet_b0(weights=EfficientNet_B0_Weights.IMAGENET1K_V1)
        in_features = model.classifier[1].in_features  # 1280 for B0
        model.classifier = nn.Sequential(
            nn.Dropout(0.2),
            nn.Linear(in_features, num_classes)
        )
    
    if freeze_backbone:
        # Freeze all layers except classifier
        for name, param in model.named_parameters():
            if "fc" not in name and "classifier" not in name:
                param.requires_grad = False
    
    return model

def count_trainable_params(model: nn.Module) -> int:
    """Count parameters that will be updated during training"""
    return sum(p.numel() for p in model.parameters() if p.requires_grad)

# Example usage
model = create_transfer_model("resnet50", num_classes=5, freeze_backbone=True)
print(f"Trainable parameters: {count_trainable_params(model):,}")
# Output: ~10,245 (only classifier) vs ~25 million (full ResNet50)

Das Einfrieren des Backbones reduziert die trainierbaren Parameter von 25 Millionen auf etwa 10.000, was das Training auf kleinen Datensätzen ohne Overfitting ermöglicht. Bei größeren Datensätzen (10.000+ Bilder) sollten spätere Schichten schrittweise mit differentiellen Lernraten aufgetaut werden—niedrigere Raten für vortrainierte Schichten, höhere Raten für den neuen Klassifikator.

Bereit für deine Data Science & ML-Interviews?

Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.

Strategien zur Datenaugmentation für Computer Vision

Datenaugmentation erweitert den Trainingsdatensatz künstlich durch Transformationen, die den semantischen Inhalt bewahren. Moderne Augmentation geht über einfache Spiegelungen und Rotationen hinaus—Techniken wie MixUp und CutOut erzeugen synthetische Trainingsbeispiele, die die Modellrobustheit verbessern.

python
# augmentation_strategies.py
import torch
import torchvision.transforms.v2 as T
from torchvision.transforms.v2 import functional as F

# Modern augmentation pipeline using torchvision v2 transforms
advanced_augmentation = T.Compose([
    T.RandomResizedCrop(224, scale=(0.8, 1.0)),  # Random crop and resize
    T.RandomHorizontalFlip(p=0.5),
    T.RandomVerticalFlip(p=0.1),  # Less common but useful for some domains
    T.RandomRotation(degrees=15),
    T.ColorJitter(brightness=0.3, contrast=0.3, saturation=0.3, hue=0.1),
    T.RandomAffine(degrees=0, translate=(0.1, 0.1)),  # Small translations
    T.GaussianBlur(kernel_size=3, sigma=(0.1, 2.0)),
    T.ToImage(),
    T.ToDtype(torch.float32, scale=True),
    T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

class CutOut:
    """Randomly mask out square regions of the image"""
    def __init__(self, n_holes: int = 1, length: int = 16):
        self.n_holes = n_holes
        self.length = length
    
    def __call__(self, img: torch.Tensor) -> torch.Tensor:
        h, w = img.shape[1], img.shape[2]
        mask = torch.ones_like(img)
        
        for _ in range(self.n_holes):
            y = torch.randint(0, h, (1,)).item()
            x = torch.randint(0, w, (1,)).item()
            y1 = max(0, y - self.length // 2)
            y2 = min(h, y + self.length // 2)
            x1 = max(0, x - self.length // 2)
            x2 = min(w, x + self.length // 2)
            mask[:, y1:y2, x1:x2] = 0
        
        return img * mask

def mixup_data(
    x: torch.Tensor,
    y: torch.Tensor,
    alpha: float = 0.4
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, float]:
    """MixUp: blend two images and their labels"""
    lam = torch.distributions.Beta(alpha, alpha).sample().item()
    batch_size = x.size(0)
    index = torch.randperm(batch_size)
    
    mixed_x = lam * x + (1 - lam) * x[index]
    y_a, y_b = y, y[index]
    
    return mixed_x, y_a, y_b, lam

CutOut zwingt das Modell, sich auf mehrere visuelle Hinweise zu verlassen, anstatt nur auf eine einzelne diskriminierende Region. MixUp erstellt konvexe Kombinationen von Trainingspaaren, was zu glatteren Entscheidungsgrenzen führt. Diese Techniken verbessern die Genauigkeit auf Standard-Benchmarks konstant um 1-3%.

Interviewfragen zu CNNs und Computer Vision

Technische Interviews für Computer-Vision-Positionen testen sowohl theoretisches Verständnis als auch praktische Implementierungsfähigkeiten. Die Vorbereitung sollte Fragen zu Architekturdesign, Optimierungsherausforderungen und Überlegungen zur realen Bereitstellung umfassen.

Häufige Interview-Themen

Interviewer fragen häufig nach Berechnungen des rezeptiven Feldes, dem Zweck von Batch-Normalisierung, warum Faltungen für Bilder funktionieren und wie man Overfitting in Vision-Modellen diagnostiziert.

F: Was ist das rezeptive Feld und warum ist es wichtig?

Das rezeptive Feld ist der Bereich des Eingabebildes, der eine bestimmte Feature-Map-Position beeinflusst. Tiefere Schichten haben größere rezeptive Felder, was ihnen ermöglicht, breiteren Kontext zu erfassen. Für ein Netzwerk mit n Faltungsschichten mit 3x3-Kerneln wächst das rezeptive Feld als (2n + 1) × (2n + 1). Das Architekturdesign erfordert die Abwägung zwischen Größe des rezeptiven Feldes und Rechenkosten—dilatierte Faltungen erweitern rezeptive Felder ohne Erhöhung der Parameter.

F: Warum wird Batch-Normalisierung in CNNs verwendet?

Batch-Normalisierung normalisiert Schichteingaben auf null Mittelwert und Einheitsvarianz und adressiert damit das interne Kovariatenschieben. Vorteile umfassen: schnellere Konvergenz (höhere Lernraten werden stabil), Regularisierungseffekt (reduziert Bedarf an Dropout) und verbesserten Gradientenfluss (verhindert verschwindende Gradienten in tiefen Netzwerken). Während der Inferenz ersetzen laufende Statistiken die Batch-Statistiken für deterministische Ausgaben.

F: Erklären Sie den Unterschied zwischen Same- und Valid-Padding.

Same-Padding fügt Nullen um die Eingabe hinzu, um räumliche Dimensionen nach der Faltung zu erhalten—eine 32×32-Eingabe mit einem 3×3-Kernel erzeugt eine 32×32-Ausgabe. Valid-Padding wendet kein Padding an und reduziert Dimensionen—dieselbe Operation erzeugt eine 30×30-Ausgabe. Same-Padding wird in tiefen Netzwerken bevorzugt, um aggressive räumliche Reduktion zu vermeiden.

F: Wie geht man mit Klassenungleichgewicht bei der Bildklassifizierung um?

Strategien umfassen: gewichtete Kreuzentropie-Verlustfunktion (höhere Gewichte für Minderheitsklassen), Oversampling von Minderheitsklassen während des Trainings, Datenaugmentation fokussiert auf unterrepräsentierte Klassen und Focal Loss, der leichte Beispiele heruntergewichtet. Bei starkem Ungleichgewicht (>100:1) sollten mehrere Techniken kombiniert werden, und Metriken jenseits der Genauigkeit sollten berücksichtigt werden—F1-Score, Precision-Recall-AUC oder Konfusionsmatrix-Analyse.

Für weitere Vorbereitung auf Deep-Learning-Interviews können die Module CNN & Bildklassifizierung und Deep Learning Grundlagen erkundet werden.

PyTorch Vision-Modelle mit TorchScript bereitstellen

Die Produktionsbereitstellung erfordert die Konvertierung von PyTorch-Modellen in optimierte Formate. TorchScript kompiliert Modelle in eine portable Darstellung, die ohne Python läuft und die Bereitstellung in C++-Anwendungen, auf mobilen Geräten oder in serverlosen Umgebungen ermöglicht.

python
# deployment_export.py
import torch
from torchvision import models
from torchvision.models import ResNet18_Weights

def export_for_production(model: torch.nn.Module, save_path: str) -> None:
    """Export model to TorchScript for production deployment"""
    model.eval()  # Set to evaluation mode (disables dropout, uses running stats)
    
    # Create example input matching expected dimensions
    example_input = torch.randn(1, 3, 224, 224)
    
    # Method 1: Tracing (for models without control flow)
    traced_model = torch.jit.trace(model, example_input)
    traced_model.save(save_path.replace(".pt", "_traced.pt"))
    
    # Method 2: Scripting (handles if/else, loops)
    scripted_model = torch.jit.script(model)
    scripted_model.save(save_path.replace(".pt", "_scripted.pt"))
    
    # Verify outputs match
    with torch.no_grad():
        original_out = model(example_input)
        traced_out = traced_model(example_input)
        scripted_out = scripted_model(example_input)
    
    assert torch.allclose(original_out, traced_out, atol=1e-5)
    assert torch.allclose(original_out, scripted_out, atol=1e-5)
    print(f"Model exported successfully to {save_path}")

def optimize_for_inference(model_path: str) -> torch.jit.ScriptModule:
    """Load and optimize TorchScript model for inference"""
    model = torch.jit.load(model_path)
    
    # Optimize for inference (fuses operations, removes dropout)
    optimized = torch.jit.optimize_for_inference(model)
    
    return optimized

# Export ResNet18
model = models.resnet18(weights=ResNet18_Weights.IMAGENET1K_V1)
export_for_production(model, "resnet18_production.pt")

Für maximale Inferenzgeschwindigkeit sollte ONNX-Export für Framework-übergreifende Kompatibilität oder TensorRT für NVIDIA-GPU-Bereitstellung in Betracht gezogen werden. Der Vergleich PyTorch vs TensorFlow behandelt Bereitstellungsabwägungen zwischen den Frameworks.

Fazit

Computer Vision mit PyTorch kombiniert leistungsstarke Abstraktionen mit produktionsreifen Werkzeugen:

  • CNN-Architekturen extrahieren hierarchische Merkmale durch Faltungs-, Pooling- und Normalisierungsschichten
  • Transfer Learning mit vortrainierten Modellen (ResNet, EfficientNet) erreicht hohe Genauigkeit bei begrenzten Daten
  • Datenaugmentation (MixUp, CutOut, geometrische Transformationen) verbessert die Generalisierung und verhindert Overfitting
  • Technische Interviews testen rezeptive Felder, Batch-Normalisierung, Padding-Strategien und den Umgang mit Klassenungleichgewicht
  • TorchScript ermöglicht die Produktionsbereitstellung ohne Python-Abhängigkeiten

Fang an zu üben!

Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.

Anthony Fillion-Maillet

Geschrieben von

Anthony Fillion-Maillet

Fullstack-Entwickler, Gründer von SharpSkill

Seit über 10 Jahren Fullstack-Entwickler. Er leitet SharpSkill und verantwortet alles, was hier erscheint.

Aktualisiert am 14. August 2026

Teilen

Verwandte Artikel