การสูญเสียเพิ่มขึ้นทันทีเมื่อฉันสลายอัตราการเรียนรู้ด้วย Adam optimizer ใน 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:

ผลลัพธ์ Setup-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:

ผลลัพธ์ Setup-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:

ผลลัพธ์ Setup-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ไม่เป็นเชิงเส้น แต่ดูเหมือนว่าผลลัพธ์จะมีลักษณะที่คล้ายกันและการสูญเสียลดลงก่อนจากนั้นเพิ่มขึ้นและอิ่มตัวด้วยค่าที่สูงกว่าสิ่งที่ฉันจะประสบความสำเร็จโดยไม่ต้องสลายตัวอัตราการเรียนรู้

Plot-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 ในความคิดเห็น

ความช่วยเหลือใด ๆ ขอบคุณ


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
Ben N

คำตอบ:


8

ฉันไม่เห็นเหตุผลว่าทำไมอัตราการเรียนรู้ที่เน่าเปื่อยควรสร้างประเภทของการกระโดดในการสูญเสียที่คุณสังเกต มันควรจะ "ช้าลง" เร็วแค่ไหนที่คุณ "เคลื่อนไหว" ซึ่งในกรณีของการสูญเสียที่ควรลดขนาดลงอย่างสม่ำเสมอที่เลวร้ายที่สุดเพียงแค่นำไปสู่ที่ราบสูงในการสูญเสียของคุณ (แทนที่จะกระโดด)

สิ่งแรกที่ฉันสังเกตเห็นในรหัสของคุณคือคุณสร้างเครื่องมือเพิ่มประสิทธิภาพขึ้นใหม่ตั้งแต่ต้นทุกยุค ฉันยังไม่ได้ทำงานกับ PyTorch มากพอที่จะบอกได้อย่างแน่นอน แต่นี่ไม่เพียงทำลายสถานะภายใน / หน่วยความจำของเครื่องมือเพิ่มประสิทธิภาพทุกครั้งหรือ ฉันคิดว่าคุณควรสร้างเครื่องมือเพิ่มประสิทธิภาพหนึ่งครั้งก่อนที่จะวนซ้ำผ่านยุค หากนี่เป็นข้อผิดพลาดในรหัสของคุณมันก็ควรจะเป็นข้อผิดพลาดในกรณีที่คุณไม่ได้ใช้อัตราการเรียนรู้ที่ลดลง ... แต่บางทีคุณอาจโชคดีที่นั่นและไม่มีผลกระทบเชิงลบแบบเดียวกันกับ แมลง

สำหรับการลดอัตราการเรียนรู้ฉันขอแนะนำให้ใช้API อย่างเป็นทางการแทนการแก้ปัญหาด้วยตนเอง ในกรณีเฉพาะของคุณคุณจะต้องยกตัวอย่างตารางเวลาStepLRด้วย:

  • optimizer = เครื่องมือเพิ่มประสิทธิภาพ ADAM ซึ่งคุณควรจะยกตัวอย่างเพียงครั้งเดียว
  • step_size = 25
  • gamma = 0.25

จากนั้นคุณสามารถโทรหาscheduler.step()ตอนเริ่มต้นของทุกยุค (หรือท้ายที่สุดตัวอย่างในลิงก์ API เรียกมันว่าตอนเริ่มต้นของทุกยุค)


หากหลังจากการเปลี่ยนแปลงข้างต้นคุณยังคงประสบปัญหาอยู่จะเป็นประโยชน์ในการเรียกใช้การทดสอบแต่ละครั้งของคุณหลายครั้งและพล็อตผลลัพธ์โดยเฉลี่ย (หรือเส้นการลงจุดสำหรับการทดสอบทั้งหมด) การทดลองของคุณในทางทฤษฎีควรเหมือนกันในช่วง 25 epoch แรก แต่เรายังเห็นความแตกต่างอย่างมากระหว่างสองร่างแม้ในช่วง 25 epochs แรกที่ไม่มีการสลายตัวของอัตราการเรียนรู้ (เช่นรูปหนึ่งเริ่มที่สูญเสีย ~ 28K เริ่มที่การสูญเสียของ ~ 40K) นี่อาจเป็นเพราะการเริ่มต้นแบบสุ่มที่แตกต่างกันดังนั้นมันเป็นการดีที่จะเฉลี่ยที่ nondeterminisim จากแปลงของคุณ


1
ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
Ben N
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.