Zum Inhalt springen
_CORE
KI & Agentensysteme Unternehmensinformationssysteme Cloud & Platform Engineering Datenplattform & Integration Sicherheit & Compliance QA, Testing & Observability IoT, Automatisierung & Robotik Mobile & Digitale Produkte Banken & Finanzen Versicherungen Öffentliche Verwaltung Verteidigung & Sicherheit Gesundheitswesen Energie & Versorgung Telko & Medien Industrie & Fertigung Logistik & E-Commerce Retail & Treueprogramme
Referenzen Technologien Blog Know-how Tools
Über uns Zusammenarbeit Karriere
CS EN DE
Lassen Sie uns sprechen

Backpropagation — jak se neuronové sítě učí

19. 02. 2025 4 Min. Lesezeit intermediate

Backpropagation ist das Herz jedes neuronalen Netzes – ein eleganter Algorithmus, der es Maschinen ermoeglicht, aus eigenen Fehlern zu lernen. Sie werden verstehen, wie dieses mathematische Prinzip den Lernprozess von der Bilderkennung bis zu Sprachmodellen steuert.

Wie Backpropagation in neuronalen Netzen funktioniert

Backpropagation ist ein Algorithmus, der es neuronalen Netzen ermoeglicht, aus Fehlern zu lernen, indem Gradienten schrittweise rueckwaerts durch das Netz propagiert werden. Ohne diesen Mechanismus wuerde Deep Learning in seiner heutigen Form nicht existieren. Schauen wir uns genau an, wie es funktioniert und warum es so wichtig ist.

Grundprinzip von Forward und Backward Pass

Das Lernen neuronaler Netze erfolgt in zwei Phasen. Zuerst der Forward Pass — Daten fliessen vorwaerts durch das Netz und erzeugen Vorhersagen. Dann folgt der Backward Pass — der Fehler wird zurueckpropagiert und die Gewichte werden aktualisiert.

# Forward pass - simple network with one hidden layer
import numpy as np

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def forward_pass(X, W1, b1, W2, b2):
    # Hidden layer
    z1 = X.dot(W1) + b1
    a1 = sigmoid(z1)

    # Output layer
    z2 = a1.dot(W2) + b2
    a2 = sigmoid(z2)

    return z1, a1, z2, a2

Berechnung von Fehler und Gradienten

Der Schluessel ist das Verstaendnis, wie Gradienten berechnet werden. Wir verwenden die Kettenregel aus der mathematischen Analysis — wir zerlegen die Ableitung einer zusammengesetzten Funktion in ein Produkt einzelner Ableitungen.

Fuer den Mean Squared Error und die Sigmoid-Aktivierung sieht der Gradient so aus:

def compute_gradients(X, y, z1, a1, z2, a2, W1, W2):
    m = X.shape[0]  # number of samples

    # Gradient for output layer
    dz2 = a2 - y  # derivative of MSE loss
    dW2 = (1/m) * a1.T.dot(dz2)
    db2 = (1/m) * np.sum(dz2, axis=0)

    # Gradient for hidden layer (chain rule)
    da1 = dz2.dot(W2.T)
    dz1 = da1 * a1 * (1 - a1)  # derivative of sigmoid
    dW1 = (1/m) * X.T.dot(dz1)
    db1 = (1/m) * np.sum(dz1, axis=0)

    return dW1, db1, dW2, db2

Gewichtsaktualisierung mittels Gradient Descent

Sobald wir die Gradienten haben, koennen wir die Gewichte aktualisieren. Gradient Descent passt jedes Gewicht in die entgegengesetzte Richtung des Gradienten an — dadurch gelangen wir schrittweise zum Minimum der Verlustfunktion.

def update_weights(W1, b1, W2, b2, dW1, db1, dW2, db2, learning_rate):
    W1 -= learning_rate * dW1
    b1 -= learning_rate * db1
    W2 -= learning_rate * dW2
    b2 -= learning_rate * db2

    return W1, b1, W2, b2

# Complete training cycle
def train_step(X, y, W1, b1, W2, b2, learning_rate=0.01):
    # Forward pass
    z1, a1, z2, a2 = forward_pass(X, W1, b1, W2, b2)

    # Compute loss
    loss = np.mean((a2 - y)**2)

    # Backward pass
    dW1, db1, dW2, db2 = compute_gradients(X, y, z1, a1, z2, a2, W1, W2)

    # Update weights
    W1, b1, W2, b2 = update_weights(W1, b1, W2, b2, 
                                    dW1, db1, dW2, db2, learning_rate)

    return W1, b1, W2, b2, loss

Probleme mit Vanishing und Exploding Gradients

In tiefen Netzen koennen Vanishing Gradients auftreten — Gradienten nehmen waehrend der Backpropagation exponentiell ab. Das entgegengesetzte Problem sind Exploding Gradients, bei denen Gradienten unendlich wachsen.

Loesungen umfassen:

  • Gradient Clipping — Begrenzung der maximalen Gradientengroesse
  • Bessere Aktivierungsfunktionen — ReLU anstelle von Sigmoid
  • Batch Normalization — Normalisierung der Eingaben fuer jede Schicht
  • Residual Connections — direkte Verbindungen zwischen entfernten Schichten
# Gradient clipping in practice
def clip_gradients(gradients, max_norm=1.0):
    total_norm = 0
    for grad in gradients:
        total_norm += np.sum(grad**2)
    total_norm = np.sqrt(total_norm)

    clip_coef = max_norm / (total_norm + 1e-6)
    if clip_coef < 1:
        for i, grad in enumerate(gradients):
            gradients[i] = grad * clip_coef

    return gradients

Backpropagation-Optimierung

Moderne Implementierungen verwenden fortgeschrittene Optimierer, die die Learning Rate anpassen oder Momentum hinzufuegen:

class AdamOptimizer:
    def __init__(self, learning_rate=0.001, beta1=0.9, beta2=0.999):
        self.lr = learning_rate
        self.beta1 = beta1
        self.beta2 = beta2
        self.m = {}  # first moment
        self.v = {}  # second moment
        self.t = 0   # time step

    def update(self, params, gradients):
        self.t += 1

        for key in params:
            if key not in self.m:
                self.m[key] = np.zeros_like(params[key])
                self.v[key] = np.zeros_like(params[key])

            # Update biased first/second moment estimates
            self.m[key] = self.beta1 * self.m[key] + (1 - self.beta1) * gradients[key]
            self.v[key] = self.beta2 * self.v[key] + (1 - self.beta2) * gradients[key]**2

            # Bias correction
            m_hat = self.m[key] / (1 - self.beta1**self.t)
            v_hat = self.v[key] / (1 - self.beta2**self.t)

            # Update parameters
            params[key] -= self.lr * m_hat / (np.sqrt(v_hat) + 1e-8)

Backpropagation in der Praxis mit PyTorch

In realen Projekten verwenden wir Frameworks, die Backpropagation automatisch implementieren:

import torch
import torch.nn as nn

# Network definition
class SimpleNet(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super().__init__()
        self.hidden = nn.Linear(input_size, hidden_size)
        self.output = nn.Linear(hidden_size, output_size)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        x = self.sigmoid(self.hidden(x))
        x = self.sigmoid(self.output(x))
        return x

# Training with automatic backpropagation
model = SimpleNet(10, 20, 1)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

for epoch in range(1000):
    # Forward pass
    outputs = model(X)
    loss = criterion(outputs, y)

    # Backward pass - automatically!
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

Zusammenfassung

Backpropagation ist ein Algorithmus, der es neuronalen Netzen ermoeglicht, durch Minimierung des Fehlers mittels Gradient Descent zu lernen. Die Schluesselkomponenten sind drei Schritte: Forward Pass zur Berechnung von Vorhersagen, Backward Pass zur Propagierung von Gradienten und Gewichtsaktualisierungen. In der Praxis verwenden wir Optimierer wie Adam und Frameworks wie PyTorch, die den gesamten Prozess automatisieren. Das Verstaendnis der Backpropagation-Prinzipien ist jedoch fuer das Debugging und die Optimierung von Deep-Learning-Modellen unerlaesslich.

backpropagationgradient descentdeep learning
Teilen:

CORE SYSTEMS Team

Wir bauen Kernsysteme und KI-Agenten, die den Betrieb am Laufen halten. 15 Jahre Erfahrung mit Enterprise-IT.