نرمال‌سازی (یادگیری ماشین)

در یادگیری ماشین، **نرمال‌سازی** یک تکنیک آماری با کاربردهای گوناگون است. نرمال‌سازی دو شکل اصلی دارد، یعنی *نرمال‌سازی داده* و *نرمال‌سازی فعال‌سازی*. نرمال‌سازی داده (یا تغییر مقیاس ویژگی) شامل روش‌هایی است که داده‌های ورودی را به‌گونه‌ای بازمقیاس می‌کنند که ویژگی‌ها دارای بازه، میانگین، واریانس یا دیگر خواص آماری یکسان بشوند. برای مثال، یکی از روش‌های پرکاربرد تغییر مقیاس ویژگی، نرمال‌سازی کمینه-بیشینه است که در آن هر ویژگی طوری تغییر داده می‌شود که دارای بازه یکسان (معمولاً [۰، ۱] یا [-۱، ۱]) باشد. این کار مشکل تفاوت بسیار زیاد مقیاس بین ویژگی‌های مختلف را حل می‌کند. برای نمونه فرض کنیم که یک ویژگی بر حسب کیلومتر و ویژگی دیگر بر حسب نانومتر اندازه‌گیری شده باشد.

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

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

* افزایش سرعت همگرایی آموزش،
* کاهش حساسیت به تغییرات و مقیاس ویژگی‌ها در داده‌های ورودی،
* کاهش بیش‌برازش،
* ایجاد تعمیم بهتر مدل به داده‌های دیده‌نشده.

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

## نرمال‌سازی دسته‌ای
مقالهٔ اصلی: نرمال‌سازی دسته‌ای

**نرمال‌سازی دسته‌ای**  به جای اعمال نرمال‌سازی بر روی تمامی ورودی‌ها، روی فعال‌سازی‌های یک لایه برای هر ریز-دسته***' عمل می‌کند.

یک شبکه پیش‌خور ساده را در نظر بگیرید که با زنجیره کردن ماژول‌ها تعریف شده است:<math display="block">x^{(0)} \mapsto x^{(1)} \mapsto x^{(2)} \mapsto \cdots</math>که در آن هر ماژول شبکه می‌تواند یک تبدیل خطی، یک تابع فعال‌سازی غیرخطی، یک هم‌نهشتی و غیره باشد. <math>x^{(0)}</math> بردار ورودی، <math>x^{(1)}</math> بردار خروجی از ماژول اول، و به همین ترتیب است.

بَچ‌نُرم یک ماژول است که می‌تواند در هر نقطه‌ای از شبکه پیش‌خور درج شود. برای مثال، اگر درست پس از <math>x^{(l)}</math> در میانه زنجره قرار داده شود، آنگاه شبکه به صورت زیر عمل می‌کند:<math display="block">\cdots \mapsto x^{(l)} \mapsto \mathrm{BN}(x^{(l)}) \mapsto x^{(l+1)} \mapsto \cdots</math>ماژول بَچ‌نُرم روی تمامی ورودی‌های به طور یکجا عمل نمی‌کند، بلکه باید هر بار روی یک دسته از ورودی‌ها اعمال شود و به همه دسته‌ها به طور همزمان نگاه نمی‌کنیم.

به بیان دقیق‌تر، فرض کنید یک دسته از ورودی‌های <math>x^{(0)}_{(1)}, x^{(0)}_{(2)}, \dots, x^{(0)}_{(B)}</math> را به طور هم‌زمان به شبکه وارد می‌کنیم. در میانه شبکه نیز، بردارهایی به صورت زیر وجود خواهد داشت:<math display="block">x^{(l)}_{(1)}, x^{(l)}_{(2)}, \dots, x^{(l)}_{(B)}</math>ماژول بَچ‌نُرم، میانگین و واریانس هر دسته از بردارها را محاسبه می‌کند:<math display="block">\begin{aligned}
\mu^{(l)}_i &= \frac 1B \sum_{b=1}^B x^{(l)}_{(b), i} \\
(\sigma^{(l)}_i)^2 &= \frac{1}{B} \sum_{b=1}^B (x_{(b),i}^{(l)} - \mu_i^{(l)})^2
\end{aligned}</math>که در آن <math>B</math> تعداد ورودی‌ها (بردارها) در دسته فعلی، <math>i</math> اندیس مؤلفه‌ها در هر بردار (ویژگی) و <math>b</math> اندیس یا نشانگر هر بردار در داخل دسته (بَچ) است. به بیان دیگر، در فرمول بالا مؤلفه <math>i</math>-ام (ویژگی <math>i</math>-ام) هر بردار در دسته در نظر گرفته می‌شود و میانگین و واریانس این مقادیر محاسبه می‌گردد.

سپس هر مؤلفه طوری نرمال‌سازی می‌شود که میانگین صفر و واریانس یک داشته باشد:<math display="block">\hat{x}^{(l)}{(b), i} = \frac{x^{(l)}{(b), i} - \mu^{(l)}_i}{\sqrt{(\sigma^{(l)}_i)^2 + \epsilon}}</math>در این‌جا <math>\epsilon</math> یک ثابت مثبت کوچک مانند <math>10^{-9}</math> است که برای پایداری عددی به واریانس افزوده می‌شود تا از [[تقسیم بر صفر]] جلوگیری شود.

در نهایت، یک تبدیل خطی اعمال می‌شود:<math display="block">y^{(l)}{(b), i} = \gamma_i \hat{x}^{(l)}{(b), i} + \beta_i</math>در این رابطه، <math>\gamma</math> و <math>\beta</math> پارامترهای درون ماژول بَچ‌نُرم هستند. این پارامترها قابل یادگیری‌اند و معمولاً با استفاده از [[گرادیان کاهشی]] آموزش داده می‌شوند.

در ادامه، یک پیاده‌سازی [[پایتون (زبان برنامه‌نویسی)|پایتون]] از بَچ‌نُرم آورده شده است:<syntaxhighlight lang="python3">
import numpy as np

def batchnorm(x, gamma, beta, epsilon=1e-9):
    # Mean and variance of each feature
    mu = np.mean(x, axis=0)  # shape (N,)
    var = np.var(x, axis=0)  # shape (N,)

    # Normalize the activations
    x_hat = (x - mu) / np.sqrt(var + epsilon)  # shape (B, N)

    # Apply the linear transform
    y = gamma * x_hat + beta  # shape (B, N)

    return y
</syntaxhighlight>

=== تفسیر ===
شبکه به مرور یاد میگیرد که در صورت نیاز با استفاده از پارامترهای <math>\gamma</math> و <math>\beta</math> نرمال‌سازی را «خنثی» کند. بَچ‌نُرم را می‌توان اینگونه تفسیر کرد: در مسیر آموزش، بَچ‌نُرم روشی است که بار عملکرد صرفاً خطی را به دوش می‌کشد، تا لایه‌ها فقط بر مدل‌سازی جنبه‌های غیرخطی داده تمرکز کنند. این موضوع می‌تواند مفید باشد، زیرا همواره به سادگی می‌توان یک لایه تبدیل خطی بعد از لایه‌های شبکه عصبی اضافه کرد.

در مقاله اصلی ادعا شده است که عملکرد بَچ‌نُرم، کاهش لغزش کوواریانس (هم‌پراکندگی) درونی است، هرچند این ادعا هم طرفداران  و هم منتقدانی دارد.


=== موارد خاص ===
مقاله اصلی توصیه می‌کند که بَچ‌نُرم فقط پس از یک تبدیل خطی استفاده شود و نه پس از یک فعال‌سازی غیرخطی. یعنی <math>\phi(\mathrm{BN}(Wx + b))</math> و نه <math>\mathrm{BN}(\phi(Wx + b))</math>. همچنین، جمله بایاس <math>b</math> اهمیتی ندارد، زیرا با کم کردن میانگین در مراحل بعدی حذف می‌شود، بنابراین فرم کلی به صورت <math>\mathrm{BN}(Wx)</math> خواهد بود. یعنی اگر بَچ‌نُرم پیش از یک تبدیل خطی قرار گیرد، جمله بایاس آن تبدیل خطی صفر در نظر گرفته می‌شود.

برای [[شبکه عصبی پیچشی|شبکه‌های عصبی پیچشی]] ، بَچ‌نُرم باید [[اصل ناوردایی|ناوردایی]] نسبت به تبدیل را حفظ کند. به این معنا که باید تمام خروجی‌های یک [[هسته (پردازش تصویر)|هسته]] یکسان را به عنوان نقاط داده متفاوتی درون یک دسته در نظر بگیرد. به این حالت گاهی نرمال‌سازی دسته‌ای مکانی***'، بَچ‌نُرم2D***' یا بَچ‌نُرم به‌ازای هر کانال***' گفته می‌شود.

به‌طور مشخص، فرض کنید یک لایه کانولوشنی دوبعدی به صورت زیر تعریف شده باشد:

x^{(l)}_{h, w, c} = \sum_{h', w', c'} K^{(l)}_{h'-h, w'-w, c, c'} x_{h', w', c'}^{(l-1)} + b^{(l)}_cکه در آن:

* x^{(l)}_{h, w, c} فعال‌سازی نورون در موقعیت (h, w) در کانال c-ام از لایه l-ام است.

* K^{(l)}_{\Delta h, \Delta w, c, c'} یک تنسور کرنل است. هر کانال c متناظر با یک کرنل K^{(l)}{h'-h, w'-w, c, c'} با اندیس‌های \Delta h, \Delta w, c' است.

* b^{(l)}_c جمله بایاس برای کانال c-ام از لایه l-ام است.

برای حفظ ناوردایی انتقالی، بَچ‌نُرم تمام خروجی‌های حاصل از یک کرنل یکسان در یک دسته را به عنوان داده‌های بیشتری در همان دسته در نظر می‌گیرد. به عبارت دیگر، این نرمال‌سازی برای هر «کرنل» c (یا به‌طور معادل، برای هر کانال c) تنها یک مرتبه اعمال می‌شود، نه برای هر «فعال‌سازی» x^{(l+1)}_{h, w, c} به صورت جداگانه:


\begin{aligned}
\mu^{(l)}_c &= \frac{1}{BHW} \sum_{b=1}^B \sum_{h=1}^H \sum_{w=1}^W x^{(l)}_{(b), h, w, c} \\
(\sigma^{(l)}_c)^2 &= \frac{1}{BHW} \sum_{b=1}^B \sum_{h=1}^H \sum_{w=1}^W (x_{(b), h, w, c}^{(l)} - \mu_c^{(l)})^2
\end{aligned}


که در آن B اندازه دسته، H ارتفاع نگاشت ویژگی و W عرض نگاشت ویژگی است.

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

در ادامه، نرمال‌سازی و تبدیل خطی نیز به صورت «به‌ازای هر کرنل» انجام می‌شود:


\begin{aligned}
\hat{x}^{(l)}_{(b), h, w, c} &= \frac{x^{(l)}_{(b), h, w, c} - \mu^{(l)}_c}{\sqrt{(\sigma^{(l)}_c)^2 + \epsilon}} \\
y^{(l)}_{(b), h, w, c} &= \gamma_c \hat{x}^{(l)}_{(b), h, w, c} + \beta_c
\end{aligned}


ملاحظات مشابهی برای نرمال‌سازی دسته‌ای در کانولوشن‌های با بعد n نیز برقرار است.

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


```python3
import numpy as np

def batchnorm_cnn(x, gamma, beta, epsilon=1e-9):
    # Calculate the mean and variance for each channel.
    mean = np.mean(x, axis=(0, 1, 2), keepdims=True)
    var = np.var(x, axis=(0, 1, 2), keepdims=True)

    # Normalize the input tensor.
    x_hat = (x - mean) / np.sqrt(var + epsilon)

    # Scale and shift the normalized tensor.
    y = gamma * x_hat + beta

    return y
```


برای شبکه‌های عصبی بازگشتی  چندلایه، نرمال‌سازی دسته‌ای معمولاً فقط برای بخش *ورودی به حالت پنهان* اعمال می‌شود و نه برای بخش *حالت پنهان به حالت پنهان*. فرض کنید حالت پنهان لایه l-ام در زمان t برابر h_t^{(l)} باشد. شبکه عصبی بازگشتی استاندارد، بدون نرمال‌سازی، رابطه زیر را ارضا می‌کند:h^{(l)}t = \phi(W^{(l)} h_t^{l-1} + U^{(l)} h{t-1}^{l} + b^{(l)}) که در آن W^{(l)}, U^{(l)}, b^{(l)} به‌ترتیب وزن‌ها و بایاس‌ها هستند و \phi تابع فعال‌سازی است. با اعمال نرمال‌سازی دسته‌ای، این رابطه به شکل زیر در می‌آید:h^{(l)}t = \phi(\mathrm{BN}(W^{(l)} h_t^{l-1}) + U^{(l)} h{t-1}^{l}) دو روش ممکن برای تعریف «دسته» در نرمال‌سازی دسته‌ای برای آراِن‌اِن‌ها وجود دارد: «فریم‌به‌فریم» و «دنباله‌محور». به‌طور مشخص، پردازش یک دسته از جمله‌ها توسط یک آراِن‌اِن را در نظر بگیرید. فرض کنید h_{b, t}^{(l)} حالت پنهان لایه l-ام برای توکن t-ام از جمله ورودی b-ام باشد. در این صورت، نرمال‌سازی دسته‌ای فریم‌به‌فریم به معنای نرمال‌سازی روی b است: \begin{aligned} \mu_t^{(l)} &= \frac{1}{B} \sum_{b=1}^B h_{i,t}^{(l)} \\ (\sigma_t^{(l)})^2 &= \frac{1}{B} \sum_{b=1}^B  (h_t^{(l)} - \mu_t^{(l)})^2 \end{aligned} و نرمال‌سازی دنباله‌محور به معنای نرمال‌سازی روی (b, t) است: \begin{aligned} \mu^{(l)} &= \frac{1}{BT} \sum_{b=1}^B\sum_{t=1}^T h_{i,t}^{(l)} \\ (\sigma^{(l)})^2 &= \frac{1}{BT} \sum_{b=1}^B\sum_{t=1}^T (h_t^{(l)} - \mu^{(l)})^2 \end{aligned} نرمال‌سازی دسته‌ای فریم‌به‌فریم برای وظایف علّی مانند پیش‌بینی نویسه بعدی مناسب است، جایی که فریم‌های آینده در دسترس نیستند و این موضوع نرمال‌سازی به ازای هر فریم را الزامی می‌کند. نرمال‌سازی دسته‌ای دنباله‌محور برای وظایفی مانند بازشناسی گفتار مناسب است، که در آن کل دنباله‌ها در دسترس هستند، اما طول‌های متغیر دارند. در یک دسته، دنباله‌های کوتاه‌تر با صفر پُر می‌شوند تا با طول بلندترین دنباله دسته یکسان شوند. در چنین تنظیماتی، روش فریم‌به‌فریم توصیه نمی‌شود، زیرا تعداد فریم‌های بدون پَدشدگی در امتداد محور زمان کاهش می‌یابد و این امر به برآوردهای آماری هرچه ضعیف‌تر منجر می‌شود.

همچنین امکان اعمال نرمال‌سازی دسته‌ای بر حافظه‌های طولانی کوتاه مدت  نیز وجود دارد.

### بهبودها
تاکنون نرمال‌سازی دسته‌ای (بَچ‌نُرم) بسیار محبوب بوده است و تلاش‌های متعددی برای بهبود آن انجام شده است. برخی از این نمونه‌ها عبارت‌اند از:

* بچینگ شبح‌گونه***': تقسیم تصادفی یک دسته به زیردسته‌ها و اعمال نرمال‌سازی دسته‌ای به صورت جداگانه روی هر زیردسته
* افت وزن***' روی \gamma و \beta؛
* و ترکیب نرمال‌سازی دسته‌ای با نرمال‌سازی گروهی.

یکی از مشکلات خاص نرمال‌سازی دسته‌ای این است که در طول آموزش، میانگین و واریانس برای هر دسته به صورت برخط محاسبه می‌شوند (معمولاً بصورت یک میانگین متحرک نمایی)، اما در مرحله استنتاج، میانگین و واریانس روی مقادیری که در طول آموزش محاسبه شده‌اند ثابت (فریز) می‌شوند. این نابرابری میان آموزش و آزمون باعث افت عملکرد می‌شود. این نابرابری را می‌توان با شبیه‌سازی میانگین متحرک در زمان استنتاج کاهش داد: \begin{aligned} \mu &= \alpha E[x] + (1 - \alpha) \mu_{x, \text{ train}} \\ \sigma^2 &= (\alpha E[x]^2 + (1 - \alpha) \mu_{x^2, \text{ train}}) - \mu^2 \end{aligned} که در آن \alpha یک ابرپارامتر است که باید روی یک مجموعه اعتبارسنجی بهینه‌سازی شود.

راهکارهای دیگر تلاش می‌کنند نرمال‌سازی دسته‌ای را به‌طور کامل حذف کنند، مانند رزنت بدون نرمال‌ساز.

## نرمال‌سازی لایه‌ای
**نرمال‌سازی لایه‌ای**  یک جایگزین پرکاربرد برای نرمال‌سازی دسته‌ای (بَچ‌نُرم) است. برخلاف بَچ‌نُرم که فعال‌سازی‌ها را در امتداد بُعد دسته برای یک ویژگی معین نرمال‌سازی می‌کند، لِیرنُرم، نرمال‌سازی را راستای تمام ویژگی‌ها درون یک نمونه داده (ورودی) منفرد انجام می‌دهد نه ما بین ورودی‌ها. در مقایسه با بَچ‌نُرم، عملکرد لِیرنُرم تحت تأثیر اندازه دسته قرار نمی‌گیرد. این روش یکی از اجزای کلیدی مدل‌های ترنسفورمر به‌شمار می‌رود.

برای یک ورودی داده و یک لایه معین، لِیرنُرم میانگین \mu و واریانس \sigma^2 را بر روی تمام نورون‌های آن لایه محاسبه می‌کند. مشابه بَچ‌نُرم، پارامترهای قابل یادگیری \gamma (مقیاس) و \beta (انتقال) اعمال می‌شوند. این نرمال‌سازی به صورت زیر تعریف می‌شود:\hat{x_i} = \frac{x_i - \mu}{\sqrt{\sigma^2 + \epsilon}}, \quad y_i = \gamma_i \hat{x_i} + \beta_iکه در آن:\mu = \frac 1D \sum_{i=1}^D x_i, \quad \sigma^2 = \frac 1D \sum_{i=1}^D (x_i - \mu)^2و اندیس i بر روی نورون‌های موجود در آن لایه تغییر می‌کند.

### مثال‌ها
برای مثال، در شبکه‌های عصبی کانولوشنی ، نرمال‌سازی لایه‌ای بر روی تمام فعال‌سازی‌های یک لایه اعمال می‌شود. با توجه به نمادگذاری پیشین، خواهیم داشت: \begin{aligned} \mu^{(l)} &= \frac{1}{HWC} \sum_{h=1}^H \sum_{w=1}^W\sum_{c=1}^C x^{(l)}_{h, w, c} \\ (\sigma^{(l)})^2 &= \frac{1}{HWC} \sum_{h=1}^H \sum_{w=1}^W\sum_{c=1}^C (x_{h, w, c}^{(l)} - \mu^{(l)})^2 \\ \hat{x}^{(l)}_{h,w,c} &= \frac{\hat{x}^{(l)}_{h,w,c} - \mu^{(l)}}{\sqrt{(\sigma^{(l)})^2 + \epsilon}} \\ y^{(l)}_{h,w,c} &= \gamma^{(l)} \hat{x}^{(l)}_{h,w,c} + \beta^{(l)} \end{aligned} توجه کنید که اندیس دسته b حذف شده است، در حالی که اندیس کانال c اضافه شده است.

در شبکه‌های عصبی بازگشتی و ترنسفورمرها، نرمال‌سازی لایه‌ای به صورت مجزا برای هر گام زمانی اعمال می‌شود. برای مثال، اگر بردار پنهان در یک شبکه عصبی بازگشتی در گام زمانی t برابر با x^{(t)} \in \mathbb{R}^{D} باشد، که در آن D بُعد بردار پنهان است، آنگاه لِیرنُرم به صورت زیر اعمال می‌شود:\hat{x_{i}}^{(t)} = \frac{x_i^{(t)} - \mu^{(t)}}{\sqrt{(\sigma^{(t)})^2 + \epsilon}}, \quad y_i^{(t)} = \gamma_i \hat{x_i}^{(t)} + \beta_iکه در آن:\mu^{(t)} = \frac 1D \sum_{i=1}^D x_i^{(t)}, \quad (\sigma^{(t)})^2 = \frac 1D \sum_{i=1}^D (x_i^{(t)} - \mu^{(t)})^2

### نرمال‌سازی لایه‌ای با میانگین مربعات ریشه‌ای
**نرمال‌سازی لایه‌ای با میانگین مربعات ریشه‌ای** : \hat{x_i} = \frac{x_i}{\sqrt{\frac 1D \sum_{i=1}^D x_i^2}}, \quad y_i = \gamma \hat{x_i} + \beta در اصل، این روش نوعی لِیرنُرم است که در آن \mu و \epsilon برابر با صفر در نظر گرفته می‌شوند. به این روش همچنین **نرمال‌سازی L2** نیز گفته می‌شود. این حالت یک مورد خاص از **نرمال‌سازی Lp** یا **نرمال‌سازی توانی** است: \hat{x_i} = \frac{x_i}{\left(\frac 1D \sum_{i=1}^D |x_i|^p \right)^{1/p}}, \quad y_i = \gamma \hat{x_i} + \beta که در آن p > 0 یک ثابت است.

### نرمال‌سازی لایه‌ای تطبیقی
**نرمال‌سازی لایه‌ای تطبیقی**  مقادیر \gamma و \beta را در لِیرنُرم نه از روی فعال‌سازی‌های خود لایه، بلکه از داده‌های دیگر محاسبه می‌کند. این روش نخستین بار برای شبکه‌های عصبی کانولوشنی پیشنهاد شد، و به طور مؤثری در ترنسفورمرهای مبتنی بر مدل‌های انتشاری  به کار رفته است. برای مثال، در یک DiT، اطلاعات شرطی (مانند یک بردار کدگذاری متن) توسط یک پرسپترون چندلایه به مقادیر \gamma و \beta تبدیل می‌شود و سپس این مقادیر در ماژول لِیرنُرم یک ترنسفورمر اعمال می‌گردند.

## نرمال‌سازی وزنی
**نرمال‌سازی وزنی**  روشی است الهام‌گرفته از نرمال‌سازی دسته‌ای که به جای نرمال‌سازی فعال‌سازی‌ها، ماتریس‌های وزن را در یک شبکه عصبی نرمال‌سازی می‌کند.

یکی نمونه از این موارد **نرمال‌سازی طیفی** است که ماتریس‌های وزن را بر نُرم طیفی آن‌ها تقسیم می‌کند. نرمال‌سازی طیفی در شبکه‌های مولد تخاصمی‌  مانند شبکه مولد تخاصمی واسرشتاین مورد استفاده قرار می‌گیرد. شعاع طیفی را می‌توان به صورت کارآمد با الگوریتم زیر محاسبه کرد:

**INPUT** matrix W and initial guess x
Iterate x \mapsto \frac{1}{\|Wx\|_2}Wx to convergence x^*. This is the eigenvector of W with eigenvalue \|W\|_s.
**RETURN** x^*, \|Wx^*\|_2

با بازانتسابW_i \leftarrow \frac{W_i}{\|W_i\|_s} پس از هر به‌روزرسانی متمایزکننده***'، می‌توان کران بالایی <math>\|W_i\|_s \leq 1</math> و در نتیجه کران بالایی برای <math>\|D \|_L</math> را بدست آورد.

این الگوریتم را می‌توان با استفاده از [[به‌خاطرسپاری (رایانش)|به‌خاطرسپاری]]***' بیش از پیش تسریع کرد: در گام t، مقدار x^*_i(t) ذخیره می‌شود. سپس در گام t+1، از x^*_i(t)  به عنوان حدس اولیه الگوریتم استفاده می‌شود. از آنجا که W_i(t+1)  بسیار به W_i(t) نزدیک است، x^*_i(t) نیز به x^*_i(t+1) نزدیک خواهد بود و این امر امکان همگرایی سریع را فراهم می‌کند.

## نرمال‌سازی‌های ویژه [[شبکه عصبی پیچشی|شبکه‌های عصبی پیچشی]]
برخی از روش‌های نرمال‌سازی فعال‌سازی وجود دارند که فقط برای شبکه‌های عصبی پیچشی  به‌کار می‌روند.

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

b_{x, y}^i=\frac{a_{x, y}^i}{\left(k+\alpha \sum_{j=\max (0, i-n / 2)}^{\min (N-1, i+n / 2)}\left(a_{x, y}^j\right)^2\right)^\beta}

که در آن a_{x,y}^i فعال‌سازی نورون در مکان (x,y) و کانال i است. به‌عبارت دیگر، هر پیکسل در یک کانال تحت تأثیر (سرکوب) فعال‌سازی‌های همان پیکسل در کانال‌های مجاور خود قرار می‌گیرد.

پارامترهایk, n, \alpha, \beta ابرپارامترهایی هستند که با استفاده از یک مجموعه اعتبارسنجی انتخاب می‌شوند.

این روش گونه‌ای از روش قدیمی‌تر **نرمال‌سازی کنتراست محلی** بود.

b_{x, y}^i=\frac{a_{x, y}^i}{\left(k+\alpha \sum_{j=\max (0, i-n / 2)}^{\min (N-1, i+n / 2)}\left(a_{x, y}^j - \bar a_{x, y}^j\right)^2\right)^\beta}

که در آن \bar a_{x, y}^j میانگین فعال‌سازی در یک پنجره کوچکِ متمرکز بر مکان (x,y) و کانال i است. ابرپارامترهای k, n, \alpha, \beta و همچنین اندازه این پنجره کوچک، با استفاده از یک مجموعه اعتبارسنجی انتخاب می‌شوند.

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

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

نرمال‌سازی پاسخ بعدها در ConvNeXT-2 با عنوان **نرمال‌سازی پاسخ سراسری** دوباره مطرح شد.

### نرمال‌سازی گروهی
**نرمال‌سازی گروهی**  روشی است که آن هم صرفاً برای شبکه‌های عصبی کانولوشنی (سی‌ان‌ان‌ها) به‌کار می‌رود. این روش را می‌توان به صورت نرمال‌سازی لایه‌ای (لِیرنُرم) برای سی‌ان‌ان‌ها در نظر گرفت که به‌ازای هر گروه از کانال‌ها یک مرتبه اعمال می‌شود.

فرض کنید در یک لایه l، کانال‌هایی با اندیس‌های 1, 2, \dots, C وجود داشته باشند. این کانال‌ها به گروه‌هایی به صورت g_1, g_2, \dots, g_G تقسیم می‌شوند. سپس نرمال‌سازی لایه‌ای به‌طور جداگانه روی هر گروه اعمال می‌شود.

### نرمال‌سازی نمونه‌ای
**نرمال‌سازی نمونه‌ای**  یا **نرمال‌سازی کنتراست**، روشی است که نخستین بار برای انتقال سبک با شبکه‌های عصبی توسعه داده شد و آن نیز فقط برای سی‌ان‌ان‌ها استفاده می‌شود. این روش را می‌توان به صورت نرمال‌سازی لایه‌ای برای سی‌ان‌ان‌ها در نظر گرفت که به‌ازای هر کانال یک‌بار اعمال می‌شود، یا به‌طور معادل، به عنوان نرمال‌سازی گروهی که در آن هر گروه تنها شامل یک کانال است:
\begin{aligned}
\mu^{(l)}_c &= \frac{1}{HW} \sum_{h=1}^H \sum_{w=1}^Wx^{(l)}_{h, w, c} \\
(\sigma^{(l)}_c)^2 &= \frac{1}{HW}  \sum_{h=1}^H \sum_{w=1}^W (x_{h, w, c}^{(l)} - \mu^{(l)}_c)^2 \\
\hat{x}^{(l)}_{h,w,c} &= \frac{\hat{x}^{(l)}_{h,w,c} - \mu^{(l)}_c}{\sqrt{(\sigma^{(l)}_c)^2 + \epsilon}} \\
y^{(l)}_{h,w,c} &= \gamma^{(l)}_c \hat{x}^{(l)}_{h,w,c}  + \beta^{(l)}_c
\end{aligned} 


### نرمال‌سازی نمونه‌ای تطبیقی
**نرمال‌سازی نمونه‌ای تطبیقی**  گونه‌ای از نرمال‌سازی نمونه‌ای است که به‌طور ویژه برای انتقال سبک عصبی با استفاده از سی‌ان‌ان‌ها طراحی شده است، و نه صرفاً برای سی‌ان‌ان‌ها به‌طور کلی.

در روش انتقال سبک AdaIN، یک سی‌ان‌ان و دو تصویر ورودی در نظر گرفته می‌شود: یکی برای **محتوا** و دیگری برای **سبک**. هر دو تصویر از طریق همان سی‌ان‌ان پردازش می‌شوند و در یک لایه مشخص l، نرمال‌سازی نمونه‌ای تطبیقی اعمال می‌شود.

فرض کنید x^{(l), \text{ content}} فعال‌سازی مربوط به تصویر محتوا و x^{(l), \text{ style}} فعال‌سازی مربوط به تصویر سبک باشد. در این حالت، AdaIN ابتدا میانگین و واریانس فعال‌سازی‌های تصویر سبک x'^{(l)} را محاسبه می‌کند و سپس از آن‌ها به عنوان پارامترهای  \gamma, \beta برای نرمال‌سازی نمونه‌ای روی x^{(l), \text{ content}} استفاده می‌کند. توجه داشته باشید که خود x^{(l), \text{ style}} بدون تغییر باقی می‌ماند. به‌طور صریح، رابطه زیر برقرار است:

## ترنسفورمرها
برخی روش‌های نرمال‌سازی به‌طور ویژه برای استفاده در ترنسفورمرها طراحی شده‌اند.

ترنسفورمر اولیه سال ۲۰۱۷ از پیکربندی «post-LN» برای نرمال‌سازی لایه‌ای (لِیرنُرم) استفاده می‌کرد. آموزش این پیکربندی دشوار بود و به بهینه‌سازی ابرپارامتر دقیق و نیز یک مرحله «گرم‌کردن» در نرخ یادگیری نیاز داشت؛ به این صورت که نرخ یادگیری از مقدار کوچکی آغاز می‌شد و به تدریج افزایش می‌یافت. قرارداد «pre-LN» که چندین بار در سال ۲۰۱۸ پیشنهاد شد،برای آموزش آسان‌تر تشخیص داده شد، به گرم‌کردن نیاز نداشت و به همگرایی سریع‌تری منجر می‌شد.

**فیکس‌نُرم** و **اسکِیل‌نُرم** هر دو بردارهای فعال‌سازی را در یک ترنسفورمر نرمال‌سازی می‌کنند. روش فیکس‌نرم بردارهای *خروجی* ترنسفورمر را بر نُرم L2 آن‌ها تقسیم می‌کند و سپس در یک پارامتر یادگرفتنی g ضرب می‌نماید. روش اسکیل‌نرم تمام لِیرنُرم‌های درون ترنسفورمر را با تقسیم بر نُرم L2 جایگزین می‌کند و سپس نتیجه را در یک پارامتر یادگرفتنیg' ضرب می‌کند (که بین تمام ماژول‌های اسکیل‌نرم یک ترنسفورمر مشترک است). **نرمال‌سازی پرس‌وجو–کلید**  بردارهای پرس‌وجو و کلید را طوری نرمال‌سازی می‌کند که نُرم L2 واحد داشته باشند.

در **nGPT**، بسیاری از بردارها به‌گونه‌ای نرمال‌سازی می‌شوند که نُرم L2 واحد داشته باشند: از جمله بردارهای حالت پنهان، بردارهای تعبیه ورودی و خروجی، ستون‌های ماتریس وزن، و بردارهای پرس‌وجو و کلید.

## متفرقه
* **نرمال‌سازی گرادیان**  بردارهای گرادیان را در طول پس‌انتشار نرمال‌سازی می‌کند.

## جستارهای وابسته

* پیش-پردازش داده
* مقیاس‌بندی ویژگی‌ها

## یادداشت‌ها


## مراجع


رده:شبکه‌های عصبی
رده:مقاله‌های دارای کد نمونه به زبان پایتون
رده:یادگیری عمیق
رده:یادگیری ماشین
رده:تبدیل داده‌های آماری