Entwickle Deep-Learning-Modelle mit PyTorch und Google Colab - Eine praktische Einführung

09.08.2022Raffael Schneider
Cloud Machine Learning Artificial Intelligence

PyTorch ist eine Open-Source Machine Learning-Bibliothek, die auf Python entwickelt wurde. Es bietet eine einfache und intuitive Programmierumgebung für die Entwicklung von Deep Learning-Modellen.

Die Verwendung von PyTorch wird für Entwickler immer wichtiger, weil es sich als sehr effektives Werkzeug für die Entwicklung von künstlicher Intelligenz und maschinellem Lernen erwiesen hat. Es bietet eine einfache Integration in andere Anwendungen und Tools, flexible Datenverarbeitung und starke GPU-Beschleunigung. Aufgrund seiner einfachen Handhabung und hohen Leistung ist es zu einer der am häufigsten verwendeten Bibliotheken in der Entwicklung von Deep-Learning-Modellen geworden. Die Features von PyTorch können wie folgt zusammengefasst werden:

  1. Einfach zu erlernen und zu verwenden: PyTorch verwendet eine einfache und intuitive Programmierumgebung, die es Entwicklern ermöglicht, schnell mit der Entwicklung von Deep-Learning-Modellen zu beginnen.
  2. Flexible Datenverarbeitung: PyTorch bietet eine flexible Datenverarbeitung, die es Entwicklern ermöglicht, Daten in den Formaten zu verarbeiten, die für ihre Anwendungen am besten geeignet sind.
  3. GPU-Beschleunigung: PyTorch nutzt die Leistung moderner GPUs für die schnelle Verarbeitung von Daten und die Entwicklung komplexer Deep-Learning-Modelle.
  4. Integrierbarkeit: PyTorch lässt sich einfach in andere Anwendungen und Tools integrieren, was es Entwicklern ermöglicht, ihre Deep-Learning-Modelle in vorhandene Arbeitsabläufe zu integrieren.
  5. Aktive Community: PyTorch hat eine aktive Community von Entwicklern, die ständig neue Funktionen und Verbesserungen entwickeln, was die Leistung und Flexibilität der Bibliothek ständig verbessert.
  6. Dynamic Computational Graph: PyTorch bietet einen dynamischen Computational Graph, der es Entwicklern ermöglicht, ihre Modelle während der Ausführung zu ändern und zu verbessern.
  7. Transfer Learning-Unterstützung: PyTorch bietet eine einfache Unterstützung für Transfer Learning, was es Entwicklern ermöglicht, vorhandene Deep-Learning-Modelle für neue Anwendungen zu verwenden und zu verbessern.

PyTorch ist mittlerweile im Jahr 2023 der Goldstandard im Rahmen Machine-Learning und ist neben TensorFlow eines der beiden grossen Frameworks dafür.

Von Facebook zur Nummer 1

PyTorch wurde von Facebook entwickelt und erstmals im Jahr 2017 veröffentlicht. Die Entwicklung von PyTorch begann als Ersatz für das damals verwendete Machine-Learning-Framework Torch. Der ursprüngliche Torch-Code wurde in C (CUDA) geschrieben. Als Interface-Language diente ein auf LuaJIT-basierendes SDK. In der Praxis aber gab es einige Hürden bei der Verwendung von Torch, insbesondere bei der Integrierung mit anderen bestehenden Tools und Bibliotheken.

Um diese Probleme zu beheben, beschlossen die Entwickler von Facebook, ein neues Framework zu schreiben, das auf den besten Funktionen von Torch aufbaute und gleichzeitig die Vorteile von Python nutzte. Das Ergebnis war PyTorch, eine Open-Source-Machine Learning-Bibliothek, die eine einfache Programmierumgebung und relativ flexible Datenverarbeitung bietet. Hot Stuff! 🤓

Jupyter Notebooks

Bevor mit einem PyTorch-Beispiel einsteigen, müssen wir noch verstehen womit man PyTorch am besten verwendet, also sprich auf welcher Platform bzw. Maschine das Deep-Learning-Modell geschrieben, modelliert, trainiert und evaluiert wird. Selbstverständlich könnte man jetzt einfach PyTorch bei sich auf dem Rechner installieren und mit vorhandenen, Python-fähigen IDEs wie zum Beispiel JetBrains PyCharm, JetBrains DataSpells, oder gar Microsoft’s VSCode dafür verwenden.

Die Gemeinsamkeit, die bei der Auswahl im Vordergrund steht, ist die Integriertheit von Jupyter Notebook. Für diejenigen, die unsere TechUps regelmäßig lesen und noch wenig Schnittmenge mit Data Science oder Machine Learning haben, könnte der Begriff “Jupyter Notebook” unter Umständen neu sein. An dieser Stelle sei gesagt, dass Jupyter Notebooks das Herzstück und Grundwerkzeug eines jeden Data Scientists oder Data Engineers darstellen.

Jupyter Notebook ist eine web-basierte, interaktive Umgebung für die Erstellung von Dokumenten, die Live-Code, beschreibende Prosa, Visualisierungen und weitere Multimedia-Inhalte enthalten. Dadurch kann der Data Scientist Code schreiben, ihn ausführen und die Ergebnisse sofort sehen. Das macht das Ganze einfach zu handhaben und hält die Iterationszyklen kurz. Zudem ermöglicht Jupyter Notebook, gerade weil es web-basiert aufgebaut ist, die Zusammenarbeit, indem es Benutzern die Möglichkeit gibt, Dokumente auszutauschen und gemeinsam an ihnen zu arbeiten.

Obwohl Jupyter eine Vielzahl von Programmiersprachen unterstützt, ist die Lingua-Franca Python. Auch verbreitet sind Sprachen wie Julia, GNU Octave oder R. Somit ist Jupyter Notebook die favorisierte Umgebung, um Machine Learning mit PyTorch zu betreiben.

Als web-basierte Umgebung basiert Jupyter auf einer Client-Server-Architektur. Man kann es auf dem lokalen Rechner installieren oder in einer durchdachten Cloud-Architektur einbetten. Für dieses TechUp machen wir es uns ein wenig einfacher und nutzen eine kostenlose Cloud-basierte Plattform, nämlich Google Colab.

Jupyter in der Cloud mit Google Colab

Google Colab ist eine kostenlose Online-Plattform, die es Benutzern ermöglicht, Jupyter-Notebooks in der Cloud auszuführen. Es ist eine einfach zu bedienende Plattform, die den Benutzern einen einfachen Zugriff auf alle gängigen Bibliotheken und Frameworks für maschinelles Lernen bietet. Colab bietet auch eine GPU-Unterstützung, die es Benutzern ermöglicht, schnell und effizient Deep-Learning-Modelle zu erstellen und zu trainieren.

Um mit Colab Deep-Learning-Modelle zu erstellen, musst du zunächst ein neues Notebook erstellen und die erforderlichen Bibliotheken und Frameworks installieren. Colab bietet bereits viele Bibliotheken und Frameworks vorinstalliert, daher müssen diese normalerweise nicht manuell installiert werden. Anschließend kannst du Code schreiben, Daten importieren sowie Modelle erstellen und trainieren.

PyTorch Kickstart

Hier ist ein einfaches Beispiel von Deep Learning mit PyTorch.

  1. Importieren von Abhängigkeiten: Zuerst müssen wir die benötigten PyTorch-Bibliotheken importieren.
1
2
3
import torch
import torch.nn as nn
import torch.optim as optim
  1. Datenvorbereitung: Als nächstes bereiten wir unsere Trainingsdaten vor. Hier verwenden wir einen einfachen Datensatz, der aus zwei Merkmalen (die x_train-Achse) und einem Ziel (die y_train-Achse) besteht.
1
2
x_train = torch.tensor([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0]])
y_train = torch.tensor([[2.0], [4.0], [6.0]])
  1. Modelldefinition: Als nächstes definieren wir unser Modell mit PyTorch. Hier verwenden wir ein einfaches, linear geschichtetes Modell.
1
2
3
4
5
6
7
8
9
class LinearRegression(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(2, 1)

    def forward(self, x):
        return self.linear(x)

model = LinearRegression()
  1. Modellausbildung: Jetzt können wir unser Modell mit den Trainingsdaten ausbilden. Hier verwenden wir den Stochastic Gradient Descent (SGD) als Optimierer und definieren eine Verlustfunktion.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

for epoch in range(100):
    y_pred = model(x_train)
    loss = criterion(y_pred, y_train)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
  1. Vorhersage: Schließlich können wir unser Modell verwenden, um Vorhersagen auf neuen Daten zu machen.
1
2
3
x_test = torch.tensor([[4.0, 4.0]])
y_test = model(x_test)
print(y_test)

Dieses Beispiel demonstriert die grundlegenden Schritte bei der Verwendung von PyTorch zur Durchführung von Deep Learning.

Machine-Learning Slang

Im Bereich Machine-Learning gibt es ein eigenes Vokabular, welche man im Vorgang verstehen sollte. Im obigen Beispiel haben wir die Begriffe von Loss, Accuracy, oder Epoch vorgefunden. Hier folgt eine kleine Erläuterung dieser Begrifflichkeiten:

  • Verlust: Die Strafe für eine schlechte Vorhersage. Das heißt, der Verlust ist eine Zahl, die angibt, wie schlecht die Vorhersage des Modells für ein einzelnes Beispiel war. Wenn die Vorhersage des Modells perfekt ist, ist der Verlust gleich null; andernfalls ist der Verlust größer.
  • Genauigkeit: Die Genauigkeit ist ein Maßstab für die Bewertung von Klassifizierungsmodellen. Inoffiziell ist die Genauigkeit der Anteil der richtigen Vorhersagen, die unser Modell getroffen hat.
  • Epoche: Jedes Mal, wenn ein Datensatz einen Algorithmus durchläuft, wird gesagt, dass er eine Epoche abgeschlossen hat. Beim maschinellen Lernen bezieht sich Epoche also auf den gesamten Durchlauf der Trainingsdaten durch den Algorithmus. Es ist ein Hyperparameter, der den Trainingsprozess des maschinellen Lernmodells bestimmt.

Das war’s? Nein. Jetzt möchten wir mal ein Verständnis verschaffen was PyTorch denn genau abstrahiert.

Die Magie hinter PyTorch

Da wir bei b-nova stets bemüht sind, zu verstehen, was etwas im Kern bewegt, müssen wir natürlich genauer hinschauen und die Abstraktionslösung hinter PyTorch ein wenig besser durchleuchten.

Oben im Beispiel sehen wir, dass bestimmte Funktionen wie torch.nn oder torch.optim sowie auch Datenstrukturen wie Dataset oder DataLoader verborgen sind. Lass uns daher mit torch.nn beginnen und schauen, wie wir die Magie hinter diesem Aufruf entschlüsseln können.

torch.nn

torch.nn ist eine Abstraktion in PyTorch, die es Entwicklern ermöglicht, neuronalen Netzen und deren Schichten einfach und effizient zu definieren und zu trainieren. Es stellt eine Reihe von Klassen und Methoden bereit, die häufig verwendete Neuronennetz-Arten, wie Convolutional Neural Networks (CNNs), Recurrent Neural Networks (RNNs) und Fully Connected Networks (FCNs), abstrahiert und vereinfacht.

Mit torch.nn können Entwickler eigene Schichten erstellen, die auf die Bedürfnisse ihrer Anwendungen zugeschnitten sind, oder bereits vordefinierte Schichten wie Convolutional Layers, Max Pooling Layers und Activation Functions verwenden. Die Schichten können miteinander verkettet werden, um ein komplettes Neuronennetz zu definieren, und das Training und die Evaluation von Modellen kann dann mithilfe von torch.optim und anderen PyTorch-Tools durchgeführt werden.

Kurz gesagt, torch.nn bietet eine einfache und effiziente Möglichkeit, neuronalen Netzen und deren Schichten zu definieren und zu trainieren, indem es häufig verwendete Konstrukte abstrahiert und vereinfacht.

torch.optim

torch.optim ist eine Abstraktion in PyTorch, die es Entwicklern ermöglicht, Optimierungsalgorithmen für das Training neuronaler Netze einfach und effizient zu implementieren. Es stellt eine Reihe von Klassen bereit, die häufig verwendete Optimierungsverfahren, wie Stochastic Gradient Descent (SGD), Adagrad, Adadelta, Adam und viele andere, abstrahiert und vereinfacht.

Mit torch.optim können Entwickler einen Optimierer wählen, der zu ihren Bedürfnissen und Anforderungen passt, und dann die Trainingsparameter und den Loss-Funktionswert für das Neuronennetz übergeben. Die Optimierungs-Klasse berechnet dann automatisch die Gradienten und aktualisiert die Gewichte, um das Modell zu verbessern.

Zusammenfassend kann man sagen, dass torch.nn und torch.optim eine einfache und effiziente Möglichkeit bieten, neuronale Netze und deren Schichten zu definieren und zu trainieren, sowie Optimierungsalgorithmen für das Training neuronaler Netze zu implementieren, indem beide quasi häufig verwendete Konstrukte abstrahiert werden.

Real-World mit MNIST-Datensatz

Hier möchten wir ein reales Beispiel durchspielen, bei dem wir uns mit einem bekannten Problem beschäftigen: dem Lesen von handgeschriebenen Ziffern. Dies ist ein häufig verwendetes Einführungsbeispiel, da es gut geeignet ist, um das Ergebnis einer Lösung zu beurteilen.

Der Datensatz, den wir dafür verwenden, stammt aus der MNIST-Datenbank. MNIST steht für Modified National Institute of Standards and Technology, einer US-amerikanischen Bundesbehörde. Der MNIST-Datensatz enthält 70.000 handgeschriebene Ziffern (0-9) im Format von 28x28 Pixeln. Er wird häufig für das Training von Modellen für die optische Zeichenerkennung verwendet.

In diesem Beispiel wird das Modell MNISTModel definiert. Es besteht aus drei linearen Schichten, die jeweils durch eine ReLU-Aktivierungsfunktion verbunden sind. Das Modell wird mit dem Adam-Optimizer und der Kreuzentropie-Loss-Funktion trainiert. Der Trainings- und Testdatensatz werden mithilfe von DataLoader in Batches geladen, um das Training zu beschleunigen. Das Modell wird für 10 Epochen trainiert. Nach jeder Epoche wird das Modell auf dem Testdatensatz getestet, und der Testverlust sowie die Genauigkeit werden ausgegeben.

Das fertige Notebook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision.datasets import MNIST
from torchvision.transforms import ToTensor
from torch.utils.data import DataLoader

# Laden des Trainings- und Testdatensatzes
train_data = MNIST(root='data', train=True, download=True, transform=ToTensor())
test_data = MNIST(root='data', train=False, download=True, transform=ToTensor())

# Definieren des Modells
class MNISTModel(nn.Module):
    def __init__(self):
        super(MNISTModel, self).__init__()
        self.fc1 = nn.Linear(28*28, 64)
        self.fc2 = nn.Linear(64, 32)
        self.fc3 = nn.Linear(32, 10)

    def forward(self, x):
        x = x.view(-1, 28*28)
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# Initialisieren des Modells, der Loss-Funktion und des Optimizers
model = MNISTModel()
loss_fn = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Definition des Trainers
def train(model, train_loader, optimizer, loss_fn):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        optimizer.zero_grad()
        output = model(data)
        loss = loss_fn(output, target)
        loss.backward()
        optimizer.step()

# Definition des Testers
def test(model, test_loader, loss_fn):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            output = model(data)
            test_loss += loss_fn(output, target).item()
            pred = output.argmax(dim=1, keepdim=True)
            correct += pred.eq(target.view_as(pred)).sum().item()
    test_loss /= len(test_loader.dataset)
    accuracy = 100. * correct / len(test_loader.dataset)
    return test_loss, accuracy

# Trainieren und Testen des Modells
train_loader = DataLoader(train_data, batch_size=64, shuffle=True)
test_loader = DataLoader(test_data, batch_size=64, shuffle=True)
for epoch in range(10):
    train(model, train_loader, optimizer, loss_fn)
    test_loss, accuracy = test(model, test_loader, loss_fn)
    print(f'Epoch {epoch}: Test Loss: {test_loss:.4f}, Accuracy: {accuracy:.2f}%')

Was hierbei passiert kann in folgenden Schritten zusammengefasst werden

  1. Zunächst werden die erforderlichen Bibliotheken importiert, einschließlich torch, torch.nn, torch.optim, MNIST und ToTensor.
  2. Der Trainings- und Testdatensatz werden geladen und in train_data und test_data gespeichert. ToTensor wird verwendet, um die Bilder in Tensoren umzuwandeln.
  3. Das Modell MNISTModel wird definiert. Es besteht aus drei linearen Schichten mit ReLU-Aktivierung zwischen ihnen. Die erste Schicht hat 784 Eingänge (28 x 28 Bilder), die zweite Schicht hat 64 Neuronen und die dritte Schicht hat 32 Neuronen und gibt eine Ausgabe von 10 Klassen zurück.
  4. Das Modell wird initialisiert und der Adam-Optimizer sowie die Kreuzentropie-Loss-Funktion werden definiert.
  5. Die Funktion train wird definiert, um das Modell auf dem Trainingsdatensatz zu trainieren. model.train() wird aufgerufen, um das Modell in den Trainingsmodus zu versetzen. Die Daten und Ziele werden von train_loader geladen. Der Optimizer wird auf Null zurückgesetzt (optimizer.zero_grad()), die Vorwärtspropagation wird durchgeführt (output = model(data)), der Loss wird berechnet (loss = loss_fn(output, target)) und die Rückwärtspropagation wird durchgeführt (loss.backward()). Schließlich wird der Optimizer aktualisiert (optimizer.step()).
  6. Die Funktion test wird definiert, um das Modell auf dem Testdatensatz zu testen. model.eval() wird aufgerufen, um das Modell in den Evaluierungsmodus zu versetzen. Die Testverluste und die Genauigkeit werden berechnet, indem die Ausgabe des Modells mit dem Ziel verglichen wird (pred.eq(target.view_as(pred)).sum().item()).
  7. train_loader und test_loader werden definiert, um die Daten in Batches zu laden.
  8. Das Modell wird für 10 Epochen trainiert. In jeder Epoche wird das Modell auf dem Testdatensatz getestet und die Testverluste und die Genauigkeit werden ausgegeben. Die Funktionen train und test werden verwendet, um das Modell auf dem Trainings- und Testdatensatz zu trainieren und zu testen.

Fazit

Der Umgang mit PyTorch, Jupyter Notebooks und Deep Learning ist äußerst zukunftsfähig. PyTorch ist eine leistungsfähige Bibliothek für Deep Learning und wird von zahlreichen namhaften Unternehmen und Forschungseinrichtungen eingesetzt. Es spielt eine entscheidende Rolle im Ökosystem des maschinellen Lernens und wird voraussichtlich auch in Zukunft eine bedeutende Rolle spielen.

Jupyter Notebooks sind ebenfalls ein essenzielles Werkzeug im Bereich des maschinellen Lernens und werden von vielen Forschern und Datenwissenschaftlern genutzt, um ihre Arbeit zu dokumentieren, zu teilen und reproduzierbar zu machen. Sie bieten eine effektive Möglichkeit, Code, Text und visuelle Darstellungen in einem einzigen Dokument zu vereinen.

Deep Learning ist eine schnell wachsende Disziplin, die in zahlreichen Branchen und Anwendungsfällen Anwendung findet. Die Nachfrage nach Fachleuten mit Kenntnissen in Deep Learning ist hoch und wird voraussichtlich in Zukunft weiter steigen. Daher wird der Umgang mit PyTorch, Jupyter Notebooks und Deep Learning auch in Zukunft äußerst relevant und zukunftsfähig sein.

PyTorch

Machine Learning Mastery

What is torch.nn really? - PyTorch Tutorials 1.13.1+cu117 documentation

MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges

MNIST Dataset

Top 15 Machine Learning Libraries in 2023

Top Machine Learning Trends for 2023

Torch - Meta Research | Meta Research