Vanishing and exploding gradients

Deep Learning ระดับกลางด้วย PyTorch

Michal Oleszak

Machine Learning Engineer

Vanishing gradients

  • Gradient ยิ่งเล็กลงเรื่อยๆ ระหว่าง backward pass
  • เลเยอร์ต้นๆ ได้รับการอัปเดตพารามิเตอร์น้อยมาก
  • โมเดลไม่เกิดการเรียนรู้

กราฟแสดงขนาด gradient เทียบกับดัชนีเลเยอร์: เลเยอร์ต้นๆ มี gradient ขนาดเล็กกว่า

Deep Learning ระดับกลางด้วย PyTorch

Exploding gradients

  • Gradient ยิ่งใหญ่ขึ้นเรื่อยๆ
  • การอัปเดตพารามิเตอร์มีขนาดใหญ่เกินไป
  • การเทรนไม่ลู่เข้า

กราฟแสดงขนาด gradient เทียบกับดัชนีเลเยอร์: เลเยอร์ต้นๆ มี gradient ขนาดใหญ่กว่า

Deep Learning ระดับกลางด้วย PyTorch

วิธีแก้ปัญหา unstable gradients

  1. การกำหนดค่าเริ่มต้นของน้ำหนักที่เหมาะสม
  2. ฟังก์ชัน activation ที่ดี
  3. Batch normalization

 

 

สามขั้นตอน

Deep Learning ระดับกลางด้วย PyTorch

การกำหนดค่าเริ่มต้นของน้ำหนัก

layer = nn.Linear(8, 1)
print(layer.weight)
Parameter containing:
tensor([[-0.0195,  0.0992,  0.0391,  0.0212,
         -0.3386, -0.1892, -0.3170,  0.2148]])
Deep Learning ระดับกลางด้วย PyTorch

การกำหนดค่าเริ่มต้นของน้ำหนัก

การกำหนดค่าเริ่มต้นที่ดีช่วยให้:

  • Variance ของอินพุตเลเยอร์ = Variance ของเอาต์พุตเลเยอร์
  • Variance ของ gradient ไม่เปลี่ยนแปลงก่อนและหลังเลเยอร์

 

วิธีการขึ้นอยู่กับฟังก์ชัน activation ที่ใช้:

  • สำหรับ ReLU และฟังก์ชันที่คล้ายกัน ใช้ He/Kaiming initialization ได้
Deep Learning ระดับกลางด้วย PyTorch

การกำหนดค่าเริ่มต้นของน้ำหนัก

import torch.nn.init as init

init.kaiming_uniform_(layer.weight)
print(layer.weight)
Parameter containing:
tensor([[-0.3063, -0.2410,  0.0588,  0.2664,
          0.0502, -0.0136,  0.2274,  0.0901]])
Deep Learning ระดับกลางด้วย PyTorch

He / Kaiming initialization

init.kaiming_uniform_(self.fc1.weight)
init.kaiming_uniform_(self.fc2.weight)
init.kaiming_uniform_(
  self.fc3.weight,
  nonlinearity="sigmoid",
)
Deep Learning ระดับกลางด้วย PyTorch

He / Kaiming initialization

import torch.nn as nn
import torch.nn.init as init

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(9, 16)
        self.fc2 = nn.Linear(16, 8)
        self.fc3 = nn.Linear(8, 1)


init.kaiming_uniform_(self.fc1.weight) init.kaiming_uniform_(self.fc2.weight) init.kaiming_uniform_( self.fc3.weight, nonlinearity="sigmoid", )




    def forward(self, x):
        x = nn.functional.relu(self.fc1(x))
        x = nn.functional.relu(self.fc2(x))
        x = nn.functional.sigmoid(self.fc3(x))
        return x







Deep Learning ระดับกลางด้วย PyTorch

ฟังก์ชัน activation

กราฟแสดงฟังก์ชัน ReLU ค่าที่ต่ำกว่าศูนย์จะเป็นแนวนอนที่ศูนย์ ค่าที่สูงกว่าศูนย์จะมีความชันเป็นบวก

  • มักใช้เป็น activation เริ่มต้น
  • nn.functional.relu()
  • ค่าเป็นศูนย์สำหรับอินพุตติดลบ — ปัญหา dying neurons

กราฟแสดงฟังก์ชัน ELU คล้ายกับ ReLU แต่มีการเปลี่ยนผ่านที่โค้งมนและราบเรียบจากค่าติดลบสู่บริเวณค่าบวก

  • nn.functional.elu()
  • Gradient ไม่เป็นศูนย์สำหรับค่าติดลบ — ช่วยป้องกัน dying neurons
  • เอาต์พุตเฉลี่ยใกล้ศูนย์ — ช่วยป้องกัน vanishing gradients
Deep Learning ระดับกลางด้วย PyTorch

Batch normalization

หลังแต่ละเลเยอร์:

  1. นอร์มอลไลซ์เอาต์พุตของเลเยอร์โดย:

    • ลบค่าเฉลี่ย
    • หารด้วยส่วนเบี่ยงเบนมาตรฐาน
  2. สเกลและเลื่อนเอาต์พุตที่นอร์มอลไลซ์แล้วด้วยพารามิเตอร์ที่เรียนรู้ได้

โมเดลเรียนรู้การกระจายอินพุตที่เหมาะสมสำหรับแต่ละเลเยอร์:

  • Loss ลดลงเร็วขึ้น
  • ช่วยป้องกัน unstable gradients
Deep Learning ระดับกลางด้วย PyTorch

Batch normalization

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(9, 16)
        self.bn1 = nn.BatchNorm1d(16)

        ...


def forward(self, x): x = self.fc1(x) x = self.bn1(x) x = nn.functional.elu(x) ...
Deep Learning ระดับกลางด้วย PyTorch

มาฝึกกันเถอะ!

Deep Learning ระดับกลางด้วย PyTorch

Preparing Video For Download...