MZ
The Null Hypothesis
→ العودة إلى المقالات

التعلم العميق

قراءة معمقة في L₀

من عدّ الأوزان غير الصفرية إلى تعلم البوابات والاسترخاءات العشوائية وحذف القنوات المنظم.

كلمات مفتاحية: تنظيم L0 · تقليص الشبكات العصبية · Hard-Concrete · البوابات العشوائية · البوابات الغاوسية · الندرة المنظمة

An abstract neural network diagram with sparse connections, gates, and red and black data flow on a pale grid.
في هذا المقال

الهواء العليل يُطير قبعتك و لكنك حمدا لله أتى حارس محطة القطار لينقذها قبل وقوعها في السكة قبل صعودك لأول يوم في مهمتك التي يغتاظ منها معظم أبطال القصص و كتابها: مفتش تذاكر طيب القلب و منظم حريص على عمله

بالنسبة لك لا يهم كثرة أو قلة ما يحمله الراكب مادام معه تذكرة مادامت موجودة أو ممثلة لك و أي بطل رواية تصادف انه لا يحمل تذكرة يعتبر غير ظاهرا أو من المفترض عدم وجوده و يجب أن ينزل في المحطة التالية

كذلك ال L0 مفتش التذاكر العزيز حريص دوما على أن يعُد الأوزان في الشبكة العصبية لا يهم كثرتها أو قلتها الذي يقيس وزن كل ما يحمله الراكب و يبقى يجمع الأوزان في تلك الخلية

على عكس ابن عمه البعيد، L1L_1 و لكن لماذا نعد الأوزان الموجودة أو الغير الصفرية للشبكة العصبية حسنا لأشياء كثيرة لكن للاجابة مبدئيا على سؤال واحد بل سؤالين في وقت واحد كيف نصل لنموذج جيد بتوقع و دقة جيدة مع أقل عدد من الأوزان ⁦(Louizos et al., 2018; Oliveira et al., 2024)⁩

هذه هي الكفاءة التي يتحدثون عنها ليل نهار و لكن قبل أن تقفل المقال خوفا من رؤية معادلات تبحث عنها لساعتين ثم ترجع و تنسى ما كنت تقرأ هنا لا تقلق هذا الوحش الكبير ليس إلا صديقنا المفتش داخل بذلته الرسمية وسط زملاء عمله

جولة مفتش التذاكر · ٦٠ ثانية

المفتش الأمين

θ =0.90-0.450.200.70-0.80
L₀مساهمة الوزن1010L₁مقدار الوزن−101
∥θ∥0=∑j1{θj≠0}=5\|\theta\|_0 = \sum_j \mathbf 1\{\theta_j\ne0\} = 5∥θ∥1=∑j∣θj∣=3.05\|\theta\|_1 = \sum_j |\theta_j| = 3.05

الشكل 1: يتغير مجموع L₁ مع مقدار الوزن، بينما لا يتغير عدد L₀ إلا عندما يصبح الوزن صفرًا تمامًا.

∥θ∥0=∑j1{θj≠0}\|\theta\|_0=\sum_j\mathbf 1\{\theta_j\ne0\}

معيار L0L_0 يعدّ كل وزن غير صفري مرة واحدة، مهما كان حجمه. والرمز jj هو فهرس الوزن في الشبكة.

فمثلا لديك هذا القطار حاول أن تجمع عدد الاوزان تذكر ذلك : θ=(3,0,−2,0,5)\theta=(3,0,-2,0,5)

لو زاد حجم بعض الاوزان و قل البعض الاخر ماذا سيحدث ؟ سيتغير قيمة صديقنا L1 لكن L0 سيظل كما هو 3 و بهذه الطريقة عرفنا لويزو و من معه من باحثون ⁦(Louizos et al., 2018)⁩ على الL0  طريقة جميلة و أنيقة و لكنها قاسية قليلا و ما يسأله الL0 هل يجب أن يبقى هذا الوزن على متن القطار و لكن لماذا نجمع الأوزان الغير صفرية ؟

جرّب بنفسك: احسب ما يراه المفتش

python

النتيجة: عدد L0L_0 يساوي 3 ومجموع L1L_1 يساوي 10.

الL 0 و ضغط الشبكات العصبية

تخيل شبكة عصبية بها مليون وزن فلو كان كلهم غير صفريين

سيصبح لدينا ∥θ∥0=1,000,000\|\theta\|_0=1{,}000{,}000 و هكذا يمكننا أن نرى مبدئيا أن لكل الأوزان ظهورا و لكن عندما ندرب هذه الشبكة العصبية وجدنا أن فقط 100,000 من هذه الأوزان هي ما تؤثر على النتيجة سواء كالتصنيف أو أي شئ آخر لذلك سيكون

∥θ∥0=100,000\|\theta\|_0=100{,}000

و هكذا نصل إلي تنبؤ جيد مع عدد معلمات مشاركة أقل وهي ما تقترن بها الأوزان لكن كيف وصلنا هنا؟ المفتش يستطيع عدد العناصر غير الصفرية جيدا أما بالنسبة لمن لديه أو من يستحق التذكرة فلا يعلم حتى الآن و هنا يدخل لويزو  ورفاقه ثانية

يمكن أن يخطر ببالك فكرة إذا كنت تعلم عن الشبكة العصبية مسبقا أن نضيف ال L0 لهدف التمرين وندع الgradient descent أو كما أحب تسميته بالنزول عن التل يخبرنا بما نحتاج إبقاءه

حسنا لن أستطيع من خلال سطرين أن ألخص كيف تتعلم الشبكة العصبية، سأستفيض في شرحها في نهاية السلسلة لكن دعني أخبرك ما نحتاجه هنا، حتى تتمرن الشبكة العصبية نحتاج إلي backpropagation و هو أساس لكي نرجع من نهاية القرار إلى البداية وهو بمثابة النزول من التل، يخبرنا الانتشار العكسي باتجاه انحدار التل، بينما يقوم المُحسِّن فعليًا باتخاذ الخطوة نحو الأسفل.

النزول من التل

الآن نحن على قمة التل- أدري أن أمثلة التضاريس كثيرة في هذه السلسلة لكني جعلتك على قطار تسافر وسط حقول خضراء-تحاول النزول تحتاج أولا أن تعرف من أي جهة ينحدر و هذه هي وظيفة الميل :

∂L∂w\frac{\partial L}{\partial w}

فماذا سيحدث إن غيرنا ال w أو الوزن بجزء بسيط

و لننظر من جهة الL 0 كلما قللنا الوزن لن يتغير القرار سيظل للوزن ظهور أما محسن الأداء optimizer ينظر إليه و يسأله كل مرة يحاول أن يغير قيمة الوزن و من بعدها يبحث عن التغير في قيمة الL0 و التي تظل واحدة لذلك لا وجود للميل الذي يقربنا لسفح الجبل أي الصفر بتدرج.

هذه قسوة المفتش التي أتحدث عنها عندما يصطدم بقيمة صفر لا تنزل فجأة فأنت الأن تقفز من 1 إلي 0

الأن المفتش ينظر إلي الوزن أهو موجود أم لا

لذا لا يمكنه أن يسأل هل يمكنك أن تخرج بتدرج من القطار ؟ بل سيرميه خارجا

جرّب بنفسك: خذ خطوة واحدة من الانحدار

python

يتجه الوزن نحو قيمة تقلل خسارة هذا المثال؛ أما عدّ L0L_0 الصلب فلا يعطي هذا الميل.

البوابة

لذلك لويزو ورفاقه بدلا من جعلهم رقما واحدا يجاوب على سؤالي ما هو الوزن؟ و إذا كنا نحتاجه كله أم ماذا ؟في وقت واحد سيفصلونها لجزئين و هذا ما سيقودنا إلي

θj=θ~jzj\theta_j=\tilde{\theta}_j z_j

حيث θ~j\tilde{\theta}_j هو الوزن الأصلي قبل قرار الإبقاء أو الإزالة، وzjz_j هي البوابة، أما θj\theta_j فهو الوزن الفعلي بعدها.

و بذلك الوزن الأساسي × قرار المشاركة = الوزن الفعلي

و بذلك تطور المفتش الذي يشاهد الوجود فقط بل لديه إثنين أحدهما وزن ما يحمله الراكب و أيضا تذكرته ( مساهمة الوزن و الوجود)

و الأن أصبح لدينا سؤال واحد نحتاج إجابته هل البوابة مفتوحة؟

هذه هي بداية حل مشكلة التعلم كيف سنقرر متى تفتح و تغلق البوابة كيف سنقرر من نعطيه ال1 و الصفر في الz

لذلك z هو متغير يأخذ قيمة صفر وواحد و له هذا الاحتمال لذلك من المنطقي استخدامهم لتوزيع برنولي

zj∼Bernoulli⁡(πj)z_j\sim\operatorname{Bernoulli}(\pi_j)

إذا كان الوزن θ~j\tilde{\theta}_j مفيدًا، ترتفع احتمالية فتح بوابته zjz_j، والعكس إذا قلّ إسهامه.

جرّب بنفسك: طبّق البوابة على الأوزان

python

البوابة المغلقة تصفّر الوزن الأوسط: [4, 0, 7].

العدد المتوقع للبوابات النشطة

حسنا الخطوة القادمة أن نصل إلي التوقع ل  Z_j ورمز التوقع E\mathbb E ⁦(Louizos et al., 2018)⁩

لدينا:

E∥θ∥0=∑jπj\boxed{ \mathbb E\|\theta\|_0 = \sum_j \pi_j }

ومعناها: المتوسط المتوقع لعدد الأوزان الفعالة يساوي مجموع احتمالات فتح بواباتها.

نبدأ من: θj=θ~jzj\theta_j=\tilde{\theta}_j z_j حيث: θ~j\tilde{\theta}_j هو الوزن الأساسي، و zjz_j هو البوابة. إذا افترضنا أن θ~j≠0\tilde{\theta}_j\ne0

إذا اعتبرنا θ~j\tilde{\theta}_j غير صفري، فإن zjz_j وحدها تحدد هل الوزن الفعلي θj\theta_j موجود أم لا.

إذا: zj=1z_j=1 فإن: θj=θ~j\theta_j=\tilde{\theta}_j إذن الوزن موجود ويحسبه L0 كواحد. أما إذا: zj=0z_j=0 فإن: θj=0\theta_j=0 إذن الوزن مختفٍ ولا يحسبه L0. لذلك، بالنسبة لوزن واحد فقط، مساهمته في عدد L0 تساوي ببساطة: zjz_j

لأن zjz_j نفسه إما 1 أو 0.

فإذا كان عندنا عدة أوزان: z1,z2,z3z_1,z_2,z_3 فإن عدد الأوزان المفتوحة في عينة معينة يساوي: ∥θ∥0=∑jzj\|\theta\|_0 = \sum_j z_j مثلاً إذا كانت البوابات في لحظة ما: (1,0,1,1,0) فإن: ∥θ∥0=3\|\theta\|_0=3 لأن ثلاث بوابات مفتوحة. لكن هنا zjz_j ليست ثابتة أثناء التدريب، بل عشوائية: zj∼Bernoulli⁡(πj)z_j\sim \operatorname{Bernoulli}(\pi_j) يعني: zj=1z_j=1 باحتمال

πj\pi_j و zj=0z_j=0 باحتمال 1−πj1-\pi_j الآن يأتي معنى التوقع. التوقع: E[zj]\mathbb E[z_j] يعني: لو كررنا تجربة فتح وإغلاق هذه البوابة مرات كثيرة جدًا، فما متوسط قيمتها؟

وبما أن قيمتها إما 1 أو 0، نحسب المتوسط المتوقع هكذا: E[zj]=1⋅πj+0⋅(1−πj)\mathbb E[z_j] = 1\cdot\pi_j + 0\cdot(1-\pi_j) فتصبح:

E[zj]=πj\boxed{ \mathbb E[z_j]=\pi_j }

مثلاً إذا: πj=0.8\pi_j=0.8 فهذا لا يعني أن البوابة قيمتها 0.8.

البوابة نفسها تظل في كل مرة إما: 0 أو 1.

لكن لو كررنا أخذ عينات كثيرة، نتوقع أن تكون مفتوحة في حوالي 80%80\% من المرات، ولذلك متوسطها يقترب من: 0.8. والآن نعود إلى عدد الأوزان: ∥θ∥0=∑jzj.\|\theta\|_0 = \sum_j z_j. نأخذ التوقع: E∥θ∥0=E[∑jzj].\mathbb E\|\theta\|_0 = \mathbb E\left[\sum_jz_j\right]. خاصية مهمة في التوقع تقول إن توقع المجموع يساوي مجموع التوقعات: =∑jE[zj].= \sum_j\mathbb E[z_j]. وبما أن: E[zj]=πj\mathbb E[z_j]=\pi_j إذن:

E∥θ∥0=∑jπj\boxed{ \mathbb E\|\theta\|_0 = \sum_j\pi_j }

خذ مثالًا صغيرًا. عندنا ثلاث بوابات: π1=0.9,  π2=0.2,  π3=0.7\pi_1=0.9,\;\pi_2=0.2,\;\pi_3=0.7. إذن: E∥θ∥0=0.9+0.2+0.7=1.8.\mathbb E\|\theta\|_0 = 0.9+0.2+0.7 = 1.8.

هذا لا يعني أن لدينا 1.8 وزنًا فعليًا.

في أي تجربة فعلية، عدد الأوزان المفتوحة يمكن أن يكون: 0,1,2,أو3. لكن لو كررنا أخذ البوابات مرات كثيرة جدًا، فإن متوسط عدد الأوزان المفتوحة سيقترب من: 1.8. بصياغة أبسط: كل راكب لديه احتمال أن يحمل تذكرة. إذا جمعنا احتمالات امتلاك التذاكر لكل الركاب، نحصل على العدد المتوقع للركاب الموجودين على القطار.

وهذه بالضبط هي النقلة المهمة هنا: بدل أن نحاول التعامل مباشرة مع عدد صلب من الصفر والواحد، أصبح لدينا: πj\pi_j وهي كمية تتغير تدريجيًا، مثل: 0.9,  0.8,  0.6,  0.30.9,\;0.8,\;0.6,\;0.3. وهذا يقودنا مباشرة إلى سؤالنا التالي:

جرّب بنفسك: قدّر العدد المتوقع للبوابات المفتوحة

python

ينبغي أن يقترب متوسط المحاكاة من القيمة النظرية 1.8.

إذا أصبح جزء L0 أسهل بهذه الطريقة، فما الذي ما زال صعبًا في دالة التدريب نفسها؟

الهدف

الآن نحتاج للشبكة العصبية أن تتعلم شيئين في آن واحد أن تكون توقعات جيدة وأن نحتفظ بأقل قدر ممكن من المكونات النشطة.

و هذا يتركنا أمام المعادلة الأكبر في رحلتنا حتى الأن

J(θ~,π)=Ez[L(θ~⊙z)]+λ∑jπj.\mathcal J(\tilde{\theta},\pi)=\mathbb E_z[\mathcal L(\tilde{\theta}\odot z)]+\lambda\sum_j\pi_j.

لا تخف منها فهي الشيئان الذين نحاول تعليم الشبكة العصبية التوقع ولكن سنفككها معا

الجزء الأول حدّ التنبؤ هو Ez[L(θ~⊙z)]\mathbb E_z[\mathcal L(\tilde{\theta}\odot z)]: متوسط خسارة التنبؤ عبر عينات البوابات. والرمز ⊙\odot يعني الضرب عنصرًا بعنصر.

لتكن (4,2,7)(4,2,7) و z=(1,0,1)z=(1,0,1) (4,2,7)⊙(1,0,1)=(4,0,7).(4,2,7)\odot(1,0,1)=(4,0,7). L(z) سيكون معناها أن احسب خسارة التنبؤ باستخدام الشبكة بعد أن تقوم البوابات التي تم أخذ عينات منها بإيقاف تشغيل بعض الأوزان.

و الأن سنرجع للتوقع و هو إلي حد ما تقدير للمتوسط و هو يجيب على السؤال في المتوسط، عبر تكوينات البوابات الناتجة عن هذه الاحتمالات، يجب أن يظل التنبؤ جيدًا.

و الان ننتقل للجزء الثاني فاتورة المفتش أما λ∑jπj\lambda\sum_j\pi_j فهو ثمن النشاط المتوقع؛ وتحدد λ\lambda مقدار الضغط نحو إغلاق البوابات. و كلما قل أصبحت الأولوية للتنبؤ و كلما زادت أصبح أولوية قص الأوزان

و الأن في رحلة التعلم يتجادل طرفي المعادلة معا فالتنبؤ يحاول دوما أن يفتح أكبر قدر من البوابات لكي يبقى التنبؤ عاليا و القص يحاول أن يحذف أكثر قدر من البوابات و حل الجدال؟

المكونات أو البوابات هي من تعطينا الدليل.

إذا كان المكوّن مهمًا، تحاول خسارة التنبؤ رفع احتمال بوابته πj\pi_j. وإذا لم يكن مهمًا، تدفعه عقوبة sparsity إلى خفض هذا الاحتمال.

جرّب بنفسك — غيّر ثمن البوابة

python

يوضح المثال مساهمة العقوبة مع تغيّر λ\lambda؛ وهو تمرين توضيحي لا نتيجة تدريب للشبكة.

سنحتاج إلى تفاضل هذه المعادلة. حدّ العقوبة λ∑jπj\lambda\sum_j\pi_j قابل للاشتقاق لأن πj\pi_j متغير مستمر. لكن حدّ التنبؤ ما زال يعتمد على عينة Bernoulli متقطعة zj∈{0,1}z_j\in\{0,1\}، لذلك لا نستطيع تمرير التدرج عبر خطوة أخذ العينة بالطريقة العادية.

كيف تتعلم الشبكة العصبية

أتتذكر ال backpropagation ؟ حسنا يحتاج إلى سلسلة مثل abc حيث نفاضلهم من خلال قاعدة السلسلة

و لكننا نواجه مشكلة هنا b هي اتباع z توزيع برنولي و هو توزيع متقطع و بذلك z متقطع إما 0 او 1 و بذلك لا يمكننا مفاضلته

نصل الآن إلى الخطوة الكبرى التالية عند لويزو.

الاسترخاء المستمر: إعطاء البوابة مساحة وسطية

z = clip(s, 0, 1)s = 0.62z = 0.62
z = clip(s, 0, 1)10−0.5011.5s

الشكل 2: يحافظ القص على قيم البوابة الوسيطة مع السماح أيضًا بصفر وواحد حقيقيين.

حتى الآن، كانت البوابة: zj∈{0,1}z_j\in\{0,1\} وهذا يعني:

  • 0: مغلقة
  • 1: مفتوحة

وهذا الانتقال حاد جدًا بالنسبة للـ backpropagation العادي.

لذلك يُدخل لويزو أولًا متغيرًا مستمرًا جديدًا:

sj∼q(sj∣ϕj)\boxed{ s_j \sim q(s_j\mid \phi_j) }

ثم يعرّف البوابة الفعلية باستخدام القص أو clipping:

zj=clip⁡(sj,0,1)\boxed{ z_j=\operatorname{clip}(s_j,0,1) }

وهذه هي الوصفة العامة للبوابة المستمرة ⁦(Louizos et al., 2018)⁩.

لا تقلق الآن بشأن q أو j. افهم الفكرة أولًا.


قبل ذلك كانت البوابة تستطيع أن تكون فقط: 0 أو: 1. لم تكن هناك حالة وسطية.

أما الآن فننشئ أولًا قيمة مستمرة sjs_j.

يمكن أن تكون مثلًا: -0.7,0.2,0.65,1.3 أو أي قيم حقيقية أخرى. ثم نمررها عبر: clip⁡(sj,0,1).\operatorname{clip}(s_j,0,1).


ماذا تعني clip؟ الـ clipping يعني: أي قيمة أقل من 0 تصبح بالضبط 0. أي قيمة بين 0 و1 تبقى كما هي. أي قيمة أكبر من 1 تصبح بالضبط 1.

رياضيًا:

clip⁡(s,0,1)={0,s≤0,s,0<s<1,1,s≥1.\operatorname{clip}(s,0,1) = \begin{cases} 0,&s\le 0,\\[4pt] s,&0<s<1,\\[4pt] 1,&s\ge1. \end{cases}

وهذه هي الصيغة القطعية لتعريف القص.


أمثلة: إذا كان: sj=−0.4s_j=-0.4 فإن: zj=0z_j=0. وإذا كان: sj=0.25s_j=0.25 فإن: zj=0.25z_j=0.25.

إذا كان: sj=0.8s_j=0.8 فإن: zj=0.8z_j=0.8. وإذا كان: sj=1.6s_j=1.6 فإن: zj=1z_j=1. إذن الآن يمكن للبوابة أن تكون مثل: 0,0.1,0.4,0.8,1 بدلًا من أن تكون فقط: 0,1.


لماذا هذا مفيد؟ لأن البوابة يمكنها الآن أن تتحرك تدريجيًا.

بدلًا من: 11 في قفزة واحدة حادة، يمكن أن يكون لدينا: 1,0.8,0.6,0.3,01, 0.8, 0.6, 0.3, 0.

وهذا يعطي التحسين المعتمد على التدرجات شيئًا أفضل بكثير للعمل معه.

الآن متسلق الجبل يرى ميلًا تدريجيًا بدلًا من حافة مفاجئة.


لكن لماذا نستخدم clipping أصلًا؟ هذا مهم جدًا. قد تسأل: إذا كنا نريد الاستمرارية، فلماذا لا نستخدم sjs_j مباشرة؟

لأننا ما زلنا نريد إمكانية الإزالة الحقيقية.

إذا كانت البوابة دائمًا قيمة ناعمة مثل: 0.00001 فهي من الناحية التقنية لا تزال غير صفرية.

وتذكر أن L0 يهتم بـ: صفر مقابل غير صفر. إذن لويزو يريد شيئين معًا:

سلوك مستمر يسهل التعلم

و

أصفار حقيقية لتحقيق sparsity

والـ clipping يحقق الاثنين ⁦(Louizos et al., 2018)⁩. إذا كان: sj≤0s_j\le0 فنحصل على: zj=0z_j=0 بالضبط. ليس: 0.00001. بل صفر حقيقي. وإذا كان: sj≥1s_j\ge1 فنحصل على: zj=1z_j=1 بالضبط.

ولهذا يصنع الـ clipping أصفارًا ووحدات حقيقية، مع السماح بقيم مستمرة بينهما.

تشبيه المفتش

المفتش لم يعد يفكر في حالتين فقط. في السابق كان لديه: تذكرة أو لا توجد تذكرة. أما الآن فأثناء التدريب توجد مساحة وسطية.

يمكن أن يكون لدينا: zj=0.8z_j=0.8 أي: هذا الوزن يساهم حاليًا بنسبة 80%80\%. أو: zj=0.3z_j=0.3 أي: هذا الوزن يساهم بنسبة 30%30\%. وإذا تحرك المتغير الأساسي إلى ما دون الصفر، يقول المفتش أخيرًا: انتهى، أُزيل. فنحصل على: zj=0z_j=0. وهكذا أصبح لدينا طريق تدريجي نحو الإزالة.

لكن انتبه إلى نقطة دقيقة: البوابة الفعلية هي: zj=clip⁡(sj,0,1)z_j=\operatorname{clip}(s_j,0,1) أما المتغير المستمر قبل القص فهو: sjs_j. وهما ليسا الشيء نفسه.

مثلًا: sj=−0.7s_j=-0.7 لكن: zj=0z_j=0. أو: sj=1.4s_j=1.4 لكن: zj=1z_j=1. إذن sjs_j يمكن أن يعيش في مجال أوسع من القيم الحقيقية، بينما zjz_j يُجبر على البقاء داخل: [0,1].

والآن يحدث شيء مهم لاحتمال L0: البوابة تكون فعالة عندما: zj>0z_j>0. وبسبب الـ clipping، فإن: zj>0z_j>0 يحدث بالضبط عندما: sj>0s_j>0. إذن: P(zj>0)=P(sj>0)P(z_j>0)=P(s_j>0).

إذا كانت QjQ_j هي دالة التوزيع التراكمي CDF الخاصة بـ sjs_j، فإن: P(sj>0)=1−Qj(0)P(s_j>0)=1-Q_j(0). وبالتالي:

P(zj>0)=1−Qj(0)\boxed{ P(z_j>0) = 1-Q_j(0) }

وهذه هي النسخة المستمرة من فكرة Bernoulli السابقة.

بدلًا من: πj\pi_j أصبح لدينا: 1−Qj(0)1-Q_j(0) بوصفه احتمال أن تكون البوابة فعالة.

وبالتالي تصبح دالة الهدف الجديدة

J(θ~,ϕ)=Es[L(θ~⊙clip⁡(s,0,1))]+λ∑j[1−Qj(0)].\mathcal J(\tilde\theta,\phi) = \mathbb E_s \left[ \mathcal L \big( \tilde\theta\odot \operatorname{clip}(s,0,1) \big) \right] + \lambda \sum_j \left[ 1-Q_j(0) \right].

لا تحفظ هذه المعادلة الآن. المهم هو الفكرة:

بوابة ثنائية→متغير عشوائي مستمر→بوابة بعد clipping\boxed{ \text{بوابة ثنائية} \rightarrow \text{متغير عشوائي مستمر} \rightarrow \text{بوابة بعد clipping} }

أي:

sj→zj=clip⁡(sj,0,1)\boxed{ s_j \rightarrow z_j=\operatorname{clip}(s_j,0,1) }

وهذه هي الجسور التي تسمح لاحقًا باستخدام توزيعات مستمرة مختلفة.

ولهذا فهذه الخطوة مهمة جدًا عندما نصل بعد ذلك إلى Gaussian gates.

إطار لويزو هنا أوسع من Hard-Concrete نفسه؛ فالفكرة العامة تسمح باستخدام توزيعات مستمرة أخرى طالما يمكن حساب الاحتمالات المطلوبة وإجراء reparameterization مناسب لها.

إذن هذه هي النقطة التي يبدأ منها الطريق نحو Gaussian gates.

والسؤال التالي هو:

كيف نُدرّب أصلًا معاملات التوزيع الذي يولّد sj؟\boxed{ \text{كيف نُدرّب أصلًا معاملات التوزيع الذي يولّد }s_j؟ }

وهنا تدخل فكرة:

Reparameterization

جرّب بنفسك: قصّ عينة مستمرة

python

القيم الأقل من صفر تصبح صفرًا، والأكبر من واحد تصبح واحدًا.

إعادة صياغة العشوائية: Reparameterization

وصلنا في آخر محطة إلى أن وجود متغير مستمر مثل sjs_j أفضل من أن نقفز مباشرة بين الصفر والواحد، لكن بقي سؤال مهم: نحن ما زلنا نأخذ sjs_j كعينة من توزيع احتمالي، فكيف يستطيع الـ backpropagation أن يعرف كيف غيَّرنا معاملات هذا التوزيع؟

الفكرة التي يستخدمها لويزو هنا تسمى Reparameterization، واسمها أكبر من فكرتها. بدل أن نخفي العشوائية داخل عملية أخذ العينة نفسها، نفصل بين شيئين:

  1. جزء نتعلمه.
  2. وجزء عشوائي لا نتعلمه.

فنكتب بصورة عامة:

sj=f(ϕj,ϵj)\boxed{s_j=f(\phi_j,\epsilon_j)}

حيث ϕj\phi_j هي معاملات التوزيع التي نريد تعلمها، و ϵj\epsilon_j ضوضاء عشوائية نأخذها من توزيع ثابت لا يعتمد على ϕj\phi_j.

الفكرة ببساطة أن العشوائية لم تختف، لكنها خرجت من الطريق الذي نريد أن نفاضله. أصبح لدينا رقم عشوائي ϵj\epsilon_j، ثم دالة عادية تربطه بالمعامل الذي نريد تعلمه.


مثال سريع قبل Hard-Concrete

لو كان التوزيع Gaussian نستطيع أن نكتب: ϵj∼N(0,1)\epsilon_j\sim\mathcal N(0,1)

sj=μj+σjϵj\boxed{s_j=\mu_j+\sigma_j\epsilon_j}

لو أخذنا في إحدى الخطوات: ϵj=0.6,μj=0.4,σj=0.5\epsilon_j=0.6,\qquad \mu_j=0.4,\qquad \sigma_j=0.5 سيصبح: sj=0.4+0.5(0.6)=0.7s_j=0.4+0.5(0.6)=0.7

والآن أثناء الـ backward pass نتعامل مع قيمة ϵj=0.6\epsilon_j=0.6 التي أخذناها كأنها ثابتة في هذه الخطوة. فإذا غيّرنا μj\mu_j من 0.40.4 إلى 0.410.41، يتحرك sjs_j من 0.70.7 إلى 0.710.71. أصبح هناك طريق واضح يستطيع التفاضل السير خلاله.

μj,σj⟶sj⟶zj⟶prediction⟶L\mu_j,\sigma_j \longrightarrow s_j \longrightarrow z_j \longrightarrow \text{prediction} \longrightarrow \mathcal L

إذن الـ Reparameterization لا يلغي العشوائية. هو فقط يقول: ضع العشوائية في ϵ\epsilon، واجعل المعامل الذي نريد تعلمه ظاهرًا داخل معادلة يمكن تفاضلها.

لكن انتبه: هذا المثال Gaussian فقط لشرح الفكرة العامة. لويزو في طريقته الأساسية لم يستخدم Gaussian gate؛ اختار Hard-Concrete، والآن وصلنا إليه أخيرًا.


جرّب بنفسك: ثبّت الضوضاء وغيّر المعامل

python

نستخدم الضوضاء نفسها، بينما يغيّر المعامل المتعلَّم موضع العينة بسلاسة.

Hard-Concrete: بوابة لويزو التي تحاول أن تجمع العالمين

نريد الآن شيئًا يحقق مطلبين كانا يبدوان متعارضين: نريد بوابة ناعمة يمكن التدريب خلالها، وفي نفس الوقت نريد أن تنتهي بعض البوابات إلى صفر حقيقي حتى يصبح لدينا L0L_0 حقيقي وليس مجرد أوزان صغيرة.

Hard-Concrete يبني هذا على عدة خطوات، لذلك لا تنظر إلى المعادلة كاملة مرة واحدة.


الخطوة الأولى: رقم عشوائي بسيط

نبدأ بـ: uj∼U(0,1)u_j\sim\mathcal U(0,1) أي نأخذ رقمًا عشوائيًا بين صفر وواحد.

مثلًا قد يكون: uj=0.2u_j=0.2 أو: uj=0.73u_j=0.73 لا يوجد قرار فتح أو إغلاق بعد. هذا فقط مصدر العشوائية.


الخطوة الثانية: نحول الرقم إلى Logistic noise

لويزو يستخدم: gj=log⁡uj−log⁡(1−uj)g_j=\log u_j-\log(1-u_j) هذه العملية تحول الرقم الذي جاء من Uniform distribution إلى ضوضاء Logistic.

لا نحتاج الآن أن نغرق في التوزيع نفسه. المهم أن gjg_j هو الجزء العشوائي، بينما سنضع بجانبه شيئًا يمكن للشبكة تعلمه.


الخطوة الثالثة: يدخل log⁡αj\log\alpha_j

الآن:

qj=gj+log⁡αjβq_j= \frac{g_j+\log\alpha_j}{\beta}

ثم: s~j=sigmoid⁡(qj)\tilde{s}_j=\operatorname{sigmoid}(q_j) هنا ظهر أول متغير مهم تتعلمه الشبكة:

log⁡αj\boxed{\log\alpha_j}

يمكنك التفكير فيه كمقبض يحرك توزيع البوابة. عندما يتحرك في اتجاه كبير موجب تميل البوابة أكثر ناحية الفتح، وعندما يتحرك ناحية السالب تميل أكثر ناحية الإغلاق.

أما β\beta فهي الـ temperature. هي تتحكم في مدى حدة أو نعومة الانتقال. لا تحتاج الآن أن تحفظ أثر كل قيمة، فقط تذكر أن log⁡αj\log\alpha_j هو الجزء الذي نتعلمه لكل بوابة، و β\beta تتحكم في شكل الاسترخاء.

والـ sigmoid يأخذ أي رقم حقيقي ويضغطه داخل المجال: (0,1)(0,1)

إذن s~j\tilde{s}_j أصبح قيمة ناعمة بين صفر وواحد.


لكن لو بقيت القيمة داخل (0,1)(0,1) فلن نحصل على صفر حقيقي

وهنا تأتي حركة Hard-Concrete الأساسية. لويزو لا يكتفي بالقيمة بين صفر وواحد، بل يمد المجال قليلًا إلى الخارج:

sˉj=s~j(ζ−γ)+γ\boxed{ \bar{s}_j= \tilde{s}_j(\zeta-\gamma)+\gamma }

حيث: γ<0,ζ>1\gamma<0,\qquad \zeta>1 في إعدادات الورقة استُخدمت مثلًا: γ=−0.1,ζ=1.1,β=23\gamma=-0.1,\qquad \zeta=1.1,\qquad \beta=\frac23 ما الفائدة من هذا المد؟

تخيل أن s~j\tilde{s}_j كان محبوسًا دائمًا بين صفر وواحد. بعد المد أصبح جزء من القيم يمكن أن يقع أقل من صفر، وجزء آخر يمكن أن يتجاوز الواحد.

ثم نطبق الحركة التي عرفناها مسبقًا:

zj=clip⁡(sˉj,0,1)\boxed{ z_j=\operatorname{clip}(\bar{s}_j,0,1) }

أي أن القيم التي هبطت تحت الصفر تصبح صفرًا حقيقيًا، والقيم التي ارتفعت فوق الواحد تصبح واحدًا حقيقيًا، وما بينهما يبقى ناعمًا.


لماذا يسمى Hard-Concrete؟

Concrete يعطينا الاسترخاء المستمر الناعم ⁦(Maddison et al., 2017)⁩، أما كلمة Hard فتأتي من عملية الـ clipping التي تصنع كتلة حقيقية عند الصفر وعند الواحد.

إذن الفكرة كلها يمكن اختصارها هكذا:

u→Logistic noise→sigmoid→stretch→clipu \rightarrow \text{Logistic noise} \rightarrow \text{sigmoid} \rightarrow \text{stretch} \rightarrow \text{clip}

بالمعنى نفسه: لم يعد القرار ورقة تذكرة تظهر فجأة. لدينا طريق ناعم أولًا، ثم في نهايته حاجزان: من خرج تحت الصفر يُغلق عليه الباب تمامًا، ومن تجاوز الواحد تُفتح له البوابة تمامًا.


احتمال أن تكون بوابة Hard-Concrete مفتوحة

تذكر أننا لا نريد فقط عينة zjz_j واحدة، بل نحتاج كذلك إلى معرفة احتمال أن تكون البوابة غير صفرية حتى نحسب عقوبة L0L_0.

في Hard-Concrete يمكن حساب هذا الاحتمال مباشرة:

pj=P(zj>0)=sigmoid⁡(log⁡αj−βlog⁡−γζ)\boxed{ p_j=P(z_j>0) = \operatorname{sigmoid} \left( \log\alpha_j - \beta \log\frac{-\gamma}{\zeta} \right) }

لا تحفظها الآن. المهم أن لدينا مرة أخرى شيئًا شبيهًا بما كان لدينا مع πj\pi_j: pj=P(zj>0)p_j=P(z_j>0) وبالتالي نستطيع أن نجمع: ∑jpj\sum_j p_j لنحصل على العدد المتوقع للبوابات النشطة.

وعند تصغير دالة الهدف، عقوبة L0L_0 تضغط على هذه الاحتمالات إلى الأسفل، بينما خسارة التنبؤ تضغط في الاتجاه المعاكس للبوابات التي يحتاج إليها النموذج.


هل انتهى الأمر وأصبح كل zjz_j صفرًا أو واحدًا؟

لا. أثناء التدريب يمكن أن تكون البوابة مثلًا: zj=0.37z_j=0.37 أو: zj=0.82z_j=0.82

لأننا ما زلنا نعمل باستـرخاء continuous relaxation. في أحيان أخرى ستتشبع بالـ clipping وتصبح صفرًا أو واحدًا بالضبط.

إذن Hard-Concrete لا يعني أن كل forward pass هو شبكة ثنائية تمامًا. هو توزيع مستمر مُقصوص يسمح أيضًا بظهور أصفار ووحدات حقيقية.


بوابة الاختبار عند لويزو ليست نفس عينة التدريب

وهذه نقطة مهمة عندما نفكر في الاستخدام العملي لاحقًا.

أثناء التدريب نأخذ عينات عشوائية، لكن عند الاختبار لا نريد أن تتغير نتيجة النموذج كل مرة بسبب سحب عشوائي جديد، لذلك يعطي لويزو بوابة حتمية تعتمد على الموقع الذي تعلمناه:

z^j=clip⁡(sigmoid⁡(log⁡αj)(ζ−γ)+γ,0,1)\boxed{ \hat z_j = \operatorname{clip} \left( \operatorname{sigmoid}(\log\alpha_j) (\zeta-\gamma)+\gamma, 0,1 \right) }

لاحظ أنها قد تكون كسرية أيضًا. أي أن deterministic gate لا تعني بالضرورة: 0 أو 10\text{ أو }1 قد تكون: 0.60.6 وهنا يجب أن نفرق منذ الآن بين ثلاثة أشياء: عينة التدريب العشوائية، والبوابة الحتمية للتقييم، والقرار الثنائي النهائي الذي سيزيل شيئًا من النموذج فعلًا.


جرّب بنفسك: اسحب بوابة Hard-Concrete

python

قد ينتج القص في النهاية صفرًا أو واحدًا بالضبط.

من وزن واحد إلى عربة كاملة: Group Sparsity

قنوات الخرجC_out = 5
بعد إعادة البناءC_out = 5
c1
c2
c3
c4
c5
القنوات المحتفظ بها5 / 5
مرشحات الطبقةC_out 5 → 5
مدخلات الطبقة التاليةC_in 5 → 5

الشكل 4: تحتاج القناة المحذوفة إلى إعادة بناء الموترات المتصلة بها فعليًا لتحقيق مكسب في السرعة.

حتى الآن كنا نتحدث وكأن لكل وزن بوابة خاصة به، لكن لويزو يسمح أيضًا أن تشترك مجموعة كاملة في بوابة واحدة.

وهنا نصل إلى السؤال الذي تركناه من بداية الرحلة: كيف يمكن أن يصل الأمر إلى إزالة Channel كامل وليس وزنًا واحدًا؟

لو وضعنا بوابة واحدة أمام مجموعة من الأوزان، فإن: zg=0z_g=0

لا يغلق وزنًا منفردًا، بل يغلق المجموعة كلها.

في convolutional neural network يمكن أن تكون المجموعة هي output feature map كامل.

أي أن كل Channel له بوابة واحدة، وهذه البوابة تُضرب في كامل خريطة الخصائص: h~j=zjhj\tilde h_j=z_jh_j إذا كان: zj=0z_j=0

تختفي خريطة الـ feature كلها، وليس بكسلًا واحدًا ولا وزنًا واحدًا.

وهنا أصبحت تذكرة المفتش لا تخص راكبًا، بل عربة كاملة من القطار. إن أُغلقت بوابة العربة، كل ما بداخلها يخرج من الرحلة.


لكن ماذا نعد؟

لو جمعنا فقط: ∑gP(zg>0)\sum_g P(z_g>0) فنحن نعد العدد المتوقع للمجموعات أو الـ channels النشطة.

لكن هذا ليس بالضرورة نفس عدد الـ parameters، لأن Channel قد يحتوي على عدد من الأوزان يختلف عن Channel آخر.

إذا كانت المجموعة GgG_g تحتوي على ∣Gg∣|G_g| وزنًا، فإن العدد المتوقع للأوزان يكون: E∥θ∥0=∑g∣Gg∣ P(zg>0)\mathbb E\|\theta\|_0 = \sum_g |G_g|\,P(z_g>0) إذن يجب ألا نخلط بين: عدد الـ channels، وعدد الأوزان، و FLOPs، والسرعة الفعلية.

هذا الفرق مهم عندما نفكر في أثر الإزالة على التنفيذ.


جرّب بنفسك: احسب المجموعات والأوزان كلًا على حدة

python

المتوسط المتوقع 1.05 مجموعة، لكنه 5.8 وزنًا لاختلاف أحجام المجموعات.

كيف تبدو دورة التدريب عند لويزو؟

الآن يمكننا أن نرى الرحلة كاملة في خطوة تدريب واحدة: أولًا نأخذ noise للبوابات. ثم نحوله عبر Hard-Concrete إلى zz. ثم نضرب الأوزان في البوابات: θ=θ~⊙z\theta=\tilde\theta\odot z

ثم نجري الـ forward pass ونحسب prediction loss.

بعدها نحسب عقوبة النشاط المتوقعة من احتمالات البوابات: λ∑jP(zj>0)\lambda\sum_jP(z_j>0)

ثم نجمع الطرفين، ويعود الـ backpropagation من الخسارة خلال الطريق الذي صنعناه بالـ reparameterization، ويحدّث أوزان الشبكة ومعاملات البوابات معًا.

إذن لويزو لم يكتشف مسبقًا من يستحق التذكرة. بل جعل التنبؤ وعقوبة التعقيد يتجادلان أثناء التدريب حتى تتحرك معاملات البوابات إلى أماكن تجعل بعض الأجزاء أكثر احتمالًا للبقاء وأجزاء أخرى أكثر احتمالًا للإغلاق.


وهنا يجب أن نوقف القطار لحظة

من السهل جدًا بعد كل هذا أن نقول: إذن Gaussian gate التي سنستخدمها بعد قليل هي نفسها طريقة لويزو.

لكن هذا غير صحيح.

لويزو أعطانا الإطار العام لفكرة L0L_0 بالبوابات المستمرة المقصوصة، لكنه اختار في تطبيقه الأساسي Hard-Concrete.

أما Gaussian stochastic gate فله مصدر مباشر آخر سنصل إليه الآن: يامادا وزملاؤه.


من Hard-Concrete إلى Gaussian: نفس الهيكل وأب مختلف

الفكرة العامة التي أخذناها من لويزو هي:

continuous sample→clip→exact zero possible\boxed{ \text{continuous sample} \rightarrow \text{clip} \rightarrow \text{exact zero possible} }

وإلى جانب ذلك نحسب احتمال أن تكون البوابة نشطة من الـ CDF الخاص بالتوزيع الأب.

Hard-Concrete اختار بناءً يعتمد على Logistic noise و sigmoid.

يامادا قال: يمكننا أن نفعل نفس الفكرة بمتغير Gaussian أبسط.


يامادا وزملاؤه: Gaussian Stochastic Gates

في عمل ⁦(Yamada et al., 2020)⁩ لكل feature بوابة stochastic خاصة به. الصيغة الأصلية يمكن كتابتها:

zd=clip⁡(md+ηd,0,1)\boxed{ z_d= \operatorname{clip}(m_d+\eta_d,0,1) }
ηd∼N(0,σ2)\eta_d\sim\mathcal N(0,\sigma^2)

وهي نفسها إذا استخدمنا reparameterization: ϵd∼N(0,1)\epsilon_d\sim\mathcal N(0,1)

sd=md+σϵd\boxed{ s_d=m_d+\sigma\epsilon_d }
zd=clip⁡(sd,0,1)\boxed{ z_d=\operatorname{clip}(s_d,0,1) }

هنا mdm_d هو المعامل الذي نتعلمه، و σ\sigma هو مقدار الضوضاء. في بناء يامادا يكون مقدار الضوضاء ثابتًا، بينما نتعلم الموقع mdm_d.


ما وظيفة mdm_d؟

تخيل منحنى Gaussian يتحرك على خط الأعداد.

إذا دفعنا mdm_d ناحية اليمين، أصبح جزء أكبر من التوزيع فوق الصفر، وبالتالي ترتفع فرصة أن تكون البوابة مفتوحة.

إذا دفعناه ناحية اليسار، ينتقل جزء أكبر من التوزيع تحت الصفر، وبعد الـ clipping يتحول هذا الجزء إلى صفر.

إذن mdm_d هو المقبض الذي يقرر تدريجيًا إن كان الـ feature يستحق البقاء.


احتمال النشاط في Gaussian gate

s ∼ 𝒩(m, σ²)σ = 0.50P(z > 0) = Φ(m/σ) = 78.8%
−3−1.501.53s

الشكل 5: هذا احتمال طويل الأمد لبوابة غير صفرية، وليس قيمة عينة واحدة.

البوابة فعالة عندما: zd>0z_d>0 وبما أن الـ clipping يحول فقط القيم التي كانت sd≤0s_d\le0 إلى صفر، فإن: zd>0  ⟺  sd>0z_d>0 \iff s_d>0 لكن: sd=md+σϵds_d=m_d+\sigma\epsilon_d إذن: P(zd>0)=P(md+σϵd>0)P(z_d>0) = P(m_d+\sigma\epsilon_d>0) ننقل mdm_d:

P(ϵd>−mdσ)P\left( \epsilon_d>-\frac{m_d}{\sigma} \right)

وباستخدام تماثل التوزيع الطبيعي نحصل على ⁦(Yamada et al., 2020)⁩:

P(zd>0)=Φ(mdσ)\boxed{ P(z_d>0) = \Phi\left(\frac{m_d}{\sigma}\right) }

حيث Φ\Phi هي CDF للتوزيع الطبيعي القياسي.

أي أنها تجيب ببساطة: ما مساحة منحنى الـ Gaussian الموجودة إلى يسار قيمة معينة؟


مثال

إذا كان: md=0.4,σ=0.5m_d=0.4,\qquad \sigma=0.5 فإن:

mdσ=0.8\frac{m_d}{\sigma}=0.8

ومن ثم: P(zd>0)=Φ(0.8)≈0.79P(z_d>0)=\Phi(0.8)\approx0.79 أي أن البوابة ستكون غير صفرية في نحو 79%79\% من العينات على المدى الطويل.

مرة أخرى: 0.790.79 ليست قيمة البوابة نفسها. هي احتمال أن تكون البوابة أكبر من صفر.


عقوبة L0L_0 عند يامادا

بدل أن نجمع πj\pi_j كما فعلنا مع Bernoulli، أو صيغة Hard-Concrete الخاصة، نجمع الآن:

∑dΦ(mdσ)\boxed{ \sum_d \Phi\left(\frac{m_d}{\sigma}\right) }

وهذا يعطينا العدد المتوقع للبوابات النشطة. فتصبح الفكرة مرة أخرى:

prediction loss+λ∑dΦ(mdσ)\text{prediction loss} + \lambda \sum_d \Phi\left(\frac{m_d}{\sigma}\right)

عقوبة الـ L0L_0 تدفع mdm_d إلى اليسار لتقل احتمالية النشاط، وخسارة التنبؤ تدفع البوابات المهمة في الاتجاه المعاكس.


جرّب بنفسك: قارن احتمال البوابة الغاوسية بالمحاكاة

python

تقترب المحاكاة من Φ(m/σ)\Phi(m/\sigma) كلما زاد عدد السحبات.

هل يامادا كان يحذف Channels؟

لا في الورقة الأصلية. وهذه نقطة يجب أن نحافظ عليها.

يامادا استخدم البوابة أساسًا كـ feature-selection gate عند مدخل الشبكة: كل input feature له بوابته.

استخدمت الورقة الأصلية Gaussian gates لاختيار الخصائص عند مدخل الشبكة. أما استخدام بوابة مشابهة لاتخاذ قرارات تخص مجموعات كاملة، فسنتركه لجزء لاحق من هذه الرحلة.


لماذا Gaussian بدل Hard-Concrete؟

يامادا قدّم Gaussian stochastic gates كبديل للتوزيعات المبنية على Logistic noise، وذكر في تجاربه تحسنًا في استقرار اختيار الـ features مقارنة بـ Hard-Concrete في سياقه التجريبي.

لكن لا نقفز من هذه الجملة إلى:

Gaussian أفضل دائمًا من Hard-Concrete.

هذا غير ما تثبته الورقة.

الأصح أن نقول: هما طريقتان مختلفتان لبناء نفس الفكرة العامة للبوابة المستمرة المقصوصة، ويامادا أعطى Gaussian gate دعمًا مباشرًا في feature selection.


Hard-Concrete و Gaussian جنبًا إلى جنب

الهيكل المشترك:

noise→continuous sample→clip→z∈[0,1]\text{noise} \rightarrow \text{continuous sample} \rightarrow \text{clip} \rightarrow z\in[0,1]

وفي الطريقتين نستطيع الوصول إلى صفر حقيقي بعد الـ clipping، ونستطيع حساب احتمال النشاط وتحويله إلى عقوبة L0L_0.

الاختلاف في التوزيع الذي يولد العينة وفي صيغة احتمال النشاط.

Hard-Concrete:

P(zj>0)=sigmoid⁡(log⁡αj−βlog⁡−γζ)P(z_j>0) = \operatorname{sigmoid} \left( \log\alpha_j - \beta\log\frac{-\gamma}{\zeta} \right)

Gaussian:

P(zj>0)=Φ(mjσ)P(z_j>0) = \Phi\left(\frac{m_j}{\sigma}\right)

إذن المفتش لم يغير وظيفته. الذي تغير هو الآلة التي تولد له احتمالات فتح البوابات.


تلميح لأحداث مستقبلية

في جزء لاحق من هذه الرحلة، سنسأل ماذا يتغير عندما يخص القرار مجموعة كاملة بدلًا من راكب واحد. وسننظر في الوقت نفسه إلى الفرق بين جعل المكوّن غير نشط وإزالة العمليات الحسابية التي يحتاج إليها النموذج فعلًا.

احتفظ بهذا السؤال معنا: عندما تشترك مجموعة كاملة في قرار واحد، ما الذي نعدّه تذكرة، وماذا يعني أن تغادر المجموعة القطار؟


عودة إلى المفتش

في بداية القصة لم يكن مفتشنا يعرف سوى عدّ الركاب: موجود أو غير موجود. ثم اكتشف أن العد وحده لا يخبره من يستحق التذكرة.

فصلنا الوزن عن قرار وجوده، ثم جعلنا القرار احتماليًا. وبعدها أعطيناه طريقًا مستمرًا عبر Reparameterization؛ فبنى Louizos لهذا الطريق Hard-Concrete، واستخدم يامادا طريقًا Gaussian.

ويبقى سؤال المفتش الأساسي:

كيف نحافظ على توقع جيد، لكن بعدد أقل من المكونات التي تستحق فعلًا أن تبقى؟

المراجع

Louizos, C., Welling, M., & Kingma, D. P. (2018). Learning sparse neural networks through L0L_0 regularization. في Proceedings of the International Conference on Learning Representations. النص الكامل.

Maddison, C. J., Mnih, A., & Teh, Y. W. (2017). The Concrete distribution: A continuous relaxation of discrete random variables. في Proceedings of the International Conference on Learning Representations. الورقة.

Oliveira, F. D. R., Batista, E. L. O., & Seara, R. (2024). On the compression of neural networks using ℓ0\ell_0-norm regularization and weight pruning. Neural Networks, 171, 343–352. https://doi.org/10.1016/j.neunet.2023.12.019

Yamada, Y., Lindenbaum, O., Negahban, S., & Kluger, Y. (2020). Feature selection using stochastic gates. في Proceedings of the 37th International Conference on Machine Learning (المجلد 119، ص ص. 10648–10659). الورقة وسجل المؤتمر.

اقرأ المزيد