Mất dần và nổ gradient

Deep Learning nâng cao với PyTorch

Michal Oleszak

Machine Learning Engineer

Gradient mất dần

  • Gradient nhỏ dần khi lan truyền ngược
  • Các lớp đầu nhận cập nhật nhỏ
  • Mô hình không học được

Đồ thị kích thước gradient theo chỉ số lớp: ở các lớp đầu, gradient nhỏ hơn

Deep Learning nâng cao với PyTorch

Gradient nổ

  • Gradient lớn dần
  • Cập nhật tham số quá lớn
  • Huấn luyện phân kỳ

Đồ thị kích thước gradient theo chỉ số lớp: ở các lớp đầu, gradient lớn hơn

Deep Learning nâng cao với PyTorch

Giải pháp cho gradient không ổn định

  1. Khởi tạo trọng số đúng
  2. Chọn hàm kích hoạt tốt
  3. Batch normalization

 

 

Ba bước

Deep Learning nâng cao với PyTorch

Khởi tạo trọng số

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 nâng cao với PyTorch

Khởi tạo trọng số

Khởi tạo tốt đảm bảo:

  • Phương sai đầu vào lớp = phương sai đầu ra lớp
  • Phương sai gradient giống nhau trước và sau lớp

 

Cách thực hiện phụ thuộc vào hàm kích hoạt:

  • Với ReLU và tương tự, dùng khởi tạo He/Kaiming
Deep Learning nâng cao với PyTorch

Khởi tạo trọng số

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 nâng cao với PyTorch

Khởi tạo He / Kaiming

init.kaiming_uniform_(self.fc1.weight)
init.kaiming_uniform_(self.fc2.weight)
init.kaiming_uniform_(
  self.fc3.weight,
  nonlinearity="sigmoid",
)
Deep Learning nâng cao với PyTorch

Khởi tạo He / Kaiming

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 nâng cao với PyTorch

Hàm kích hoạt

Đồ thị hàm ReLU. Với giá trị < 0, đường nằm ngang tại 0; với giá trị > 0, đường dốc lên.

  • Thường là hàm kích hoạt mặc định
  • nn.functional.relu()
  • Bằng 0 với đầu vào âm - neuron “chết”

Đồ thị hàm ELU. Tương tự ReLU nhưng chuyển tiếp mượt và cong từ âm sang dương.

  • nn.functional.elu()
  • Gradient khác 0 cho giá trị âm - giảm neuron “chết”
  • Trung bình đầu ra quanh 0 - giảm mất dần gradient
Deep Learning nâng cao với PyTorch

Batch normalization

Sau mỗi lớp:

  1. Chuẩn hóa đầu ra lớp bằng:

    • Trừ đi trung bình
    • Chia cho độ lệch chuẩn
  2. Co giãn và tịnh tiến giá trị đã chuẩn hóa bằng tham số học được

Mô hình học phân phối đầu vào tối ưu cho từng lớp:

  • Giảm loss nhanh hơn
  • Giảm gradient không ổn định
Deep Learning nâng cao với 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 nâng cao với PyTorch

Ayo berlatih!

Deep Learning nâng cao với PyTorch

Preparing Video For Download...