1import torch
2import torch.nn as nn
3
4LR = 0.04 # Lernrate
5DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
6
7# TODO:
8# Legen Sie die Trainingsdaten und Labels fest.
9# Die Trainingsdaten repräsentieren die Eingaben für ein XOR-Problem.
10# Die Labels repräsentieren die erwarteten Ausgaben für diese Eingaben.
11# Die Eingaben sind 2D-Punkte, und die Labels sind die erwarteten Klassifikationen.
12# Die Daten und Labels sollten auf das Gerät `DEVICE` verschoben werden.
13# Achten Sie darauf, dass die Daten als `torch.float32` und die Labels als `torch.long` definiert sind.
14training_data = torch.tensor(
15 [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]], dtype=torch.float32, device=DEVICE
16)
17labels = torch.tensor([0, 1, 1, 0], dtype=torch.long, device=DEVICE)
18
19
20class SimpleNetwork(nn.Module):
21 """Ein einfaches neuronales Netzwerk mit einer versteckten Schicht."""
22
23 def __init__(self):
24 """Initialisiert das Netzwerk mit einer versteckten Schicht.
25
26 **TODO**:
27
28 - Rufen Sie die Methode `super().__init__()` auf, um die Basisklasse zu initialisieren.
29
30 - Definieren Sie die erste voll verbundene Schicht `fc1` mit 2 Eingängen und 8 Ausgängen.
31
32 - Definieren Sie die zweite voll verbundene Schicht `fc2` mit 8 Eingängen und 2 Ausgängen.
33 """
34 # Initialisierung der Basisklasse
35 super().__init__()
36
37 # Definition der voll verbundenen Schichten
38 # Die erste Schicht hat 2 Eingänge und 8 Ausgänge
39 self.fc1 = nn.Linear(2, 8)
40
41 # Die zweite Schicht hat 8 Eingänge und 2 Ausgänge
42 # Diese Schicht wird verwendet, um die Klassifikationsergebnisse zu erzeugen
43 self.fc2 = nn.Linear(8, 2)
44
45 def forward(self, x):
46 """Führt den Vorwärtsdurchlauf des Netzwerks aus.
47
48 **TODO**:
49
50 - Wenden Sie die erste voll verbundene Schicht `fc1` auf die Eingabe `x` an.
51
52 - Wenden Sie die ReLU-Aktivierungsfunktion (`torch.relu <https://docs.pytorch.org/docs/stable/generated/torch.nn.ReLU.html>`_) auf die Ausgabe der ersten Schicht `fc1` an.
53
54 - Wenden Sie die zweite voll verbundene Schicht `fc2` auf die Ausgabe der ReLU-Aktivierung an.
55
56 - Geben Sie die Ausgabe der zweiten Schicht `fc2` zurück.
57 """
58
59 # Vorwärtsdurchlauf durch die erste Schicht
60 x = self.fc1(x)
61
62 # Aktivierungsfunktion ReLU anwenden
63 x = torch.relu(x)
64
65 # Vorwärtsdurchlauf durch die zweite Schicht
66 x = self.fc2(x)
67
68 # Ausgabe zurückgeben
69 return x
70
71
72def train_model(model, data, labels, criterion, optimizer, epochs=8000):
73 """Trainiert das Modell mit den gegebenen Daten und Labels.
74
75 Diese Funktion führt das Training des Modells durch, indem sie die Eingabedaten und Labels verwendet,
76 um die Gewichte des Modells zu aktualisieren. Der Verlust wird in jeder 1000. Epoche ausgegeben.
77
78 Parameter:
79 ----------
80
81 model : nn.Module
82 Das zu trainierende neuronale Netzwerk.
83
84 data : torch.Tensor
85 Die Eingabedaten für das Training.
86
87 labels : torch.Tensor
88 Die zugehörigen Labels für die Eingabedaten.
89
90 criterion : nn.Module
91 Das Kriterium zur Berechnung des Verlusts (z.B. CrossEntropyLoss).
92
93 optimizer : torch.optim.Optimizer
94 Der Optimierer, der verwendet wird, um die Gewichte des Modells zu aktualisieren
95
96 epochs : int, optional
97 Die Anzahl der Epochen, die das Modell trainiert werden soll (Standard: 8000).
98
99 **TODO**:
100
101 Iterieren Sie über die Anzahl der Epochen und führen Sie in jeder Epoche die folgenden Schritte aus:
102
103 - Setzen Sie die Gradienten des Optimierers zurück. (`optimizer.zero_grad() <https://pytorch.org/docs/stable/generated/torch.optim.Optimizer.zero_grad.html>`_)
104
105 - Führen Sie einen Vorwärtsdurchlauf des Modells mit den Eingabedaten `data` durch.
106
107 - Berechnen Sie den Verlust zwischen den Modell-Ausgaben und den Labels mit dem Kriterium `criterion`.
108
109 - Führen Sie den Rückwärtsdurchlauf durch, um die Gradienten zu berechnen. (`loss.backward() <https://pytorch.org/docs/stable/generated/torch.Tensor.backward.html>`_)
110
111 - Geben Sie den Verlust alle 1000 Epochen aus.
112
113 - Führen Sie den Optimierungsschritt durch, um die Gewichte des Modells zu aktualisieren. (`optimizer.step() <https://pytorch.org/docs/stable/generated/torch.optim.Optimizer.step.html>`_)
114 """
115 # Training des Modells
116 for epoch in range(epochs):
117 # Gradienten zurücksetzen
118 optimizer.zero_grad()
119
120 # Vorwärtsdurchlauf
121 outputs = model(data)
122
123 # Verlust berechnen und Rückwärtsdurchlauf
124 loss = criterion(outputs, labels)
125
126 # Gradienten berechnen
127 loss.backward()
128
129 # Ausgabe des Verlusts alle 1000 Epochen
130 if epoch % 1000 == 999:
131 print(f"Epoch {epoch+1}, Loss: {loss.item()}")
132
133 # Optimierungsschritt
134 optimizer.step()
135
136
137if __name__ == "__main__":
138 # Initialisierung des Modells, Loss-Kriteriums und Optimierers
139 model = SimpleNetwork().to(DEVICE)
140 criterion = nn.CrossEntropyLoss()
141 optimizer = torch.optim.SGD(model.parameters(), lr=LR)
142
143 # Das Modell trainieren
144 model.train()
145 train_model(model, training_data, labels, criterion, optimizer)
146
147 # Nach dem Training das Modell verwenden
148 model.eval()
149 with torch.no_grad():
150 outputs = model(training_data)
151
152 print("Training complete.")
153 print(outputs)