چیت‌شیت

نظریه اطلاعات و پایداری عددی

Information Theory and Numerical Stability

آنتروپی، آنتروپی متقاطع و واگرایی کولبک-لایبلر، سافت‌مکس پایدار و log-sum-exp، فرمت‌های ممیز شناور، PCA و انتخاب معیار فاصله.

  • ۱۲ بخش
  • ۴ درس مرتبط
  • کد و دستورها عیناً از دوره‌ی اصلی
فهرست مطالب
  1. فرمول‌های اطلاعات
  2. مسیر پایدار تابع زیان
  3. سافت‌مکس پایدار، LSE و آنتروپی متقاطع
  4. وظایف در کد
  5. فرمت‌های ممیز شناور و محدودیت‌ها
  6. دقت ترکیبی با مقیاس‌بندی تابع زیان
  7. باگ‌های عددی
  8. پیچ‌های تنظیم و آستانه‌ها
  9. انتخاب معیار فاصله
  10. کاهش ابعاد
  11. پرسش‌ها
  12. نکات کاربردی

فرمول‌های اطلاعات

مفهوم‌ها
غافلگیری (Surprise)
$I(x) = -\log p(x)$. پایه 2 برحسب بیت؛ پایه e برحسب نات.
آنتروپی
$H(P) = -\sum_x p(x) \log p(x)$. سکه سالم 1 بیت؛ سکه با احتمال 99٪ معادل 0.08 بیت.
آنتروپی متقاطع
$H(P,Q) = -\sum_x p(x) \log q(x)$. برچسب تک‌داغ (one-hot) خروجی $-\log q(\text{true class})$ می‌دهد.
واگرایی کولبک-لایبلر
$D_{KL}(P \Vert Q) = H(P,Q) - H(P)$. متقارن نیست.
اطلاعات متقابل
$I(X;Y) = H(X) + H(Y) - H(X,Y)$. مقدار صفر یعنی مستقل هستند.
آنتروپی شرطی
$H(Y \mid X) = H(X,Y) - H(X)$. انشعاب‌های درخت تصمیم آن را کمینه می‌کنند.
پرپلکسیتی
$e^{H(P,Q)}$ برحسب نات. پرپلکسیتی 50 یعنی انتخاب یکنواخت از میان 50 توکن.
هموارسازی برچسب‌ها
$(1-\epsilon)\,\text{hard} + \epsilon / K$. با 0.1 و 4 کلاس، کلاس درست 0.925 می‌گیرد.
واحدها
1 نات معادل 1.4427 بیت است. PyTorch و TensorFlow از نات استفاده می‌کنند.

مسیر پایدار تابع زیان

معماری
شیفت‌یافتهلگاریتم احتمالاتلاجیت‌هاامتیازهای خام zتفریق بیشینهc = max(x)Log-sum-expبزرگ‌ترین جمله exp(0) = 1 می‌شودlog_softmax_stablez منهای lseآنتروپی متقاطعمنهای لگاریتم احتمال کلاس درستواگرایی کولبک-لایبلرآنتروپی متقاطع منهای آنتروپیپرپلکسیتیexp میانگین آنتروپی متقاطع

سافت‌مکس پایدار، LSE و آنتروپی متقاطع

کد
python
def logsumexp_stable(values):
    c = max(values)                   # بزرگ‌ترین نما 0 می‌شود
    return c + math.log(sum(math.exp(v - c) for v in values))

def log_softmax_stable(logits):
    c = max(logits)
    lse = c + math.log(sum(math.exp(z - c) for z in logits))
    return [z - lse for z in logits]  # لگاریتم احتمالات، بدون سرریز

def cross_entropy_stable(true_class, logits):
    log_probs = log_softmax_stable(logits)
    return -log_probs[true_class]     # هرگز log(0) را فراخوانی نمی‌کند

وظایف در کد

کار و کد
وظیفهکد
آنتروپی برحسب بیتentropy(probs, base=2)
واگرایی کولبک-لایبلرkl_divergence(p, q, base=2)
پرپلکسیتی بر اساس میانگین آنتروپی متقاطعperplexity(avg_cross_entropy, base="e")
سافت‌مکس امنsoftmax_stable(logits)
گرادیان عددیnumerical_gradient(f, x, h=1e-5)
مقایسه با پس‌انتشارcheck_gradient(analytical, numerical)
برش نُرم گرادیانclip_by_norm(gradients, max_norm)
واریانس با میانگین بزرگwelford_variance(values)

فرمت‌های ممیز شناور و محدودیت‌ها

پیش‌فرض‌ها
تنظیمپیش‌فرضنکته
float64 max1.8e30811 بیت نما، حدود 15 تا 16 رقم اعشار
float32 max3.4028235e+388 بیت نما، حدود 7 تا 8 رقم اعشار
float32 min normal1.175e-38اعداد غیراستاندارد (Denormals) تا 1.401e-45 می‌رسند
float32 exp overflowexp(89.0)خروجی inf می‌دهد؛ exp(88.7) همچنان جا می‌شود
float32 exp underflowexp(-104)خروجی 0.0 می‌دهد
float16 max65,504گرادیان‌های زیر حدود 6e-8 صفر می‌شوند
bfloat16 max3.4e388 بیت نما، 7 بیت مانتیس
float32 machine epsilon1.19e-7کوچک‌ترین e که در آن 1.0 + e != 1.0 است

دقت ترکیبی با مقیاس‌بندی تابع زیان

گام‌به‌گام
  1. وزن‌های اصلی (Master weights)یک نسخه float32 از وزن‌ها نگه دارید.
  2. گذر رو به جلوبرای سرعت، آن را با float16 اجرا کنید.
  3. تابع زیان (loss)برای جلوگیری از سرریز، آن را در float32 محاسبه کنید.
  4. مقیاس‌بندیتابع زیان را در یک ضریب ضرب کنید؛ مثلاً 1024.
  5. گام رو به عقببا float16 اجرا کنید. گرادیان‌ها 1024 برابر بزرگ‌ترند.
  6. برش مقیاس (Unscale)پیش از به‌روزرسانی، گرادیان‌ها را بر 1024 تقسیم کنید.
  7. به‌روزرسانیوزن‌های اصلی float32 را تغییر دهید.
  8. مقیاس‌بندی پویااز 65536 شروع کنید. در صورت inf نصف کنید؛ پس از N گام سالم، دو برابر کنید.

باگ‌های عددی

عیب‌یابی
  • تابع زیان بعد از چند دوره NaN می‌شود

    علت
    لاجیت‌ها خیلی بزرگ بودند، سافت‌مکس سرریز کرد
    راه‌حل
    سافت‌مکس پایدار، کاهش نرخ یادگیری (LR)، برش گرادیان
  • تابع زیان روی log(num_classes) گیر کرده است

    علت
    خروجی‌های تقریباً یکنواخت، بدون یادگیری
    راه‌حل
    بررسی برچسب‌ها، تابع زیان و نورون مرده‌ی ReLU
  • دقت اعتبارسنجی 1 تا 3 درصد پایین‌تر است

    علت
    دقت ترکیبی بدون مقیاس‌بندی تابع زیان
    راه‌حل
    مقیاس‌بندی پویای تابع زیان یا استفاده از bfloat16
  • نُرم گرادیان در برخی لایه‌ها 0.0 است

    علت
    نورون مرده‌ی ReLU یا زیرریز float16
    راه‌حل
    استفاده از LeakyReLU یا GELU، مقیاس‌بندی گرادیان
  • نتایج بین GPUها متفاوت است

    علت
    جمع ممیز شناور خاصیت شرکت‌پذیری ندارد
    راه‌حل
    torch.use_deterministic_algorithms(True)
  • exp() در تابع زیان inf برمی‌گرداند

    علت
    لاجیت‌های خام بدون تفریق مقدار بیشینه
    راه‌حل
    torch.nn.functional.log_softmax()
  • واگرایی پس از سوییچ به float16

    علت
    گرادیان‌های زیر 6e-8، مقادیر بالای 65,504
    راه‌حل
    AMP همراه با مقیاس‌بندی تابع زیان، یا bfloat16
  • واریانس اشتباه برای مقادیر بزرگ

    علت
    حذف فاجعه‌بار
    راه‌حل
    welford_variance یا مرکززدایی از داده‌ها

پیچ‌های تنظیم و آستانه‌ها

پیش‌فرض‌ها
تنظیمپیش‌فرضنکته
Gradient check `h`1e-5محدوده معمول 1e-5 تا 1e-7
Gradient check pass1e-7بالای 1e-3 مشکلی وجود دارد
max_norm1.0ترنسفورمرها؛ 0.5 برای RL، 5.0 برای شبکه‌های ساده
LayerNorm `epsilon`1e-5جلوگیری از تقسیم بر صفر
Epsilon in log and divide1e-8log(x + 1e-8)
t-SNE perplexity5-50درس از مقدار 30 استفاده می‌کند
UMAP `n_neighbors`15همراه با min_dist برابر با 0.1
PCA cumulative variance0.95یا یک آستانه 90 تا 95 درصدی

انتخاب معیار فاصله

دستورها
دستورکاربرد
cosine_similarity(a, b)متن و امبدینگ‌ها؛ اندازه بردار را نادیده می‌گیرد
dot_product(a, b)سیستم‌های توصیه‌گر؛ اندازه نشان‌دهنده محبوبیت است
l2_distance(a, b)پیکسل‌ها و داده‌های مکانی در مقیاس‌های قابل‌مقایسه
l1_distance(a, b)ویژگی‌های اسپارس با ابعاد بالا؛ مقاوم در برابر داده‌های پرت
linf_distance(a, b)بدترین انحراف در یک بعد
mahalanobis_distance(x, y, cov_matrix)داده‌های پرت با ویژگی‌های همبسته
jaccard_similarity(set_a, set_b)مجموعه‌ها و تگ‌ها؛ معیار IoU برای بخش‌بندی (segmentation)
edit_distance(s1, s2)رشته‌ها؛ درج، حذف یا جایگزینی

کاهش ابعاد

مفهوم‌ها
نفرین ابعاد
در 1000 بعد، نسبت بیشینه به کمینه فاصله حدود 1.02 است.
PCA
مرکززدایی، کوواریانس، np.linalg.eigh، مرتب‌سازی بر اساس مقدار ویژه، نگه داشتن k تای برتر.
نسبت واریانس تبیین‌شده
یک مقدار ویژه تقسیم بر مجموع همه مقادیر ویژه.
انتخاب k
حفظ 90 تا 95٪ واریانس، یافتن نقطه زانویی، یا آزمون k روی وظیفه.
خطای بازسازی
مجموع مقادیر ویژه حذف‌شده؛ خطای بالا نشانگر داده پرت است.
t-SNE
همسایگی‌های محلی را حفظ می‌کند؛ تصادفی و با پیچیدگی $O(n^2)$؛ فواصل خوشه‌ها معنایی ندارند.
UMAP
سریع‌تر از t-SNE؛ ساختار سراسری بیشتری را حفظ می‌کند.
Kernel PCA
انجام PCA در فضای ویژگی کرنل؛ کرنل RBF دایره‌های هم‌مرکز را تفکیک می‌کند.

پرسش‌ها

پرسش و پاسخ
چرا مقدار بیشینه تفریق می‌شود؟
بزرگ‌ترین جمله exp(0) = 1 می‌شود؛ حاصل‌جمع حداقل 1 خواهد بود.
چرا bfloat16 برای آموزش؟
دامنه عددی float32 را دارد؛ مقیاس‌بندی تابع زیان معمولاً لازم نیست.
چرا کمینه‌سازی آنتروپی متقاطع؟
با منفی درست‌نمایی لگاریتمی برابر است؛ H(P) مقداری ثابت است.
چرا واگرایی KL یک فاصله نیست؟
متقارن نیست و در نامساوی مثلثی صدق نمی‌کند.
چرا فاصله واسراشتاین در GANها؟
حتی در صورت عدم همپوشانی توزیع‌ها، گرادیان تولید می‌کند.
چرا جریمه L1 باعث وزن‌های اسپارس می‌شود؟
خطوط تراز تابع زیان در گوشه‌ها با لوزی L1 برخورد می‌کنند.
چرا تفاضل مرکزی؟
خطای آن $O(h^2)$ است؛ تفاضل پیشرو خطای $O(h)$ دارد.

نکات کاربردی

نکته‌ها
  • اعداد ممیز شناور را با == مقایسه نکنید؛ از math.isclose() استفاده کنید.
  • هنگام اشکال‌زدایی پس از هر گذر رو به جلو nan و inf را بررسی کنید: math.isfinite(x).
  • ورودی‌های تابع exp را محدود کنید: exp(clamp(x, -80, 80)).
  • برش بر اساس نُرم را با torch.nn.utils.clip_grad_norm_() انجام دهید؛ جهت گرادیان را حفظ می‌کند.
  • هر لایه یا تابع زیان جدید را با torch.autograd.gradcheck() بررسی کنید.
  • با امبدینگ‌های نرمال‌شده بر اساس L2، شباهت کسینوسی و ضرب داخلی نتیجه یکسانی می‌دهند.