فاز 1 · درس 9

نظریه اطلاعات در یادگیری ماشین: از آنتروپی تا پرپلکسیتی

نوع
مفهومی
زمان
حدود 60 دقیقه
زبان‌ها
Python
دو زنگوله توزیع احتمالاتی با فاصله‌ای مشخص در کنار یک ترازوی دقیق برای سنجش واگرایی
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفهوم
  4. محتوای اطلاعات (غافلگیری)
  5. آنتروپی (میانگین غافلگیری)
  6. آنتروپی متقاطع (تابع زیانی که هر روز استفاده می‌کنید)
  7. واگرایی KL (فاصله‌ی میان دو توزیع)
  8. اطلاعات متقابل
  9. آنتروپی شرطی
  10. آنتروپی مشترک
  11. نگاهی عمیق‌تر به اطلاعات متقابل
  12. هموارسازی برچسب‌ها و آنتروپی متقاطع
  13. چرا آنتروپی متقاطع، همان تابع زیان اصلی برای طبقه‌بندی است؟
  14. مقایسه‌ی بیت و نات
  15. پرپلکسیتی
  16. پیاده‌سازی از صفر
  17. گام 1: محتوای اطلاعات و آنتروپی
  18. گام 2: آنتروپی متقاطع و واگرایی KL
  19. گام 3: آنتروپی متقاطع به‌عنوان زیان طبقه‌بندی
  20. گام 4: برابری آنتروپی متقاطع با منفی لگاریتم درست‌نمایی
  21. گام 5: اطلاعات متقابل
  22. استفاده از ابزارهای واقعی
  23. تمرین‌ها
  24. راهنمایی‌ها
  25. اصطلاحات کلیدی
  26. برای مطالعه‌ی بیشتر

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

نظریه اطلاعات (Information Theory) همان زبان مشترکی است که پیوند میان عدم قطعیت، فشرده‌سازی داده‌ها و توابع زیان طبقه‌بندی را توضیح می‌دهد. با پیاده‌سازی مفاهیمی مثل آنتروپی، واگرایی کولبک-لایبلر (KL Divergence) و اطلاعات متقابل (Mutual Information) با زبان پایتون، ریشه‌ی ریاضی مدل‌سازی زبانی و شبکه‌های عصبی را به‌طور ملموس درک خواهید کرد.

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

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

  • محاسبه‌ی آنتروپی (Entropy)، آنتروپی متقاطع (Cross-Entropy) و واگرایی کولبک-لایبلر (KL Divergence) از صفر و توضیح رابطه‌ی میان آن‌ها
  • استخراج ریاضی این‌که چرا کمینه‌سازی زیان آنتروپی متقاطع معادل بیشینه‌سازی لگاریتم درست‌نمایی است
  • محاسبه‌ی اطلاعات متقابل (Mutual Information) میان ویژگی‌ها و متغیر هدف برای رتبه‌بندی اهمیت ویژگی‌ها
  • توضیح پرپلکسیتی (Perplexity) به‌عنوان اندازه‌ی واژگان مؤثری که مدل زبانی از میان آن‌ها دست به انتخاب می‌زند

صورت مسئله

در هر مدل طبقه‌بندی که آموزش می‌دهید، تابع CrossEntropyLoss() را صدا می‌زنید. در تمام مقالات مدل‌های زبانی با واژه‌ی «پرپلکسیتی» روبه‌رو می‌شوید. در بحث‌های مربوط به VAEها، تقطیر دانش (Distillation) و RLHF نام واگرایی KL را می‌خوانید. این مفاهیم تکه‌های جداافتاده از پازل نیستند؛ همگی یک مفهوم واحدند در جامه‌های گوناگون.

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

در این درس، تمام فرمول‌ها را از صفر پیاده‌سازی می‌کنیم تا ریشه‌ی شکل‌گیری و دلیل کارکرد آن‌ها را به چشم ببینید.

مفهوم

محتوای اطلاعات (غافلگیری)

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

محتوای اطلاعات (Information Content) برای پیشامدی با احتمال pp به‌صورت زیر تعریف می‌شود:

I(x)=−log⁡(p(x))I(x) = -\log(p(x))

استفاده از لگاریتم بر مبنای 2 به شما بیت می‌دهد؛ استفاده از لگاریتم طبیعی، نات (Nat). مفهوم یکی است، فقط واحد اندازه‌گیری فرق می‌کند.

Event              Probability    Surprise (bits)
Fair coin heads    0.5            1.0
Rolling a 6        0.167          2.58
1-in-1000 event    0.001          9.97
Certain event      1.0            0.0

پیشامدهای قطعی هیچ اطلاعاتی به همراه ندارند؛ چون از قبل می‌دانستید رخ خواهند داد.

آنتروپی (میانگین غافلگیری)

آنتروپی برابر است با امید ریاضی غافلگیری در میان تمام پیامدهای محتمل یک توزیع.

H(P)=−∑xp(x)log⁡(p(x))H(P) = -\sum_{x} p(x) \log(p(x))

یک سکه‌ی سالم بیشترین آنتروپی ممکن را برای یک متغیر دودویی دارد: 1 بیت. در مقابل، یک سکه‌ی توردار (مثلاً 99% احتمال شیر) آنتروپی پایینی دارد: 0.08 بیت. در این حالت از قبل می‌دانید چه اتفاقی خواهد افتاد؛ بنابراین هر پرتاب سکه تقریباً هیچ داده‌ی جدیدی به شما نمی‌گوید.

Fair coin:H=−(0.5log⁡2(0.5)+0.5log⁡2(0.5))=1.0 bitBiased coin:H=−(0.99log⁡2(0.99)+0.01log⁡2(0.01))=0.08 bits\begin{aligned} \text{Fair coin:} \quad & H = -(0.5 \log_2(0.5) + 0.5 \log_2(0.5)) = 1.0 \text{ bit} \\ \text{Biased coin:} \quad & H = -(0.99 \log_2(0.99) + 0.01 \log_2(0.01)) = 0.08 \text{ bits} \end{aligned}

آنتروپی، عدم قطعیتِ کاهش‌ناپذیر در یک توزیع را می‌سنجد. داده‌ها را نمی‌توان فراتر از این حد فشرده کرد.

آنتروپی متقاطع (تابع زیانی که هر روز استفاده می‌کنید)

آنتروپی متقاطع، میانگین غافلگیری را زمانی می‌سنجد که از توزیع QQ برای کدگذاری پیامدهایی استفاده کنید که در اصل از توزیع PP سرچشمه گرفته‌اند.

H(P,Q)=−∑xp(x)log⁡(q(x))H(P, Q) = -\sum_{x} p(x) \log(q(x))

در این‌جا PP توزیع واقعی (برچسب‌ها) و QQ پیش‌بینی مدل شماست. اگر QQ کاملاً بر PP منطبق باشد، آنتروپی متقاطع با آنتروپی برابر خواهد شد. هر گونه اختلاف میان این دو، مقدار آنتروپی متقاطع را بالا می‌برد.

در مسائل طبقه‌بندی، PP یک بردار وان-هات (One-hot) است (کلاس واقعی احتمال 1 و بقیه‌ی کلاس‌ها احتمال 0 دارند). این موضوع فرمول آنتروپی متقاطع را ساده می‌کند:

H(P,Q)=−log⁡(q(true_class))H(P, Q) = -\log(q(\text{true\_class}))

کل فرمول تابع زیان آنتروپی متقاطع برای طبقه‌بندی همین است: احتمال پیش‌بینی‌شده برای کلاس درست را به حداکثر برسانید.

واگرایی KL (فاصله‌ی میان دو توزیع)

واگرایی KL میزان غافلگیری اضافه‌ای را نشان می‌دهد که بر اثر استفاده از توزیع QQ به‌جای PP متحمل می‌شوید.

DKL(P ∥ Q)=∑xp(x)log⁡(p(x)/q(x))=H(P,Q)−H(P)\begin{aligned} D_{KL}(P \,\|\, Q) &= \sum_{x} p(x) \log(p(x) / q(x)) \\ &= H(P, Q) - H(P) \end{aligned}

آنتروپی متقاطع برابر است با مجموع آنتروپی و واگرایی KL. از آن‌جا که آنتروپیِ توزیع واقعی در طول آموزش ثابت است، کمینه‌سازی آنتروپی متقاطع همان کمینه‌سازی واگرایی KL است. در واقع شما توزیع پیش‌بینی‌های مدل را به سمت توزیع واقعی push می‌کنید.

واگرایی KL متقارن نیست: DKL(P∥Q)≠DKL(Q∥P)D_{KL}(P \Vert Q) \ne D_{KL}(Q \Vert P). بنابراین از نظر ریاضی یک متریکِ فاصله‌ی واقعی به شمار نمی‌آید.

اطلاعات متقابل

اطلاعات متقابل نشان می‌دهد دانستن مقدار یک متغیر، چه میزان اطلاعات درباره‌ی متغیر دیگر به ما می‌دهد.

I(X;Y)=H(X)−H(X∣Y)=H(X)+H(Y)−H(X,Y)\begin{aligned} I(X; Y) &= H(X) - H(X \mid Y) \\ &= H(X) + H(Y) - H(X, Y) \end{aligned}

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

در انتخاب ویژگی (Feature Selection)، بالا بودن اطلاعات متقابل میان یک ویژگی و متغیر هدف نشان می‌دهد ویژگی مفید است؛ مقدار پایین آن یعنی نویز است.

آنتروپی شرطی

H(Y∣X)H(Y \mid X) نشان می‌دهد پس از مشاهده‌ی متغیر XX، هنوز چه مقدار عدم قطعیت درباره‌ی YY باقی مانده است.

H(Y∣X)=H(X,Y)−H(X)H(Y \mid X) = H(X,Y) - H(X)

دو حالت حدی وجود دارد:

  • اگر XX به‌طور کامل مقدار YY را تعیین کند، آن‌گاه H(Y∣X)=0H(Y \mid X) = 0. دانستن XX همه‌ی عدم قطعیت‌ها درباره‌ی YY را از بین می‌برد. مثال: XX = دمای هوا بر حسب سلسیوس، YY = دمای هوا بر حسب فارنهایت.
  • اگر XX هیچ اطلاعاتی درباره‌ی YY ندهد، آن‌گاه H(Y∣X)=H(Y)H(Y \mid X) = H(Y). دانستن XX ذره‌ای از عدم قطعیت شما کم نمی‌کند. مثال: XX = پرتاب سکه، YY = وضعیت آب‌وهوای فردا.

آنتروپی شرطی همواره مقداری نامنفی دارد و هرگز از H(Y)H(Y) بیشتر نمی‌شود:

0≤H(Y∣X)≤H(Y)0 \le H(Y \mid X) \le H(Y)

در یادگیری ماشین، آنتروپی شرطی در درخت‌های تصمیم (Decision Trees) ظاهر می‌شود. در هر انشعاب، الگوریتم ویژگی XX را انتخاب می‌کند که H(Y∣X)H(Y \mid X) را کمینه کند؛ یعنی همان ویژگی که بیشترین عدم قطعیت را از روی برچسب YY حذف می‌کند.

آنتروپی مشترک

H(X,Y)H(X,Y) آنتروپی توزیع مشترک متغیرهای XX و YY در کنار یکدیگر است.

H(X,Y)=−∑x∑yp(x,y)log⁡(p(x,y))H(X,Y) = -\sum_{x} \sum_{y} p(x,y) \log(p(x,y))

یک ویژگی کلیدی:

H(X,Y)≤H(X)+H(Y)H(X,Y) \le H(X) + H(Y)

تساوی زمانی برقرار است که XX و YY مستقل باشند. اگر آن‌ها اطلاعات مشترکی داشته باشند، آنتروپی مشترک کمتر از مجموع آنتروپی‌های فردی خواهد بود. این آنتروپیِ «گم‌شده» دقیقاً همان اطلاعات متقابل است.

نمودار ون اطلاعاتH(X)H(Y)I(X;Y)اطلاعاتمتقابلH(X|Y)= H(X) - I(X;Y)H(Y|X)= H(Y) - I(X;Y)H(X,Y) = H(X) + H(Y) - I(X;Y)

روابط حاکم بر این مفاهیم:

  • H(X,Y)=H(X)+H(Y∣X)=H(Y)+H(X∣Y)H(X,Y) = H(X) + H(Y \mid X) = H(Y) + H(X \mid Y)
  • I(X;Y)=H(X)−H(X∣Y)=H(Y)−H(Y∣X)I(X;Y) = H(X) - H(X \mid Y) = H(Y) - H(Y \mid X)
  • H(X,Y)=H(X)+H(Y)−I(X;Y)H(X,Y) = H(X) + H(Y) - I(X;Y)

نگاهی عمیق‌تر به اطلاعات متقابل

اطلاعات متقابل I(X;Y)I(X;Y) مشخص می‌کند که دانستن یک متغیر چقدر از عدم قطعیت ما نسبت به متغیر دیگر می‌کاهد.

I(X;Y)=H(X)−H(X∣Y)=H(Y)−H(Y∣X)=H(X)+H(Y)−H(X,Y)=∑x∑yp(x,y)log⁡(p(x,y)p(x) p(y))\begin{aligned} I(X;Y) &= H(X) - H(X \mid Y) \\ &= H(Y) - H(Y \mid X) \\ &= H(X) + H(Y) - H(X,Y) \\ &= \sum_{x} \sum_{y} p(x,y) \log\left(\frac{p(x,y)}{p(x) \, p(y)}\right) \end{aligned}

ویژگی‌ها:

  • همیشه I(X;Y)≥0I(X;Y) \ge 0. هرگز با مشاهده‌ی یک متغیر، اطلاعات از دست نمی‌دهید.
  • I(X;Y)=0I(X;Y) = 0 است اگر و تنها اگر XX و YY مستقل باشند.
  • I(X;Y)=I(Y;X)I(X;Y) = I(Y;X). برخلاف واگرایی KL، کاملاً متقارن است.
  • I(X;X)=H(X)I(X;X) = H(X). یک متغیر تمام اطلاعاتش را با خودش به اشتراک می‌گذارد.

اطلاعات متقابل در انتخاب ویژگی. در یادگیری ماشین، هدف شما یافتن ویژگی‌هایی است که درباره‌ی متغیر هدف اطلاعات مفیدی در اختیارتان بگذارند. اطلاعات متقابل راهکاری اصولی برای اولویت‌بندی ویژگی‌ها در اختیارتان می‌گذارد:

  1. برای هر ویژگی XiX_i، مقدار I(Xi;Y)I(X_i; Y) را محاسبه کنید (در این‌جا YY متغیر هدف است).
  2. ویژگی‌ها را بر اساس نمره‌ی اطلاعات متقابل رتبه‌بندی کنید.
  3. تعداد kk ویژگی برتر را نگه دارید.

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

روش نوع ارتباط قابل کشف هزینه‌ی محاسباتی سازگار با متغیرهای طبقه‌بندی‌شده (Categorical)؟
همبستگی پیرسون روابط خطی O(n)O(n) خیر
همبستگی اسپیرمن روابط یکنواخت O(nlog⁡n)O(n \log n) خیر
اطلاعات متقابل هر نوع وابستگی آماری O(nlog⁡n)O(n \log n) با تقسیم‌بندی بازه‌ها بله

هموارسازی برچسب‌ها و آنتروپی متقاطع

در طبقه‌بندی استاندارد از برچسب‌های سخت (Hard Targets) استفاده می‌شود: [0, 0, 1, 0]. کلاس واقعی احتمال 1 و باقی کلاس‌ها احتمال 0 دریافت می‌کنند. در روش هموارسازی برچسب‌ها (Label Smoothing)، این برچسب‌ها با برچسب‌های نرم (Soft Targets) جایگزین می‌شوند:

soft_target=(1−ϵ)⋅hard_target+ϵ/num_classes\text{soft\_target} = (1 - \epsilon) \cdot \text{hard\_target} + \epsilon / \text{num\_classes}

به‌عنوان نمونه با ϵ=0.1\epsilon = 0.1 و 4 کلاس:

  • برچسب سخت: [0, 0, 1, 0]
  • برچسب نرم: [0.025, 0.025, 0.925, 0.025]

از دیدگاه نظریه‌ی اطلاعات، هموارسازی برچسب‌ها آنتروپی توزیع هدف را بالا می‌برد. برچسب‌های سختِ وان-هات آنتروپی صفر دارند؛ یعنی هیچ عدم قطعیتی در آن‌ها نیست. در مقابل، برچسب‌های نرم دارای آنتروپی مثبت هستند.

چرا این کار کمک می‌کند:

  • از هدایت لاجیت‌ها (Logits) به سمت مقادیر حدی جلوگیری می‌کند (تحت آنتروپی متقاطع، برای انطباق کامل روی برچسب وان-هات به لاجیت‌های بی‌نهایت نیاز است)
  • نوعی تنظیم‌سازی (Regularization) به شمار می‌رود: مدل دیگر نمی‌تواند اطمینان 100 درصدی داشته باشد
  • کالیبراسیون را تقویت می‌کند: احتمالات پیش‌بینی‌شده، عدم قطعیت واقعی را بهتر بازتاب می‌دهند
  • شکاف رفتاری میان فاز آموزش و استنتاج را کاهش می‌دهد

تابع زیان آنتروپی متقاطع با هموارسازی برچسب‌ها به‌صورت زیر درمی‌آید:

L=(1−ϵ)⋅CE(hard_target,prediction)+ϵ⋅Huniform(prediction)L = (1 - \epsilon) \cdot \text{CE}(\text{hard\_target}, \text{prediction}) + \epsilon \cdot H_{\text{uniform}}(\text{prediction})

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

چرا آنتروپی متقاطع، همان تابع زیان اصلی برای طبقه‌بندی است؟

سه دیدگاه، به یک نتیجه می‌رسند.

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

دیدگاه بیشینه‌سازی درست‌نمایی (Maximum Likelihood). برای NN نمونه‌ی آموزشی با کلاس‌های واقعی yiy_i:

Likelihood=∏iq(yi)Log-likelihood=∑ilog⁡(q(yi))Negative log-likelihood=−∑ilog⁡(q(yi))\begin{aligned} \text{Likelihood} &= \prod_i q(y_i) \\ \text{Log-likelihood} &= \sum_i \log(q(y_i)) \\ \text{Negative log-likelihood} &= -\sum_i \log(q(y_i)) \end{aligned}

خط آخر همان تابع زیان آنتروپی متقاطع است. کمینه‌سازی آنتروپی متقاطع = بیشینه‌سازی درست‌نمایی داده‌های آموزشی در مدل شما.

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

مقایسه‌ی بیت و نات

تنها تفاوت آن‌ها در مبنای لگاریتم است.

log base 2   -> bits      (information theory tradition)
log base e   -> nats      (machine learning convention)
log base 10  -> hartleys  (rarely used)

1 نات برابر است با 1/ln⁡(2)1/\ln(2) بیت = 1.4427 بیت. PyTorch و TensorFlow به‌صورت پیش‌فرض از لگاریتم طبیعی (نات) استفاده می‌کنند.

پرپلکسیتی

پرپلکسیتی برابر است با فرم نماییِ آنتروپی متقاطع. این معیار به شما می‌گوید مدل به‌طور مؤثر میان چند گزینه‌ی با شانس یکسان دچار تردید است.

Perplexity=2H(P,Q)(if using bits)Perplexity=eH(P,Q)(if using nats)\begin{aligned} \text{Perplexity} &= 2^{H(P,Q)} \quad \text{(if using bits)} \\ \text{Perplexity} &= e^{H(P,Q)} \quad \text{(if using nats)} \end{aligned}

یک مدل زبانی با پرپلکسیتی 50، به‌طور میانگین همان‌قدر سردرگم است که انگار بخواهد توکن بعدی را به‌صورت تصادفی و یکنواخت از میان 50 توکن ممکن انتخاب کند. هر چه این عدد کمتر باشد، بهتر است.

مدل GPT-2 در بنچمارک‌های استاندارد به پرپلکسیتی حدود 30 رسید. مدل‌های امروزی برای حوزه‌هایی با داده‌های غنی، اعدادی تک‌رقمی ثبت کرده‌اند.

آنتروپی و KLشکل توزیع‌های p (آبی) و q (خاکستری)
آنتروپی H(p) میانگین غافلگیری توزیع آبی را می‌سنجد و وقتی هر چهار بازه برابر باشند به بیشینه می‌رسد. KL(p‖q) بیت‌های اضافی مصرف‌شده برای کدگذاری نمونه‌های p با کدی بر پایه‌ی q را اندازه می‌گیرد؛ این مقدار هرگز منفی نیست، فقط در صورت یکسان بودن دو توزیع صفر می‌شود و متقارن نیست. آموزش با انتروپی متقاطع دقیقاً همین شکاف را کمینه می‌کند.

پیاده‌سازی از صفر

گام 1: محتوای اطلاعات و آنتروپی

import math

def information_content(p, base=2):
    if p <= 0 or p > 1:
        return float('inf') if p <= 0 else 0.0
    return -math.log(p) / math.log(base)

def entropy(probs, base=2):
    return sum(
        p * information_content(p, base)
        for p in probs if p > 0
    )

fair_coin = [0.5, 0.5]
biased_coin = [0.99, 0.01]
fair_die = [1/6] * 6

print(f"Fair coin entropy:   {entropy(fair_coin):.4f} bits")
print(f"Biased coin entropy: {entropy(biased_coin):.4f} bits")
print(f"Fair die entropy:    {entropy(fair_die):.4f} bits")

گام 2: آنتروپی متقاطع و واگرایی KL

def cross_entropy(p, q, base=2):
    total = 0.0
    for pi, qi in zip(p, q):
        if pi > 0:
            if qi <= 0:
                return float('inf')
            total += pi * (-math.log(qi) / math.log(base))
    return total

def kl_divergence(p, q, base=2):
    return cross_entropy(p, q, base) - entropy(p, base)

true_dist = [0.7, 0.2, 0.1]
good_model = [0.6, 0.25, 0.15]
bad_model = [0.1, 0.1, 0.8]

print(f"Entropy of true dist:     {entropy(true_dist):.4f} bits")
print(f"CE (good model):          {cross_entropy(true_dist, good_model):.4f} bits")
print(f"CE (bad model):           {cross_entropy(true_dist, bad_model):.4f} bits")
print(f"KL divergence (good):     {kl_divergence(true_dist, good_model):.4f} bits")
print(f"KL divergence (bad):      {kl_divergence(true_dist, bad_model):.4f} bits")

گام 3: آنتروپی متقاطع به‌عنوان زیان طبقه‌بندی

def softmax(logits):
    max_logit = max(logits)
    exps = [math.exp(z - max_logit) for z in logits]
    total = sum(exps)
    return [e / total for e in exps]

def cross_entropy_loss(true_class, logits):
    probs = softmax(logits)
    return -math.log(probs[true_class])

logits = [2.0, 1.0, 0.1]
true_class = 0

probs = softmax(logits)
loss = cross_entropy_loss(true_class, logits)

print(f"Logits:      {logits}")
print(f"Softmax:     {[f'{p:.4f}' for p in probs]}")
print(f"True class:  {true_class}")
print(f"Loss:        {loss:.4f} nats")
print(f"Perplexity:  {math.exp(loss):.2f}")

گام 4: برابری آنتروپی متقاطع با منفی لگاریتم درست‌نمایی

import random

random.seed(42)

n_samples = 1000
n_classes = 3
true_labels = [random.randint(0, n_classes - 1) for _ in range(n_samples)]
model_logits = [[random.gauss(0, 1) for _ in range(n_classes)] for _ in range(n_samples)]

ce_loss = sum(
    cross_entropy_loss(label, logits)
    for label, logits in zip(true_labels, model_logits)
) / n_samples

nll = -sum(
    math.log(softmax(logits)[label])
    for label, logits in zip(true_labels, model_logits)
) / n_samples

print(f"Cross-entropy loss:      {ce_loss:.6f}")
print(f"Negative log-likelihood: {nll:.6f}")
print(f"Difference:              {abs(ce_loss - nll):.2e}")

گام 5: اطلاعات متقابل

def mutual_information(joint_probs, base=2):
    rows = len(joint_probs)
    cols = len(joint_probs[0])

    margin_x = [sum(joint_probs[i][j] for j in range(cols)) for i in range(rows)]
    margin_y = [sum(joint_probs[i][j] for i in range(rows)) for j in range(cols)]

    mi = 0.0
    for i in range(rows):
        for j in range(cols):
            pxy = joint_probs[i][j]
            if pxy > 0:
                mi += pxy * math.log(pxy / (margin_x[i] * margin_y[j])) / math.log(base)
    return mi

independent = [[0.25, 0.25], [0.25, 0.25]]
dependent = [[0.45, 0.05], [0.05, 0.45]]

print(f"MI (independent): {mutual_information(independent):.4f} bits")
print(f"MI (dependent):   {mutual_information(dependent):.4f} bits")

استفاده از ابزارهای واقعی

پیاده‌سازی همین مفاهیم با NumPy، درست به همان روشی که در عمل استفاده خواهید کرد:

import numpy as np

def np_entropy(p):
    p = np.asarray(p, dtype=float)
    mask = p > 0
    result = np.zeros_like(p)
    result[mask] = p[mask] * np.log(p[mask])
    return -result.sum()

def np_cross_entropy(p, q):
    p, q = np.asarray(p, dtype=float), np.asarray(q, dtype=float)
    mask = p > 0
    return -(p[mask] * np.log(q[mask])).sum()

def np_kl_divergence(p, q):
    return np_cross_entropy(p, q) - np_entropy(p)

true = np.array([0.7, 0.2, 0.1])
pred = np.array([0.6, 0.25, 0.15])
print(f"Entropy:    {np_entropy(true):.4f} nats")
print(f"Cross-ent:  {np_cross_entropy(true, pred):.4f} nats")
print(f"KL div:     {np_kl_divergence(true, pred):.4f} nats")

شما عملکرد درونی torch.nn.CrossEntropyLoss() را از صفر ساختید. حالا دلیل افت مقدار زیان در زمان آموزش را می‌دانید: توزیع پیش‌بینی‌شده‌ی مدل دارد به توزیع واقعی نزدیک‌تر می‌شود؛ فاصله‌ای که بر حسب نات‌های اطلاعات تلف‌شده سنجیده می‌شود.

تمرین‌ها

  1. آنتروپی الفبای انگلیسی را با فرض توزیع یکنواخت (26 حرف) حساب کنید. سپس این مقدار را بر اساس بسامد واقعی حروف تخمین بزنید. کدام مقدار بیشتر است و چرا؟

  2. مدلی برای یک نمونه با برچسب واقعی 1، لاجیت‌های [5.0, 2.0, 0.5] را خروجی می‌دهد. زیان آنتروپی متقاطع را دستی حساب کنید، سپس با تابع cross_entropy_loss خود درستی نتیجه را بسنجید. چه لاجیت‌هایی مقدار زیان را صفر می‌کنند؟

  3. نشان دهید که واگرایی KL متقارن نیست. دو توزیع PP و QQ را در نظر بگیرید و مقادیر DKL(P∥Q)D_{KL}(P \Vert Q) و DKL(Q∥P)D_{KL}(Q \Vert P) را حساب کنید. دلیل تفاوت این دو عدد را توضیح دهید.

  4. تابعی بنویسید که پرپلکسیتی را برای دنباله‌ای از پیش‌بینی‌های توکن حساب کند. با گرفتن لیستی از جفت‌های (true_token_index, predicted_logits)، پرپلکسیتی توالی را بازگردانید.

راهنمایی‌ها

تمرین 1. تابع entropy را با 26 احتمال برابر فراخوانی کنید؛ خروجی باید log⁡226≈4.70\log_2 26 \approx 4.70 بیت باشد. بسامد واقعی حروف نامتعادل و غیریکنواخت است، بنابراین آنتروپی با داده‌های واقعی باید کمتر شود.

تمرین 2. ابتدا تابع softmax لاجیت‌ها را حساب کنید، سپس مقدار −ln⁡-\ln احتمال اندیس 1 را بگیرید و با خروجی cross_entropy_loss(1, logits) مقایسه کنید؛ هر دو عدد باید نزدیک به 3.06 باشند. مقدار زیان تنها زمانی به سمت 0 میل می‌کند که لاجیت کلاس 1 بسیار بزرگ‌تر از دو کلاس دیگر باشد.

تمرین 3. دو توزیع کوچک با شکل‌های متفاوت انتخاب کنید (مثلاً P=[0.9,0.1]P = [0.9, 0.1] و Q=[0.5,0.5]Q = [0.5, 0.5]) و تابع kl_divergence را با هر دو ترتیب ورودی فراخوانی کنید. این دو مقدار باید متفاوت باشند؛ چرا که در هر جهت، لگاریتم نسبت احتمالات با توزیع متفاوتی وزن‌دهی می‌شود.

تمرین 4. برای هر جفت ورودی، مقدار cross_entropy_loss(true_token_index, predicted_logits) را حساب کنید، میانگین بگیرید و نتیجه را به perplexity بفرستید. درستی تابع را با لاجیت‌های یکنواخت روی VV توکن بیازمایید: پرپلکسیتی باید دقیقاً VV شود.

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

اصطلاح در گفتار عامیانه معنای دقیق و فنی
محتوای اطلاعات (Information content) «غافلگیری» تعداد بیت‌ها (یا نات‌ها) مورد نیاز برای کدگذاری یک رویداد: −log⁡(p)-\log(p)
آنتروپی (Entropy) «تصادفی بودن» میانگین غافلگیری در میان همه‌ی پیامدهای یک توزیع. مقیاسی برای سنجش عدم قطعیتِ کاهش‌ناپذیر.
آنتروپی متقاطع (Cross-entropy) «همان تابع زیان» میانگین غافلگیری هنگام استفاده از توزیع مدل QQ برای کدگذاری پیامدهای حاصل از توزیع واقعی PP.
واگرایی کولبک-لایبلر (KL divergence) «فاصله‌ی میان دو توزیع» بیت‌های اضافه‌ای که به دلیل استفاده از QQ به‌جای PP هدر می‌روند. برابر با آنتروپی متقاطع منهای آنتروپی. نامتقارن است.
اطلاعات متقابل (Mutual information) «ارتباط متغیرهای X و Y» میزان کاهش عدم قطعیت درباره‌ی XX در صورت دانستن YY. مقدار صفر به معنی استقلال دو متغیر است.
سافت‌مکس (Softmax) «تبدیل لاجیت به احتمال» به توان رساندن و نرمال‌سازی. نگاشت هر بردار از اعداد حقیقی به یک توزیع احتمالاتی معتبر.
پرپلکسیتی (Perplexity) «میزان گیج شدن مدل» فرم نماییِ آنتروپی متقاطع. دامنه‌ی واژگان مؤثری که مدل در هر گام از میان آن‌ها دست به انتخاب می‌زند.
بیت (Bits) «واحد شانون» سنجش اطلاعات با لگاریتم بر مبنای 2. هر بیت نتیجه‌ی یک پرتاب سکه‌ی سالم را معلوم می‌کند.
نات (Nats) «واحد یادگیری ماشین» سنجش اطلاعات با لگاریتم طبیعی. واحد پیش‌فرض در PyTorch و TensorFlow.
منفی لگاریتم درست‌نمایی (Negative log-likelihood) «زیان NLL» در برچسب‌های وان-هات دقیقاً با تابع زیان آنتروپی متقاطع یکسان است. کمینه‌سازی آن، احتمال پیش‌بینی‌های درست را بیشینه می‌کند.

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

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درس«آنتروپی» در نظریه اطلاعات چه چیزی را اندازه‌گیری می‌کند؟
  2. پیش از درستابع زیان انتروپی متقاطع معمولاً برای چه کاری در شبکه‌های عصبی استفاده می‌شود؟
  3. پس از درسچرا کمینه کردن انتروپی متقاطع در طول آموزش، معادل کمینه کردن دیورژانس KL است؟
  4. پس از درسیک مدل زبانی روی مجموعه‌ی آزمون دارای پرپلکسیتی 50 است. این به چه معناست؟
  5. پس از درساطلاعات متقابل چه تفاوتی با همبستگی پیرسون در انتخاب ویژگی دارد؟

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

چرا کمینه‌سازی آنتروپی متقاطع معادل بیشینه‌سازی درست‌نمایی (Likelihood) است؟

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

تفاوت بیت (Bit) و نات (Nat) در محاسبه‌ی آنتروپی چیست؟

تفاوت آن‌ها فقط در مبنای لگاریتم است؛ اگر لگاریتم در مبنای 2 محاسبه شود واحد سنجش اطلاعات بیت است و اگر از لگاریتم طبیعی استفاده شود واحد نات خواهد بود (هر نات تقریباً معادل 1.4427 بیت است).

معیار پرپلکسیتی (Perplexity) در مدل‌های زبانی چه چیزی را نشان می‌دهد؟

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

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

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