فاز 3 · درس 8

مقداردهی اولیه وزن‌ها و پایداری آموزش در یادگیری عمیق

نوع
ساختنی
زمان
حدود 90 دقیقه
زبان‌ها
Python
پیش‌نیاز
درس 03.04 (توابع اکتیویشن)، درس 03.07 (منظم‌سازی)
مجموعه‌ای منظم از دومینوهای متوالی روی یک سطح که تعادل ظریف و پایداری انتشار نیرو در طول مسیر را نشان می‌دهند
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفاهیم پایه
  4. مسئله‌ی تقارن
  5. انتشار واریانس در لایه‌ها
  6. مقداردهی اولیه‌ی Xavier/Glorot
  7. مقداردهی اولیه‌ی Kaiming/He
  8. مقداردهی اولیه‌ی ترنسفورمر
  9. بزرگی اکتیویشن در 50 لایه
  10. انتخاب روش مقداردهی مناسب
  11. پیاده‌سازی گام‌به‌گام
  12. گام 1: استراتژی‌های مقداردهی اولیه
  13. گام 2: توابع اکتیویشن
  14. گام 3: گذر رو به جلو در 50 لایه
  15. گام 4: اجرای آزمایش
  16. گام 5: نمایش مسئله‌ی تقارن
  17. گام 6: گزارش لایه‌به‌لایه‌ی بزرگی مقادیر
  18. کاربرد در پروژه‌های واقعی
  19. تحویل پروژه
  20. تمرین‌ها
  21. اصطلاحات کلیدی
  22. برای مطالعه‌ی بیشتر

بسیاری از مدل‌های یادگیری عمیق پیش از آنکه اولین گام بهینه‌سازی را بردارند، در مرحله‌ی مقداردهی اولیه شکست می‌خورند. اگر وزن‌ها را اشتباه تنظیم کنید، سیگنال اکتیویشن‌ها در همان چند لایه‌ی اول یا به صفر سقوط می‌کند یا با مقادیری نجومی منفجر می‌شود؛ در نتیجه گرادیان‌ها ناپدید می‌شوند و عملاً هیچ یادگیری رخ نمی‌دهد.

درک ریاضی رفتار واریانس در گذر رو به جلو و پس‌انتشار به شما امکان می‌دهد دلیل طراحی روش‌های معروفی مثل Xavier/Glorot و Kaiming/He را متوجه شوید. تطبیق دقیق تابع اکتیویشن (مانند ReLU یا Tanh) با استراتژی مقداردهی، شرط اصلی پایدار ماندن آموزش در شبکه‌های بسیار عمیق و ترنسفورمرها است.

پیاده‌سازی این درس را می‌توانید بدون نیاز به منابع پردازشی خاص یا GPU ابری، به‌راحتی روی پردازنده‌ی سیستم محلی خود اجرا کرده و اثر مقیاس وزن‌ها را بر پایداری آموزش ارزیابی کنید.

وزن‌دهی اولیه را اشتباه انجام دهید، آموزش هرگز شروع نمی‌شود. آن را درست انجام دهید، شبکه‌ای با 50 لایه به همان روانیِ 3 لایه آموزش می‌بیند.

اهداف یادگیری

  • پیاده‌سازی استراتژی‌های مقداردهی اولیه صفر، تصادفی، Xavier/Glorot و Kaiming/He و سنجش اثر آن‌ها روی بزرگی اکتیویشن‌ها در 50 لایه
  • اثبات اینکه چرا در مقداردهی اولیه Xavier از رابطه‌ی Var(w) = 2/(fan_in + fan_out) و در Kaiming از Var(w) = 2/fan_in استفاده می‌شود
  • نشان دادن مسئله‌ی تقارن (symmetry problem) با مقداردهی اولیه صفر و توضیح اینکه چرا مقیاس تصادفی به‌تنهایی کافی نیست
  • تطبیق استراتژی مقداردهی اولیه مناسب با تابع اکتیویشن: Xavier برای sigmoid/tanh و Kaiming برای ReLU/GELU

صورت مسئله

همه‌ی وزن‌ها را صفر بگذارید؛ هیچ‌چیز آموزش نمی‌بیند. تک‌تک نورون‌ها تابع یکسانی را محاسبه می‌کنند، گرادیان برابری می‌گیرند و دقیقاً مثل هم به‌روزرسانی می‌شوند. بعد از 10000 ایپاک (epoch)، لایه‌ی پنهان 512 نورونی شما هنوز 512 کپی از همان یک نورون است. هزینه‌ی 512 پارامتر را داده‌اید، اما عملاً 1 پارامتر نصیبتان شده است.

وزن‌ها را بیش از حد بزرگ انتخاب کنید؛ اکتیویشن‌ها در طول شبکه منفجر می‌شوند. تا لایه‌ی 10، مقادیر به 1e15 می‌رسند. تا لایه‌ی 20، سرریز می‌کنند و بی‌نهایت می‌شوند. گرادیان‌ها هم در مسیر برگشت دقیقاً همین مسیر را می‌روند.

آن‌ها را به‌طور تصادفی از یک توزیع نرمال استاندارد بردارید؛ برای 3 لایه جواب می‌دهد. در 50 لایه، بسته به اینکه مقیاس تصادفی کمی بیش از حد کوچک بوده یا کمی بیش از حد بزرگ، سیگنال یا به صفر سقوط می‌کند یا تا بی‌نهایت منفجر می‌شود. مرز بین «کار می‌کند» و «خراب است» به باریکی مو است.

مقداردهی اولیه‌ی وزن‌ها (weight initialization) دست‌کم‌گرفته‌شده‌ترین تصمیم در یادگیری عمیق است. معماری شبکه مقاله می‌گیرد؛ برای بهینه‌سازها پست وبلاگی می‌نویسند؛ اما به مقداردهی اولیه فقط در پاورقی اشاره می‌شود. با این حال، اگر آن را اشتباه انتخاب کنید هیچ‌چیز دیگری اهمیتی نخواهد داشت؛ شبکه‌تان پیش از شروع آموزش مرده است.

مفاهیم پایه

مسئله‌ی تقارن

همه‌ی نورون‌ها در یک لایه ساختار یکسانی دارند: ورودی‌ها را در وزن‌ها ضرب کن، بایاس (bias) را اضافه کن، تابع اکتیویشن را اعمال کن. اگر همه‌ی وزن‌ها با مقدار یکسانی شروع شوند (صفر حالت افراطی آن است)، همه‌ی نورون‌ها خروجی یکسانی تولید می‌کنند. در پس‌انتشار (backpropagation)، به هر نورون گرادیان کاملاً یکسانی می‌رسد. در گام به‌روزرسانی، وزن‌های هر نورون به یک اندازه تغییر می‌کنند.

اینجا گیر می‌افتید. شبکه صدها پارامتر دارد، اما همگی هماهنگ و یک‌دست جلو می‌روند. به این حالت تقارن می‌گویند و مقداردهی اولیه‌ی تصادفی راهکاری سرراست برای شکستن آن است. هر نورون از نقطه‌ی متفاوتی در فضای وزن‌ها شروع می‌کند؛ در نتیجه هر کدام ویژگی متفاوتی را یاد می‌گیرند.

اما «تصادفی بودن» کافی نیست. مقیاس (scale) این تصادفی بودن مشخص می‌کند که آیا شبکه آموزش می‌بیند یا نه.

انتشار واریانس در لایه‌ها

یک لایه‌ی تکی با fan_in ورودی را در نظر بگیرید:

z=w1x1+w2x2+⋯+wnxnz = w_1 x_1 + w_2 x_2 + \cdots + w_n x_n

اگر هر وزن wiw_i از توزیعی با واریانس Var(w)\mathrm{Var}(w) نمونه‌برداری شود و هر ورودی xix_i دارای واریانس Var(x)\mathrm{Var}(x) باشد، واریانس خروجی برابر است با:

Var(z)=fanin⋅Var(w)⋅Var(x)\mathrm{Var}(z) = \text{fan}_{\text{in}} \cdot \mathrm{Var}(w) \cdot \mathrm{Var}(x)

اگر Var(w)=1\mathrm{Var}(w) = 1 و fanin=512\text{fan}_{\text{in}} = 512 باشد، واریانس خروجی 512 برابر واریانس ورودی می‌شود. پس از 10 لایه: 51210=1.2×1027512^{10} = 1.2 \times 10^{27}. سیگنال شما منفجر شده است.

اگر Var(w)=0.001\mathrm{Var}(w) = 0.001 باشد، واریانس خروجی در هر لایه با ضریب 0.001⋅512=0.5120.001 \cdot 512 = 0.512 کوچک می‌شود. پس از 10 لایه: 0.51210=0.000130.512^{10} = 0.00013. سیگنال شما ناپدید شده است.

هدف: انتخاب Var(w)\mathrm{Var}(w) به‌گونه‌ای که Var(z)=Var(x)\mathrm{Var}(z) = \mathrm{Var}(x) برقرار باشد، تا بزرگی سیگنال در تمام لایه‌ها ثابت بماند.

مقداردهی اولیه‌ی Xavier/Glorot

گلوروت و بنجیو (2010) فرمول را برای توابع اکتیویشن sigmoid و tanh استخراج کردند. برای ثابت نگه داشتن واریانس، هم در گذر رو به جلو (forward pass) و هم در پس‌انتشار:

Var(w)=2fanin+fanout\mathrm{Var}(w) = \frac{2}{\text{fan}_{\text{in}} + \text{fan}_{\text{out}}}

در عمل، وزن‌ها از توزیع زیر نمونه‌برداری می‌شوند:

w∼Uniform(−limit,limit)where limit=6fanin+fanoutw \sim \text{Uniform}(-\text{limit}, \text{limit}) \quad \text{where } \text{limit} = \sqrt{\frac{6}{\text{fan}_{\text{in}} + \text{fan}_{\text{out}}}}

یا:

w∼Normal(0,2fanin+fanout)w \sim \text{Normal}\left(0, \sqrt{\frac{2}{\text{fan}_{\text{in}} + \text{fan}_{\text{out}}}}\right)

این روش جواب می‌دهد؛ چون sigmoid و tanh در نزدیکی صفر (جایی که اکتیویشن‌های دارای مقداردهی اولیه‌ی درست قرار می‌گیرند) رفتاری تقریباً خطی دارند. واریانس در طول ده‌ها لایه پایدار می‌ماند.

مقداردهی اولیه‌ی Kaiming/He

تابع ReLU نیمی از خروجی‌ها را صفر می‌کند (هر مقدار منفی صفر می‌شود). مقدار مؤثر fan_in نصف می‌شود، چون به‌طور میانگین نیمی از ورودی‌ها صفر شده‌اند. مقداردهی اولیه‌ی Xavier این موضوع را در نظر نمی‌گیرد و واریانس مورد نیاز را کمتر از واقعیت تخمین می‌زند.

هه و همکاران (2015) فرمول را اصلاح کردند:

Var(w)=2fanin\mathrm{Var}(w) = \frac{2}{\text{fan}_{\text{in}}}

وزن‌ها از این توزیع نمونه‌برداری می‌شوند:

w∼Normal(0,2fanin)w \sim \text{Normal}\left(0, \sqrt{\frac{2}{\text{fan}_{\text{in}}}}\right)

ضریب 2 صفر شدن نیمی از اکتیویشن‌ها توسط ReLU را جبران می‌کند. بدون این ضریب، سیگنال در هر لایه حدود 0.5 برابر کوچک می‌شود. در 50 لایه: 0.550=8.8×10−160.5^{50} = 8.8 \times 10^{-16}. مقداردهی Kaiming جلوی این افت را می‌گیرد.

مقداردهی اولیه‌ی ترنسفورمر

مدل GPT-2 الگوی متفاوتی را معرفی کرد. اتصالات باقیمانده (residual connections) خروجی هر زیرلایه را به ورودی‌اش اضافه می‌کنند:

x=x+sublayer(x)x = x + \text{sublayer}(x)

هر جمع، واریانس را افزایش می‌دهد. با وجود NN لایه‌ی باقیمانده، واریانس متناسب با NN رشد می‌کند. GPT-2 وزن‌های لایه‌های باقیمانده را با ضریب 1/2N1/\sqrt{2N} مقیاس‌بندی می‌کند که در آن NN تعداد لایه‌ها است. این کار بزرگی سیگنال جمع‌شده را پایدار نگه می‌دارد.

مدل Llama 3 (با 405 میلیارد پارامتر و 126 لایه) از روش مشابهی استفاده می‌کند. بدون این مقیاس‌بندی، جریان باقیمانده در طول 126 لایه از بلوک‌های اتنشن (attention) و پیش‌خور (feedforward) بدون مهار رشد می‌کرد.

مقداردهی اولیه Kaimingمقداردهی اولیه Xavierمقداردهی اولیه صفرلایه 1همه وزن‌ها = 0لایه 2همه نورون‌ها یکسانلایه 3همچنان یکساننتیجه: 1 نورون موثرصرف‌نظر از عرض لایهلایه 1Var = 2/(fan_in+fan_out)لایه 2سیگنال پایدارلایه 50سیگنال پایدارنتیجه: آموزش مناسب باsigmoid/tanhلایه 1Var = 2/fan_inلایه 2سیگنال پایدارلایه 50سیگنال پایدارنتیجه: آموزش مناسب باReLU/GELU

بزرگی اکتیویشن در 50 لایه

نتایجمیانگین بزرگی فعال‌سازیلایه 1لایه 10لایه 25لایه 50تصادفی N(0,1): انفجار تا لایه 5تصادفی N(0,0.01): محوشدن تا لایه 10Xavier + Sigmoid: حدود 1.0 در لایه 50Kaiming + ReLU: حدود 1.0 در لایه 50

انتخاب روش مقداردهی مناسب

Sigmoid / TanhReLU / Leaky ReLUGELU / Swishباقیمانده ترنسفورمرچه تابع فعّال‌سازی؟نوع فعّال‌سازی؟Xavier/GlorotVar = 2/(fan_in + fan_out)Kaiming/HeVar = 2/fan_inKaiming/He(مشابه ReLU)مقیاس با 1/sqrt(2N)N = تعداد لایه‌هابررسی: حفظ بزرگی فعال‌سازیبین 0.5 و 2.0در تمام لایه‌ها
واریانس مقداردهی اولیه وزنیک روش را انتخاب کنید
WEIGHT INIT VARIANCEEach layer multiplies the activation variance by a gain of n·Var(w). Naive large weights make that gain grow with width, so activations explode (log axis). Xavier sets Var(w)=1/n and He sets 2/n for ReLU, both holding the gain near one so signal magnitude stays flat across depth.
هر لایه، واریانس اکتیویشن را در بهره‌ی n·Var(w) ضرب می‌کند. وزن‌های بزرگِ ساده‌لوحانه باعث می‌شوند این بهره با افزایش پهنا رشد کند و اکتیویشن‌ها منفجر شوند (محور لگاریتمی). خاویر Var(w)=1/n و هه مقدار 2/n را برای ReLU تنظیم می‌کند؛ هر دو، بهره را نزدیک به یک نگه می‌دارند تا بزرگی سیگنال در طول عمق شبکه ثابت بماند.

پیاده‌سازی گام‌به‌گام

گام 1: استراتژی‌های مقداردهی اولیه

چهار روش برای مقداردهی اولیه‌ی ماتریس وزن. هر کدام یک لیست از لیست‌ها (ماتریس دوبعدی) با fan_in ستون و fan_out سطر برمی‌گردانند.

import math
import random


def zero_init(fan_in, fan_out):
    return [[0.0 for _ in range(fan_in)] for _ in range(fan_out)]


def random_init(fan_in, fan_out, scale=1.0):
    return [[random.gauss(0, scale) for _ in range(fan_in)] for _ in range(fan_out)]


def xavier_init(fan_in, fan_out):
    std = math.sqrt(2.0 / (fan_in + fan_out))
    return [[random.gauss(0, std) for _ in range(fan_in)] for _ in range(fan_out)]


def kaiming_init(fan_in, fan_out):
    std = math.sqrt(2.0 / fan_in)
    return [[random.gauss(0, std) for _ in range(fan_in)] for _ in range(fan_out)]

گام 2: توابع اکتیویشن

برای آزمایش هر استراتژی با اکتیویشن هدفش، به sigmoid، tanh و ReLU نیاز داریم.

def sigmoid(x):
    x = max(-500, min(500, x))
    return 1.0 / (1.0 + math.exp(-x))


def tanh_act(x):
    return math.tanh(x)


def relu(x):
    return max(0.0, x)

گام 3: گذر رو به جلو در 50 لایه

داده‌های تصادفی را از یک شبکه‌ی عمیق عبور دهید و میانگین بزرگی اکتیویشن را در هر لایه اندازه بگیرید.

def forward_deep(init_fn, activation_fn, n_layers=50, width=64, n_samples=100):
    random.seed(42)
    layer_magnitudes = []

    inputs = [[random.gauss(0, 1) for _ in range(width)] for _ in range(n_samples)]

    for layer_idx in range(n_layers):
        weights = init_fn(width, width)
        biases = [0.0] * width

        new_inputs = []
        for sample in inputs:
            output = []
            for neuron_idx in range(width):
                z = sum(weights[neuron_idx][j] * sample[j] for j in range(width)) + biases[neuron_idx]
                output.append(activation_fn(z))
            new_inputs.append(output)
        inputs = new_inputs

        magnitudes = []
        for sample in inputs:
            magnitudes.append(sum(abs(v) for v in sample) / width)
        mean_mag = sum(magnitudes) / len(magnitudes)
        layer_magnitudes.append(mean_mag)

    return layer_magnitudes

گام 4: اجرای آزمایش

همه‌ی ترکیب‌ها را اجرا کنید: مقداردهی صفر، تصادفی N(0,1)، تصادفی N(0,0.01)، مقداردهی Xavier با sigmoid، مقداردهی Xavier با tanh و Kaiming با ReLU. بزرگی مقادیر را در لایه‌های کلیدی چاپ کنید.

def run_experiment():
    configs = [
        ("Zero init + Sigmoid", lambda fi, fo: zero_init(fi, fo), sigmoid),
        ("Random N(0,1) + ReLU", lambda fi, fo: random_init(fi, fo, 1.0), relu),
        ("Random N(0,0.01) + ReLU", lambda fi, fo: random_init(fi, fo, 0.01), relu),
        ("Xavier + Sigmoid", xavier_init, sigmoid),
        ("Xavier + Tanh", xavier_init, tanh_act),
        ("Kaiming + ReLU", kaiming_init, relu),
    ]

    print(f"{'Strategy':<30} {'L1':>10} {'L5':>10} {'L10':>10} {'L25':>10} {'L50':>10}")
    print("-" * 80)

    for name, init_fn, act_fn in configs:
        mags = forward_deep(init_fn, act_fn)
        row = f"{name:<30}"
        for idx in [0, 4, 9, 24, 49]:
            val = mags[idx]
            if val > 1e6:
                row += f" {'EXPLODED':>10}"
            elif val < 1e-6:
                row += f" {'VANISHED':>10}"
            else:
                row += f" {val:>10.4f}"
        print(row)

گام 5: نمایش مسئله‌ی تقارن

نشان دهید که مقداردهی صفر نورون‌های کاملاً یکسان تولید می‌کند.

def symmetry_demo():
    random.seed(42)
    weights = zero_init(2, 4)
    biases = [0.0] * 4

    inputs = [0.5, -0.3]
    outputs = []
    for neuron_idx in range(4):
        z = sum(weights[neuron_idx][j] * inputs[j] for j in range(2)) + biases[neuron_idx]
        outputs.append(sigmoid(z))

    print("\nSymmetry Demo (4 neurons, zero init):")
    for i, out in enumerate(outputs):
        print(f"  Neuron {i}: output = {out:.6f}")
    all_same = all(abs(outputs[i] - outputs[0]) < 1e-10 for i in range(len(outputs)))
    print(f"  All identical: {all_same}")
    print(f"  Effective parameters: 1 (not {len(weights) * len(weights[0])})")

گام 6: گزارش لایه‌به‌لایه‌ی بزرگی مقادیر

نمودار میله‌ای بصری از بزرگی اکتیویشن‌ها در طول 50 لایه چاپ کنید.

def magnitude_report(name, magnitudes):
    print(f"\n{name}:")
    for i, mag in enumerate(magnitudes):
        if i % 5 == 0 or i == len(magnitudes) - 1:
            if mag > 1e6:
                bar = "X" * 50 + " EXPLODED"
            elif mag < 1e-6:
                bar = "." + " VANISHED"
            else:
                bar_len = min(50, max(1, int(mag * 10)))
                bar = "#" * bar_len
            print(f"  Layer {i+1:3d}: {bar} ({mag:.6f})")

کاربرد در پروژه‌های واقعی

فریم‌ورک PyTorch این قابلیت‌ها را در قالب توابع توکار ارائه می‌دهد:

import torch
import torch.nn as nn

layer = nn.Linear(512, 256)

nn.init.xavier_uniform_(layer.weight)
nn.init.xavier_normal_(layer.weight)

nn.init.kaiming_uniform_(layer.weight, nonlinearity='relu')
nn.init.kaiming_normal_(layer.weight, nonlinearity='relu')

nn.init.zeros_(layer.bias)

وقتی nn.Linear(512, 256) را صدا می‌زنید، PyTorch به‌طور پیش‌فرض از مقداردهی اولیه‌ی یکنواخت (uniform) Kaiming استفاده می‌کند. دلیل اینکه بیشتر شبکه‌های ساده بدون دردسر کار می‌کنند همین است؛ PyTorch از قبل انتخاب درست را انجام داده است. اما وقتی معماری‌های سفارشی می‌سازید یا عمق شبکه را از 20 لایه فراتر می‌برید، باید دقیقاً بدانید چه اتفاقی در جریان است و در صورت نیاز رفتار پیش‌فرض را بازنویسی کنید.

در ترنسفورمرها، مدل‌های HuggingFace معمولاً مقداردهی اولیه را در متد _init_weights مدیریت می‌کنند. پیاده‌سازی GPT-2 لایه‌های تصویر کردن (projections) باقیمانده را با ضریب 1/N1/\sqrt{N} مقیاس‌بندی می‌کند. اگر ترنسفورمری را از صفر می‌نویسید، باید این بخش را خودتان اضافه کنید.

تحویل پروژه

این درس فایل زیر را تولید می‌کند:

  • outputs/prompt-init-strategy.md -- پرامپتی که مشکلات مقداردهی اولیه‌ی وزن را ریشه‌یابی کرده و استراتژی مناسب را پیشنهاد می‌دهد

تمرین‌ها

  1. مقداردهی اولیه‌ی LeCun را اضافه کنید (Var=1/fanin\mathrm{Var} = 1/\text{fan}_{\text{in}}، طراحی‌شده برای تابع اکتیویشن SELU). آزمایش 50 لایه‌ای را با مقداردهی LeCun به همراه tanh اجرا و با Xavier به همراه tanh مقایسه کنید.

  2. مقیاس‌بندی باقیمانده‌ی GPT-2 را پیاده‌سازی کنید: خروجی هر لایه را قبل از اضافه کردن به جریان باقیمانده در 1/2N1/\sqrt{2N} ضرب کنید. شبکه را در 50 لایه با مقیاس‌بندی و بدون آن اجرا کنید و بسنجید بزرگی سیگنال باقیمانده با چه سرعتی رشد می‌کند.

  3. تابعی تحت عنوان «بررسی سلامت مقداردهی اولیه» بسازید که ابعاد لایه‌ها و نوع اکتیویشن شبکه را دریافت کند، سپس مقداردهی اولیه‌ی درست را پیشنهاد دهد و در صورتی که مقداردهی فعلی مشکلی ایجاد می‌کند هشدار دهد.

  4. آزمایش را با fanin=16\text{fan} _{\text{in}} = 16 در برابر fanin=1024\text{fan} _{\text{in}} = 1024 اجرا کنید. روش‌های Xavier و Kaiming با مقدار fan_in سازگار می‌شوند، اما مقداردهی تصادفی ساده این‌طور نیست. نشان دهید که با بزرگ‌تر شدن لایه‌ها، شکاف بین حالت «کار می‌کند» و «خراب می‌شود» چطور عمیق‌تر خواهد شد.

  5. مقداردهی اولیه‌ی متعامد (orthogonal initialization) را پیاده‌سازی کنید (یک ماتریس تصادفی بسازید، تجزیه‌ی مقدارهای منفرد یا SVD آن را حساب کنید و از ماتریس متعامد U استفاده کنید). آن را در 50 لایه با Kaiming برای شبکه‌های ReLU مقایسه کنید.

اصطلاحات کلیدی

اصطلاح در گفتگوهای عامیانه معنای دقیق فنی
Weight initialization (مقداردهی اولیه‌ی وزن) «تنظیم تصادفی وزن‌های شروع» استراتژی انتخاب مقادیر اولیه‌ی وزن‌ها که تعیین می‌کند آیا شبکه اصلاً امکان آموزش دیدن دارد یا نه
Symmetry breaking (شکستن تقارن) «متمایز کردن نورون‌ها از هم» استفاده از مقداردهی اولیه‌ی تصادفی برای اطمینان از اینکه نورون‌ها توابع یکسانی را محاسبه نکنند و ویژگی‌های متفاوتی را یاد بگیرند
Fan-in «تعداد ورودی‌های یک نورون» تعداد اتصالات ورودی که مشخص می‌کند واریانس ورودی چطور در مجموع وزن‌دار انباشته می‌شود
Fan-out «تعداد خروجی‌های یک نورون» تعداد اتصالات خروجی که برای حفظ واریانس گرادیان حین پس‌انتشار اهمیت دارد
Xavier/Glorot init «مقداردهی اولیه‌ی مخصوص سیگموئید» رابطه Var(w)=2/(fanin+fanout)\mathrm{Var}(w) = 2/(\text{fan} _{\text{in}} + \text{fan} _{\text{out}})، طراحی‌شده برای حفظ واریانس در طول توابع اکتیویشن sigmoid و tanh
Kaiming/He init «مقداردهی اولیه‌ی مخصوص رلو» رابطه Var(w)=2/fanin\mathrm{Var}(w) = 2/\text{fan}_{\text{in}}، با در نظر گرفتن صفر شدن نیمی از اکتیویشن‌ها توسط ReLU
Variance propagation (انتشار واریانس) «چگونگی رشد یا افت سیگنال در لایه‌ها» تحلیل ریاضی چگونگی تغییر واریانس اکتیویشن‌ها در هر لایه بر اساس مقیاس وزن‌ها
Residual scaling (مقیاس‌بندی باقیمانده) «ترفند مقداردهی GPT-2» مقیاس‌بندی وزن‌های اتصالات باقیمانده با ضریب 1/2N1/\sqrt{2N} برای جلوگیری از رشد واریانس در طول NN لایه‌ی ترنسفورمر
Dead network (شبکه‌ی مرده) «هیچ‌چیز یاد نمی‌گیرد» شبکه‌ای که در آن مقداردهی ضعیف باعث صفر شدن همه‌ی گرادیان‌ها یا اشباع کامل همه‌ی اکتیویشن‌ها شده است
Exploding activations (انفجار اکتیویشن‌ها) «مقادیر تا بی‌نهایت بالا می‌روند» حالتی که در آن واریانس وزن‌ها بیش از حد بالا است و باعث رشد نمایی بزرگی اکتیویشن‌ها در طول لایه‌ها می‌شود

برای مطالعه‌ی بیشتر

  • مقاله‌ی گلوروت و بنجیو با عنوان "Understanding the difficulty of training deep feedforward neural networks" (2010) -- مقاله‌ی اصلی مقداردهی اولیه‌ی Xavier به همراه تحلیل واریانس
  • مقاله‌ی هه و همکاران با عنوان "Delving Deep into Rectifiers" (2015) -- معرفی مقداردهی اولیه‌ی Kaiming برای شبکه‌های با اکتیویشن ReLU
  • مقاله‌ی ردفورد و همکاران با عنوان "Language Models are Unsupervised Multitask Learners" (2019) -- مقاله‌ی مدل GPT-2 با مقداردهی اولیه‌ی مقیاس‌بندی باقیمانده
  • مقاله‌ی میشکین و ماتاس با عنوان "All You Need is a Good Init" (2016) -- مقداردهی اولیه‌ی واریانس واحد لایه‌به‌لایه، رویکردی تجربی در برابر فرمول‌های تحلیلی

سؤالات متداول

چرا مقداردهی اولیه وزن‌ها با صفر مانع یادگیری شبکه عصبی می‌شود؟

مقداردهی صفر تقارن ایجاد می‌کند؛ همه‌ی نورون‌های یک لایه خروجی کاملاً یکسانی تولید می‌کنند، گرادیان برابری در پس‌انتشار دریافت می‌کنند و به یک اندازه به‌روزرسانی می‌شوند. در نتیجه تفاوتی با داشتن تنها یک نورون نخواهند داشت.

تفاوت اصلی مقداردهی Xavier و Kaiming چیست؟

مقداردهی Xavier برای توابعی مانند Sigmoid و Tanh طراحی شده، در حالی که Kaiming اثر صفر شدن نیمی از خروجی‌ها توسط تابع ReLU را با ضریب 2 در فرمول واریانس جبران می‌کند.

چرا در ترنسفورمرهایی مانند GPT-2 از مقیاس‌بندی باقیمانده (Residual Scaling) استفاده می‌شود؟

در اتصالات باقیمانده، خروجی لایه‌ها با ورودی جمع می‌شود که واریانس را متناسب با تعداد لایه‌ها بالا می‌برد. با ضرب در ضریب 1 تقسیم بر رادیکال تعداد لایه‌ها، رشد واریانس در طول لایه‌های متوالی مهار می‌شود.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.