PyTorch-Verlustfunktionen
Einführung
Verlustfunktionen sind im ML-Modelltraining von grundlegender Bedeutung, und in den meisten maschinellen Lernprojekten gibt es keine Möglichkeit, Ihr Modell ohne eine Verlustfunktion dazu zu bringen, korrekte Vorhersagen zu treffen. Laienhaft ausgedrückt ist eine Verlustfunktion eine mathematische Funktion oder ein mathematischer Ausdruck, mit dem gemessen wird, wie gut ein Modell bei einem Datensatz abschneidet. Wenn der Entwickler weiß, wie gut ein Modell bei einem bestimmten Datensatz abschneidet, erhält er Einblicke in viele Entscheidungen während des Trainings, z. B. die Verwendung eines neuen, leistungsfähigeren Modells oder sogar die Änderung der Verlustfunktion selbst in einen anderen Typ. Apropos Arten von Verlustfunktionen: Es gibt mehrere dieser Verlustfunktionen, die im Laufe der Jahre entwickelt wurden und sich jeweils für die Verwendung für eine bestimmte Trainingsaufgabe eignen.
Voraussetzungen
Dieser Artikel erfordert das Verständnis neuronaler Netze. Auf hoher Ebene bestehen neuronale Netze aus miteinander verbundenen Knoten („Neuronen“), die in Schichten organisiert sind. Sie lernen und treffen Vorhersagen durch einen Prozess namens „Training“, der die Gewichtungen und Verzerrungen der Verbindungen zwischen Neuronen anpasst. Zum Verständnis neuronaler Netze gehört die Kenntnis ihrer verschiedenen Schichten (Eingabeschicht, verborgene Schichten, Ausgabeschicht), Aktivierungsfunktionen, Optimierungsalgorithmen (Varianten des Gradientenabstiegs), Verlustfunktionen usw.
Darüber hinaus sind Kenntnisse der Python-Syntax und der PyTorch-Bibliothek für das Verständnis der in diesem Artikel vorgestellten Codefragmente unerlässlich.
In diesem Artikel werden wir verschiedene Verlustfunktionen untersuchen, die Teil des PyTorch nn-Moduls sind. Wir werden uns weiter eingehend damit befassen, wie PyTorch diese Verlustfunktionen den Benutzern als Teil seiner nn-Modul-API zur Verfügung stellt, indem es eine benutzerdefinierte Funktion erstellt.
Nachdem wir nun ein umfassendes Verständnis davon haben, was Verlustfunktionen sind, wollen wir uns mit einigen weiteren technischen Details zur Funktionsweise von Verlustfunktionen befassen.
Was sind Verlustfunktionen?
Wir haben bereits erwähnt, dass Verlustfunktionen uns sagen, wie gut ein Modell bei einem bestimmten Datensatz abschneidet. Technisch gesehen geschieht dies dadurch, dass gemessen wird, wie nahe ein vorhergesagter Wert am tatsächlichen Wert liegt. Wenn unser Modell Vorhersagen macht, die den tatsächlichen Werten sowohl in unserem Trainings- als auch in unserem Testdatensatz sehr nahe kommen, bedeutet das, dass wir über ein recht robustes Modell verfügen.
Obwohl Verlustfunktionen uns wichtige Informationen über die Leistung unseres Modells liefern, ist dies nicht die Hauptfunktion der Verlustfunktion, da es robustere Techniken zur Bewertung unserer Modelle gibt, wie z. B. Genauigkeit und F-Scores. Die Bedeutung von Verlustfunktionen wird vor allem während des Trainings erkannt, wenn wir die Gewichte unseres Modells in die Richtung bewegen, die den Verlust minimiert. Dadurch erhöhen wir die Wahrscheinlichkeit, dass unser Modell korrekte Vorhersagen trifft, was ohne eine Verlustfunktion wahrscheinlich nicht möglich gewesen wäre.
Unterschiedliche Verlustfunktionen eignen sich für unterschiedliche Probleme und werden von Forschern jeweils sorgfältig ausgearbeitet, um einen stabilen Gradientenfluss während des Trainings sicherzustellen.
Manchmal können die mathematischen Ausdrücke von Verlustfunktionen etwas entmutigend sein, was dazu geführt hat, dass einige Entwickler sie als Black Boxes behandeln. Wir werden später einige der am häufigsten verwendeten Verlustfunktionen von PyTorch aufdecken, aber vorher werfen wir einen Blick darauf, wie wir Verlustfunktionen in der Welt von PyTorch verwenden.
Verlustfunktionen in PyTorch
PyTorch verfügt standardmäßig über viele kanonische Verlustfunktionen mit vereinfachten Entwurfsmustern, die es Entwicklern ermöglichen, diese verschiedenen Verlustfunktionen während des Trainings sehr schnell zu durchlaufen. Alle Verlustfunktionen von PyTorch sind im nn-Modul verpackt, der Basisklasse von PyTorch für alle neuronalen Netze. Dadurch ist das Hinzufügen einer Verlustfunktion zu Ihrem Projekt so einfach wie das Hinzufügen einer einzigen Codezeile. Schauen wir uns an, wie man in PyTorch eine Funktion für den mittleren quadratischen Fehlerverlust hinzufügt.
import torch.nn as nn
MSE_loss_fn = nn.MSELoss()
Die vom obigen Code zurückgegebene Funktion kann verwendet werden, um mithilfe des folgenden Formats zu berechnen, wie weit eine Vorhersage vom tatsächlichen Wert entfernt ist.
#predicted_value is the prediction from our neural network
#target is the actual value in our dataset
#loss_value is the loss between the predicted value and the actual value
Loss_value = MSE_loss_fn(predicted_value, target)
Nachdem wir nun eine Vorstellung davon haben, wie Verlustfunktionen in PyTorch verwendet werden, werfen wir einen Blick hinter die Kulissen einiger der von PyTorch angebotenen Verlustfunktionen.
Welche Verlustfunktionen sind in PyTorch verfügbar?
Viele dieser Verlustfunktionen, mit denen PyTorch ausgestattet ist, werden grob in drei Gruppen eingeteilt: Regressionsverlust, Klassifizierungsverlust und Rankingverlust.
Bei Regressionsverlusten handelt es sich meist um kontinuierliche Werte, die jeden Wert zwischen zwei Grenzwerten annehmen können. Ein Beispiel hierfür wären Vorhersagen der Immobilienpreise einer Gemeinde.
Klassifizierungsverlustfunktionen befassen sich mit diskreten Werten, beispielsweise der Aufgabe, ein Objekt als Schachtel, Stift oder Flasche zu klassifizieren.
Ranking-Verluste sagen die relativen Abstände zwischen Werten voraus. Ein Beispiel hierfür wäre die Gesichtsverifizierung, bei der wir wissen möchten, welche Gesichtsbilder zu einem bestimmten Gesicht gehören, und dies erreichen können, indem wir anhand ihres Grades der relativen Annäherung an das Gesicht einordnen, welche Gesichter zum ursprünglichen Gesichtsträger gehören und welche nicht Zielgesichtsscan.
L1-Verlustfunktion/mittlerer absoluter Fehler
Die L1-Verlustfunktion berechnet den mittleren absoluten Fehler zwischen jedem Wert im vorhergesagten Tensor und dem des Ziels. Es berechnet zunächst die absolute Differenz zwischen jedem Wert im vorhergesagten Tensor und dem des Ziels und berechnet die Summe aller Werte, die von jeder Berechnung der absoluten Differenz zurückgegeben werden. Schließlich wird der Durchschnitt dieses Summenwerts berechnet, um den mittleren absoluten Fehler (MAE) zu erhalten. Die L1-Verlustfunktion ist sehr robust im Umgang mit Rauschen.
import torch.nn as nn
#size_average and reduce are deprecated
#reduction specifies the method of reduction to apply to output. Possible values are 'mean' (default) where we compute the average of the output, 'sum' where the output is summed and 'none' which applies no reduction to output
Loss_fn = nn.L1Loss(size_average=None, reduce=None, reduction='mean')
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)
output = loss_fn(input, target)
print(output) #tensor(0.7772, grad_fn=<L1LossBackward>)
Der zurückgegebene Einzelwert ist der berechnete Verlust zwischen zwei Tensoren mit der Dimension 3 x 5.
Mittlerer quadratischer Fehler
Der mittlere quadratische Fehler weist einige bemerkenswerte Ähnlichkeiten mit MAE auf. Anstatt die absolute Differenz zwischen den Werten im Vorhersagetensor und dem Ziel zu berechnen, wie es beim mittleren absoluten Fehler der Fall ist, wird die quadrierte Differenz zwischen den Werten im Vorhersagetensor und denen des Zieltensors berechnet. Dadurch werden relativ große Unterschiede stärker bestraft, während relativ kleine Unterschiede weniger bestraft werden. MSE gilt jedoch als weniger robust im Umgang mit Ausreißern und Rauschen als MAE.
import torch.nn as nn
loss = nn.MSELoss(size_average=None, reduce=None, reduction='mean')
#L1 loss function parameters explanation applies here.
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)
output = loss(input, target)
print(output) #tensor(0.9823, grad_fn=<MseLossBackward>)
Kreuzentropieverlust
Der Kreuzentropieverlust wird bei Klassifizierungsproblemen verwendet, an denen mehrere diskrete Klassen beteiligt sind. Es misst die Differenz zwischen zwei Wahrscheinlichkeitsverteilungen für einen bestimmten Satz von Zufallsvariablen. Wenn Kreuzentropieverlust verwendet wird, ist die Ausgabe unseres Netzwerks normalerweise eine Softmax-Schicht, die sicherstellt, dass die Ausgabe des neuronalen Netzwerks ein Wahrscheinlichkeitswert ist (Wert zwischen 0 und 1).
Die Softmax-Schicht besteht aus zwei Teilen – dem Exponenten der Vorhersage für eine bestimmte Klasse.
yi ist die Ausgabe des neuronalen Netzwerks für eine bestimmte Klasse. Die Ausgabe dieser Funktion ist eine Zahl nahe Null, aber niemals Null, wenn yi groß und negativ ist, und näher an 1, wenn yi positiv und sehr groß ist.
import numpy as np
np.exp(34) #583461742527454.9
np.exp(-34) #1.713908431542013e-15
Der zweite Teil ist ein Normalisierungswert und wird verwendet, um sicherzustellen, dass die Ausgabe der Softmax-Schicht immer ein Wahrscheinlichkeitswert ist.
Dies wird durch Summieren aller Exponenten jedes Klassenwerts erreicht. Die endgültige Gleichung von Softmax sieht folgendermaßen aus:
]
Im nn-Modul von PyTorch kombiniert der Kreuzentropieverlust den Verlust von Log-Softmax und negativer Log-Likelihood (NLL) in einer einzigen Verlustfunktion.
Beachten Sie, dass die Gradientenfunktion in der gedruckten Ausgabe einen NLL-Verlust darstellt. Dies zeigt tatsächlich, dass der Kreuzentropieverlust den NLL-Verlust unter der Haube mit einer Log-Softmax-Schicht kombiniert.
Verlust mit negativer Log-Likelihood (NLL).
Die NLL-Verlustfunktion funktioniert ganz ähnlich wie die Kreuzentropieverlustfunktion. Der Kreuzentropieverlust kombiniert eine Log-Softmax-Schicht und einen NLL-Verlust, um den Wert des Kreuzentropieverlusts zu erhalten. Dies bedeutet, dass der NLL-Verlust verwendet werden kann, um den Kreuzentropieverlustwert zu erhalten, indem die letzte Schicht des neuronalen Netzwerks eine Log-Softmax-Schicht anstelle einer normalen Softmax-Schicht ist.
m = nn.LogSoftmax(dim=1)
loss = nn.NLLLoss()input is of size N x C = 3 x 5
input = torch.randn(3, 5, requires_grad=True)each element in target has to have 0 <= value < C
target = torch.tensor([1, 0, 4])
output = loss(m(input), target)
output.backward()2D loss example (used, for example, with image inputs)
N, C = 5, 4
loss = nn.NLLLoss()input is of size N x C x height x width
data = torch.randn(N, 16, 10, 10)
conv = nn.Conv2d(16, C, (3, 3))
m = nn.LogSoftmax(dim=1)each element in target has to have 0 <= value < C
target = torch.empty(N, 8, 8, dtype=torch.long).random_(0, C)
output = loss(m(conv(data)), target)
print(output) #tensor(1.4892, grad_fn=<NllLoss2DBackward>)
#credit NLLLoss — PyTorch 1.9.0 documentation
Binärer Kreuzentropieverlust
Binärer Kreuzentropieverlust ist eine spezielle Klasse von Kreuzentropieverlusten, die für das spezielle Problem der Klassifizierung von Datenpunkten in nur zwei Klassen verwendet werden. Beschriftungen für diese Art von Problem sind in der Regel binär. Unser Ziel besteht daher darin, das Modell dazu zu bringen, eine Zahl nahe Null für eine Null-Beschriftung und eine Zahl nahe Eins für eine Eins-Beschriftung vorherzusagen. Wenn der BCE-Verlust für die binäre Klassifizierung verwendet wird, ist die Ausgabe des neuronalen Netzwerks normalerweise eine Sigmoidschicht, um sicherzustellen, dass die Ausgabe entweder einen Wert nahe Null oder einen Wert nahe Eins hat.
import torch.nn as nn
m = nn.Sigmoid()
loss = nn.BCELoss()
input = torch.randn(3, requires_grad=True)
target = torch.empty(3).random_(2)
output = loss(m(input), target)
print(output) #tensor(0.4198, grad_fn=<BinaryCrossEntropyBackward>)
Binärer Kreuzentropieverlust mit Logits
Wir haben im vorherigen Abschnitt erwähnt, dass ein binärer Kreuzentropieverlust normalerweise als Sigmoidschicht ausgegeben wird, um sicherzustellen, dass die Ausgabe zwischen 0 und 1 liegt. Ein binärer Kreuzentropieverlust mit Logits kombiniert diese beiden Schichten in nur einer Schicht. Laut PyTorch-Dokumentation handelt es sich hierbei um eine numerisch stabilere Version, da sie den Log-Summen-Exp-Trick nutzt.
import torch
import torch.nn as nn
target = torch.ones([10, 64], dtype=torch.float32) # 64 classes, batch size = 10
output = torch.full([10, 64], 1.5) # A prediction (logit)
pos_weight = torch.ones([64]) # All weights are equal to 1
criterion = torch.nn.BCEWithLogitsLoss(pos_weight=pos_weight)
loss = criterion(output, target) # -log(sigmoid(1.5))
print(loss) #tensor(0.2014)
Glatter L1-Verlust
Die glatte L1-Verlustfunktion kombiniert die Vorteile von MSE-Verlust und MAE-Verlust durch einen heuristischen Wert Beta. Dieses Kriterium wurde im Fast R-CNN-Artikel eingeführt. Wenn die absolute Differenz zwischen dem Grundwahrheitswert und dem vorhergesagten Wert unter Beta liegt, verwendet das Kriterium eine quadrierte Differenz, ähnlich wie beim MSE-Verlust. Das Diagramm des MSE-Verlusts ist eine kontinuierliche Kurve, was bedeutet, dass der Gradient bei jedem Verlustwert variiert und überall abgeleitet werden kann. Darüber hinaus nimmt der Gradient mit abnehmendem Verlustwert ab, was beim Gradientenabstieg praktisch ist. Bei sehr großen Verlustwerten explodiert der Gradient jedoch, daher das Kriterium für den Wechsel zu MAE, bei dem der Gradient für jeden Verlustwert nahezu konstant ist, wenn die absolute Differenz größer als Beta wird und die potenzielle Gradientenexplosion eliminiert wird.
import torch.nn as nn
loss = nn.SmoothL1Loss()
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)
output = loss(input, target)
print(output) #tensor(0.7838, grad_fn=<SmoothL1LossBackward>)
Verlust der Scharniereinbettung
Der Scharniereinbettungsverlust wird hauptsächlich bei halbüberwachten Lernaufgaben verwendet, um die Ähnlichkeit zwischen zwei Eingaben zu messen. Es wird verwendet, wenn ein Eingabetensor und ein Beschriftungstensor vorhanden sind, die Werte von 1 oder -1 enthalten. Es wird hauptsächlich bei Problemen mit nichtlinearen Einbettungen und halbüberwachtem Lernen verwendet.
import torch
import torch.nn as nn
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)
hinge_loss = nn.HingeEmbeddingLoss()
output = hinge_loss(input, target)
output.backward()
print('input: ', input)
print('target: ', target)
print('output: ', output)
#input: tensor([[ 1.4668e+00, 2.9302e-01, -3.5806e-01, 1.8045e-01, #1.1793e+00], [-6.9471e-05, 9.4336e-01, 8.8339e-01, -1.1010e+00, #1.5904e+00], [-4.7971e-02, -2.7016e-01, 1.5292e+00, -6.0295e-01, #2.3883e+00]], requires_grad=True)
#target: tensor([[-0.2386, -1.2860, -0.7707, 1.2827, -0.8612], [ 0.6747, 0.1610, 0.5223, -0.8986, 0.8069], [ 1.0354, 0.0253, 1.0896, -1.0791, -0.0834]])
#output: tensor(1.2103, grad_fn=<MeanBackward0>)
Margin-Ranking-Verlust
Der Margin-Ranking-Verlust gehört zu den Ranking-Verlusten, deren Hauptziel im Gegensatz zu anderen Verlustfunktionen darin besteht, den relativen Abstand zwischen einer Reihe von Eingaben in einem Datensatz zu messen. Die Margin-Ranking-Verlustfunktion benötigt zwei Eingaben und eine Bezeichnung, die nur 1 oder -1 enthält. Wenn die Bezeichnung 1 ist, wird davon ausgegangen, dass die erste Eingabe einen höheren Rang haben sollte als die zweite Eingabe, und wenn die Bezeichnung -1 ist, wird angenommen, dass die zweite Eingabe einen höheren Rang haben sollte als die erste Eingabe. Diese Beziehung wird durch die Gleichung und den Code unten dargestellt.
import torch.nn as nn
loss = nn.MarginRankingLoss()
input1 = torch.randn(3, requires_grad=True)
input2 = torch.randn(3, requires_grad=True)
target = torch.randn(3).sign()
output = loss(input1, input2, target)
print('input1: ', input1)
print('input2: ', input2)
print('output: ', output)
#input1: tensor([-1.1109, 0.1187, 0.9441], requires_grad=True)
#input2: tensor([ 0.9284, -0.3707, -0.7504], requires_grad=True)
#output: tensor(0.5648, grad_fn=<MeanBackward0>)
Triplett-Margenverlust
Dieses Kriterium misst die Ähnlichkeit zwischen Datenpunkten anhand von Tripletts der Trainingsdatenstichprobe. Bei den beteiligten Drillingen handelt es sich um eine Ankerprobe, eine Positivprobe und eine Negativprobe. Das Ziel besteht darin, 1) den Abstand zwischen der positiven Probe und dem Anker so gering wie möglich zu halten und 2) den Abstand zwischen dem Anker und der negativen Probe so zu gestalten, dass er größer als ein Randwert plus dem Abstand zwischen der positiven Probe und ist der Anker. Normalerweise gehört die positive Stichprobe zur gleichen Klasse wie der Anker, die negative Stichprobe jedoch nicht. Mithilfe dieser Verlustfunktion möchten wir daher den Triplett-Margenverlust verwenden, um einen hohen Ähnlichkeitswert zwischen dem Anker und der positiven Stichprobe und einen niedrigen Ähnlichkeitswert zwischen dem Anker und der negativen Stichprobe vorherzusagen.
import torch.nn as nn
triplet_loss = nn.TripletMarginLoss(margin=1.0, p=2)
anchor = torch.randn(100, 128, requires_grad=True)
positive = torch.randn(100, 128, requires_grad=True)
negative = torch.randn(100, 128, requires_grad=True)
output = triplet_loss(anchor, positive, negative)
print(output) #tensor(1.1151, grad_fn=<MeanBackward0>)
Kosinus-Einbettungsverlust
Der Kosinus-Einbettungsverlust misst den Verlust bei gegebenen Eingaben x1, x2 und einem Label-Tensor y, der die Werte 1 oder -1 enthält. Es wird verwendet, um den Grad der Ähnlichkeit oder Unähnlichkeit zweier Eingaben zu messen.
Das Kriterium misst die Ähnlichkeit, indem es den Kosinusabstand zwischen den beiden Datenpunkten im Raum berechnet. Der Kosinusabstand korreliert mit dem Winkel zwischen den beiden Punkten. Das heißt, je kleiner der Winkel, desto näher sind die Eingaben und desto ähnlicher sind sie.
import torch.nn as nn
loss = nn.CosineEmbeddingLoss()
input1 = torch.randn(3, 6, requires_grad=True)
input2 = torch.randn(3, 6, requires_grad=True)
target = torch.randn(3).sign()
output = loss(input1, input2, target)
print('input1: ', input1)
print('input2: ', input2)
print('output: ', output)
#input1: tensor([[ 1.2969e-01, 1.9397e+00, -1.7762e+00, -1.2793e-01, #-4.7004e-01, -1.1736e+00], [-3.7807e-02, 4.6385e-03, -9.5373e-01, 8.4614e-01, -1.1113e+00, 4.0305e-01], [-1.7561e-01, 8.8705e-01, -5.9533e-02, 1.3153e-03, -6.0306e-01, 7.9162e-01]], requires_grad=True)
#input2: tensor([[-0.6177, -0.0625, -0.7188, 0.0824, 0.3192, 1.0410], [-0.5767, 0.0298, -0.0826, 0.5866, 1.1008, 1.6463], [-0.9608, -0.6449, 1.4022, 1.2211, 0.8248, -1.9933]], requires_grad=True)
#output: tensor(0.0033, grad_fn=<MeanBackward0>)
Kullback-Leibler-Divergenzverlust
Bei zwei Verteilungen, P und Q, misst der Kullback-Leibler (KL)-Divergenzverlust, wie viele Informationen verloren gehen, wenn P (angenommen, dass es sich um die wahren Verteilungen handelt) durch Q ersetzt wird. Indem wir messen, wie viele Informationen verloren gehen, wenn wir Q zur Approximation verwenden P, wir sind in der Lage, die Ähnlichkeit zwischen P und Q zu ermitteln und somit unseren Algorithmus so zu steuern, dass er eine Verteilung erzeugt, die der wahren Verteilung P sehr nahe kommt. Der Informationsverlust, wenn Q zur Approximation von P verwendet wird, ist nicht derselbe, wenn P dazu verwendet wird ungefähr Q, und daher ist die KL-Divergenz nicht symmetrisch.
import torch.nn as nn
loss = nn.KLDivLoss(size_average=None, reduce=None, reduction='mean', log_target=False)
input1 = torch.randn(3, 6, requires_grad=True)
input2 = torch.randn(3, 6, requires_grad=True)
output = loss(input1, input2)
print('output: ', output) #tensor(-0.0284, grad_fn=<KlDivBackward>)
Erstellen einer benutzerdefinierten Verlustfunktion
PyTorch bietet uns zwei beliebte Möglichkeiten, unsere eigene Verlustfunktion entsprechend unserem Problem zu erstellen; Dies sind nämlich die Verwendung einer Klassenimplementierung und die Verwendung einer Funktionsimplementierung. Sehen wir uns an, wie wir beide Methoden implementieren können, beginnend mit der Funktionsimplementierung.
Dies ist mit Abstand die einfachste Möglichkeit, Ihre eigene benutzerdefinierte Verlustfunktion zu schreiben. Es ist genauso einfach wie das Erstellen einer Funktion, das Übergeben der erforderlichen Eingaben und anderer Parameter, das Ausführen einer Operation mithilfe der Kern-API oder Funktions-API von PyTorch und das Zurückgeben eines Werts. Sehen wir uns eine Demonstration mit einem benutzerdefinierten mittleren quadratischen Fehler an.
def custom_mean_square_error(y_predictions, target):
square_difference = torch.square(y_predictions - target)
loss_value = torch.mean(square_difference)
return loss_value
Im obigen Code definieren wir eine benutzerdefinierte Verlustfunktion, um den mittleren quadratischen Fehler bei einem gegebenen Vorhersagetensor und einem Zieltensor zu berechnen
y_predictions = torch.randn(3, 5, requires_grad=True);
target = torch.randn(3, 5)
pytorch_loss = nn.MSELoss();
p_loss = pytorch_loss(y_predictions, target)
loss = custom_mean_square_error(y_predictions, target)
print('custom loss: ', loss)
print('pytorch loss: ', p_loss)
#custom loss: tensor(2.3134, grad_fn=<MeanBackward0>)
#pytorch loss: tensor(2.3134, grad_fn=<MseLossBackward>)
Wir können den Verlust mit unserer benutzerdefinierten Verlustfunktion und der MSE-Verlustfunktion von PyTorch berechnen und feststellen, dass wir die gleichen Ergebnisse erhalten haben.
Benutzerdefinierter Verlust mit Python-Klassen
Dieser Ansatz ist wahrscheinlich die standardmäßige und empfohlene Methode zum Definieren benutzerdefinierter Verluste in PyTorch. Die Verlustfunktion wird durch Unterklassifizierung des nn-Moduls als Knoten im neuronalen Netzwerkdiagramm erstellt. Das bedeutet, dass unsere benutzerdefinierte Verlustfunktion genauso eine PyTorch-Ebene ist wie eine Faltungsebene. Sehen wir uns eine Demonstration an, wie dies mit einem benutzerdefinierten MSE-Verlust funktioniert.
class Custom_MSE(nn.Module):
def __init__(self):
super(Custom_MSE, self).__init__();
def forward(self, predictions, target):
square_difference = torch.square(predictions - target)
loss_value = torch.mean(square_difference)
return loss_value
def __call__(self, predictions, target):
square_difference = torch.square(y_predictions - target)
loss_value = torch.mean(square_difference)
return loss_value
Letzte Gedanken
Wir haben viel über die in PyTorch verfügbaren Verlustfunktionen diskutiert und uns auch intensiv mit dem Innenleben der meisten dieser Verlustfunktionen befasst. Die Wahl der richtigen Verlustfunktion für ein bestimmtes Problem kann eine überwältigende Aufgabe sein. Hoffentlich dient dieses Tutorial zusammen mit der offiziellen PyTorch-Dokumentation als Leitfaden, wenn Sie versuchen zu verstehen, welche Verlustfunktion am besten zu Ihrem Problem passt.