Втрата різко стрибає, коли я знижую рівень навчання за допомогою оптимізатора Адама в PyTorch


11

Я треную auto-encoderмережу з Adamоптимізатором (з amsgrad=True) таMSE loss завданням розділення одноканального аудіо джерела. Кожного разу, коли я знижую коефіцієнт навчання на коефіцієнт, втрати мережі різко стрибають, а потім зменшуються до наступного занепаду швидкості навчання.

Я використовую Pytorch для реалізації мережі та навчання.

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

Я отримую дуже дивовижні результати для налаштувань №2, №3, №4 і не можу пояснити це жодним поясненням. Ось мої результати:

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.

Сюжет-1:

Результати настройки 1

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?

Ділянка-2:

Результати настройки 2

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.

Сюжет-3:

Налаштування-3 результати

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.

Як запропонував @Dennis в коментарях нижче, я спробував і те, і інше ReLU і1e-02 leakyReLU . Але результати, схоже, поводяться аналогічно, і втрати спочатку зменшуються, потім збільшуються, а потім насичуються більш високою цінністю, ніж те, що я досяг би без зниження рівня швидкості навчання.

Сюжет-4 показує результати.

Сюжет-4:

введіть тут опис зображення

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)

ЗМІНИ:

  • Як запропоновано в коментарях та відповіді нижче, я внесла зміни до свого коду та навчила модель. Я додав код і сюжети для того ж.
  • Я намагався з різними lr_schedulerв PyTorch (multiStepLR, ExponentialLR)і сюжети для того ж перераховані вSetup-4 як запропоновано @Dennis в коментарях нижче.
  • Спробуйте з leakyReLU, як запропонував @Dennis у коментарях.

Будь-яка допомога. Дякую


Коментарі не для розширеного обговорення; ця розмова була переміщена до чату .
Бен N

Відповіді:


8

Я не бачу причин, через які зменшувані темпи навчання повинні створювати види стрибків втрат, які ви спостерігаєте. Це повинно "уповільнити" те, як швидко ви "рухаєтесь", що у випадку втрати, яка інакше послідовно скорочується насправді, повинна, в гіршому випадку, просто призвести до плато ваших втрат (а не цих стрибків).

Перше, що я помічаю у вашому коді, це те, що ви заново створюєте оптимізатор з нуля кожної епохи. Я ще не працював достатньо з PyTorch, щоб точно сказати, але чи не просто це руйнує внутрішній стан / пам'ять оптимізатора кожного разу? Я думаю, вам слід просто створити оптимізатор один раз, перед циклом через епохи. Якщо це дійсно помилка у вашому коді, він також повинен бути помилкою у випадку, коли ви не використовуєте зменшення швидкості навчання ... але, можливо, вам просто пощастить і не відчуєте однакових негативних наслідків помилка.

Для зниження швидкості навчання я рекомендую використовувати для цього офіційний API , а не ручне рішення. У вашому конкретному випадку вам потрібно створити планувальник StepLR за допомогою:

  • optimizer = оптимізатор ADAM, який, ймовірно, слід створити лише один раз.
  • step_size = 25
  • gamma = 0.25

Потім ви можете просто зателефонувати scheduler.step()на початку кожної епохи (а може, наприкінці? Приклад у посиланні API називає її на початку кожної епохи).


Якщо після змін, зазначених вище, ви все ще відчуваєте проблему, також було б корисно запустити кожен ваш експеримент кілька разів та скласти середні результати (або графіки для всіх експериментів). Ваші експерименти теоретично повинні бути однаковими протягом перших 25 епох, але ми все ще бачимо величезні відмінності між цими двома фігурами навіть під час тих перших 25 епох, у яких не відбувається зниження швидкості навчання (наприклад, одна цифра починається з втрати ~ 28 К, інша починається з втрати ~ 40 К). Це може бути просто пов'язано з різними випадковими ініціалізаціями, тому було б добре оцінити, що недетермінімізується з ваших ділянок.


1
Коментарі не для розширеного обговорення; ця розмова була переміщена до чату .
Бен N
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.