PyTorch에서 Adam 옵티 마이저로 학습 속도를 떨어 뜨리면 손실이 갑자기 증가합니다.


11

최적화 프로그램 ( )을 사용하고 단일 채널 오디오 소스 분리 작업을 수행 하는 auto-encoder네트워크를 훈련하고 있습니다 . 학습률을 한 요인 씩 감퇴시킬 때마다 네트워크 손실이 급격히 증가한 다음 학습률이 다음 감퇴 할 때까지 감소합니다.Adamamsgrad=TrueMSE 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에 의해 제안, 나는 모두 시도 ReLU1e-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)

EDITS :

  • 아래의 의견과 답변에서 제안한대로 코드를 변경하고 모델을 훈련했습니다. 코드와 플롯을 추가했습니다.
  • 나는 여러 가지로 시도 lr_scheduler에서 PyTorch (multiStepLR, ExponentialLR)동일한에 대한 플롯에 나와있는 Setup-4아래 의견 @Dennis에 의해 제안.
  • 의견에서 @Dennis가 제안한 leakyReLU 시도.

어떤 도움이라도. 감사


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
벤 N

답변:


8

나는 학습률이 쇠퇴하는 것이 당신이 관찰하고있는 손실의 종류를 뛰어 넘어야 할 이유가 없다고 본다. 그것은 당신이 얼마나 빨리 "이동"하는지 "느리게"해야합니다. 그렇지 않으면 지속적으로 줄어드는 손실의 경우, 실제로 최악의 경우, 그 점프보다는 오히려 손실의 정체로 이어져야합니다.

코드에서 가장 먼저 관찰하는 것은 모든 시대를 처음부터 최적화 프로그램을 다시 작성한다는 것입니다. 나는 아직 PyTorch와 충분히 협력하지 않았지만 매번 옵티마이 저의 내부 상태 / 메모리를 파괴하지는 않습니까? 에포크를 반복하기 전에 옵티 마이저를 한 번만 만들어야한다고 생각합니다. 이것이 실제로 코드의 버그 인 경우 학습 속도 감소를 사용하지 않는 경우에도 실제로 버그 일 것입니다. 그러나 어쩌면 단순히 운이 좋을 수도 있고 곤충.

학습 속도 감소를 위해서는 수동 솔루션이 아닌 공식 API를 사용하는 것이 좋습니다 . 특별한 경우에는 다음 과 같이 StepLR 스케줄러 를 인스턴스화해야합니다 .

  • optimizer = ADAM 최적화 프로그램. 한 번만 인스턴스화해야합니다.
  • step_size = 25
  • gamma = 0.25

그런 다음 scheduler.step()모든 에포크의 시작시에 간단히 호출 할 수 있습니다 (또는 어쩌면 API 링크의 예제는 모든 에포크의 시작에 호출합니다).


위의 변경 후에도 여전히 문제가 발생하면 각 실험을 여러 번 실행하고 평균 결과 (또는 모든 실험에 대한 플롯 라인)를 플롯하는 것이 유용합니다. 실험은 이론적으로 처음 25 시대 동안 동일해야하지만 학습 속도 붕괴가 발생하지 않는 처음 25 시대 동안에도 두 수치 사이에는 큰 차이가 있습니다. ~ 40K의 손실에서 시작). 이것은 단순히 임의의 초기화가 다르기 때문일 수 있으므로 플롯에서 그 비결정을 평균화하는 것이 좋습니다.


1
의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
벤 N
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.