Der Verlust springt abrupt, wenn ich die Lernrate mit dem Adam-Optimierer in PyTorch reduziere

10

Ich trainiere ein auto-encoderNetzwerk mit AdamOptimierer (mit amsgrad=True) und MSE lossfür die Aufgabe der Einkanal-Audioquellentrennung. Immer wenn ich die Lernrate um einen Faktor verringere, springt der Netzwerkverlust abrupt und nimmt dann bis zum nächsten Abfall der Lernrate ab.

Ich verwende Pytorch für die Netzwerkimplementierung und Schulung.

Following are my experimental setups:

 Setup-1: NO learning rate decay, and 
          Using the same Adam optimizer for all epochs

 Setup-2: NO learning rate decay, and 
          Creating a new Adam optimizer with same initial values every epoch

 Setup-3: 0.25 decay in learning rate every 25 epochs, and
          Creating a new Adam optimizer every epoch

 Setup-4: 0.25 decay in learning rate every 25 epochs, and
          NOT creating a new Adam optimizer every time rather
          using PyTorch's "multiStepLR" and "ExponentialLR" decay scheduler 
          every 25 epochs

Ich erhalte sehr überraschende Ergebnisse für die Setups Nr. 2, Nr. 3, Nr. 4 und kann keine Erklärung dafür liefern. Folgendes sind meine Ergebnisse:

Setup-1 Results:

Here I'm NOT decaying the learning rate and 
I'm using the same Adam optimizer. So my results are as expected.
My loss decreases with more epochs.
Below is the loss plot this setup.

Plot-1:

Setup-1 Ergebnisse

optimizer = torch.optim.Adam(lr=m_lr,amsgrad=True, ...........)

for epoch in range(num_epochs):
    running_loss = 0.0
    for i in range(num_train):
        train_input_tensor = ..........                    
        train_label_tensor = ..........
        optimizer.zero_grad()
        pred_label_tensor = model(train_input_tensor)
        loss = criterion(pred_label_tensor, train_label_tensor)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    loss_history[m_lr].append(running_loss/num_train)

Setup-2 Results:  

Here I'm NOT decaying the learning rate but every epoch I'm creating a new
Adam optimizer with the same initial parameters.
Here also results show similar behavior as Setup-1.

Because at every epoch a new Adam optimizer is created, so the calculated gradients
for each parameter should be lost, but it seems that this doesnot affect the 
network learning. Can anyone please help on this?

Grundstück 2:

Setup-2 Ergebnisse

for epoch in range(num_epochs):
    optimizer = torch.optim.Adam(lr=m_lr,amsgrad=True, ...........)

    running_loss = 0.0
    for i in range(num_train):
        train_input_tensor = ..........                    
        train_label_tensor = ..........
        optimizer.zero_grad()
        pred_label_tensor = model(train_input_tensor)
        loss = criterion(pred_label_tensor, train_label_tensor)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    loss_history[m_lr].append(running_loss/num_train)

Setup-3 Results: 

As can be seen from the results in below plot, 
my loss jumps every time I decay the learning rate. This is a weird behavior.

If it was happening due to the fact that I'm creating a new Adam 
optimizer every epoch then, it should have happened in Setup #1, #2 as well.
And if it is happening due to the creation of a new Adam optimizer with a new 
learning rate (alpha) every 25 epochs, then the results of Setup #4 below also 
denies such correlation.

Grundstück 3:

Setup-3 Ergebnisse

decay_rate = 0.25
for epoch in range(num_epochs):
    optimizer = torch.optim.Adam(lr=m_lr,amsgrad=True, ...........)

    if epoch % 25 == 0  and epoch != 0:
        lr *= decay_rate   # decay the learning rate

    running_loss = 0.0
    for i in range(num_train):
        train_input_tensor = ..........                    
        train_label_tensor = ..........
        optimizer.zero_grad()
        pred_label_tensor = model(train_input_tensor)
        loss = criterion(pred_label_tensor, train_label_tensor)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    loss_history[m_lr].append(running_loss/num_train)

Setup-4 Results:  

In this setup, I'm using Pytorch's learning-rate-decay scheduler (multiStepLR)
which decays the learning rate every 25 epochs by 0.25.
Here also, the loss jumps everytime the learning rate is decayed.

Wie von @Dennis in den Kommentaren unten vorgeschlagen, habe ich es mit beiden ReLUund 1e-02 leakyReLUNichtlinearitäten versucht . Aber die Ergebnisse scheinen sich ähnlich zu verhalten und der Verlust nimmt zuerst ab, steigt dann an und sättigt sich dann bei einem höheren Wert als dem, was ich ohne Abnahme der Lernrate erreichen würde.

Diagramm 4 zeigt die Ergebnisse.

Grundstück 4:

Geben Sie hier die Bildbeschreibung ein

scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer=optimizer, milestones=[25,50,75], gamma=0.25)

scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer, gamma=0.95)

scheduler = ......... # defined above
optimizer = torch.optim.Adam(lr=m_lr,amsgrad=True, ...........)

for epoch in range(num_epochs):

    scheduler.step()

    running_loss = 0.0
    for i in range(num_train):
        train_input_tensor = ..........                    
        train_label_tensor = ..........
        optimizer.zero_grad()
        pred_label_tensor = model(train_input_tensor)
        loss = criterion(pred_label_tensor, train_label_tensor)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    loss_history[m_lr].append(running_loss/num_train)

EDITS:

  • Wie in den Kommentaren und Antworten unten vorgeschlagen, habe ich Änderungen an meinem Code vorgenommen und das Modell trainiert. Ich habe den Code und die Diagramme für dasselbe hinzugefügt.
  • Ich habe versucht, mit verschiedenen lr_schedulerIn PyTorch (multiStepLR, ExponentialLR)und Plots für die gleichen sind in aufgeführt, Setup-4wie von @Dennis in den Kommentaren unten vorgeschlagen.
  • Versuchen Sie es mit leakyReLU, wie von @Dennis in den Kommentaren vorgeschlagen.

Irgendeine Hilfe. Vielen Dank

vinaykumar2491
quelle
Kommentare sind nicht für eine ausführliche Diskussion gedacht. Dieses Gespräch wurde in den Chat verschoben .
Ben N

Antworten:

8

Ich sehe keinen Grund, warum sinkende Lernraten die Art von Verlustsprüngen hervorrufen sollten, die Sie beobachten. Es sollte "verlangsamen", wie schnell Sie sich "bewegen", was im Falle eines Verlusts, der ansonsten konstant schrumpft, im schlimmsten Fall nur zu einem Plateau Ihrer Verluste führen sollte (und nicht zu diesen Sprüngen).

Das erste, was ich in Ihrem Code beobachte, ist, dass Sie den Optimierer in jeder Epoche von Grund auf neu erstellen. Ich habe noch nicht genug mit PyTorch gearbeitet, um sicher zu sein, aber zerstört dies nicht jedes Mal den internen Status / Speicher des Optimierers? Ich denke, Sie sollten den Optimierer nur einmal erstellen, bevor Sie die Epochen durchlaufen. Wenn dies tatsächlich ein Fehler in Ihrem Code ist, sollte es auch dann noch ein Fehler sein, wenn Sie den Lernratenabfall nicht verwenden ... aber vielleicht haben Sie dort einfach Glück und erleben nicht die gleichen negativen Auswirkungen von Fehler.

Für den Rückgang der Lernrate würde ich empfehlen, dafür die offizielle API anstelle einer manuellen Lösung zu verwenden. In Ihrem speziellen Fall möchten Sie einen StepLR- Scheduler instanziieren , mit:

  • optimizer = der ADAM-Optimierer, den Sie wahrscheinlich nur einmal instanziieren sollten.
  • step_size = 25
  • gamma = 0.25

Sie können dann einfach scheduler.step()zu Beginn jeder Epoche aufrufen (oder am Ende? Das Beispiel im API-Link ruft es zu Beginn jeder Epoche auf).


Wenn nach den obigen Änderungen das Problem weiterhin auftritt, ist es auch hilfreich, jedes Ihrer Experimente mehrmals auszuführen und die durchschnittlichen Ergebnisse (oder die Linien für alle Experimente) zu zeichnen. Ihre Experimente sollten theoretisch während der ersten 25 Epochen identisch sein, aber wir sehen immer noch große Unterschiede zwischen den beiden Figuren, selbst während der ersten 25 Epochen, in denen kein Lernratenabfall auftritt (z. B. beginnt eine Figur mit einem Verlust von ~ 28K, die andere beginnt mit einem Verlust von ~ 40K). Dies kann einfach auf unterschiedliche zufällige Initialisierungen zurückzuführen sein. Es wäre also gut, das Nichtdeterminisim aus Ihren Plots zu mitteln.

Dennis Soemers
quelle
1
Kommentare sind nicht für eine ausführliche Diskussion gedacht. Dieses Gespräch wurde in den Chat verschoben .
Ben N