Масштабування й нормалізація

Модуль 1Урок 4 з 56Безкоштовний модуль

Уявіть рецепт: одна спеція — чайна ложка, інша — ціле відро. Страва зіпсується. У шарі моделі одна ознака може бути порядку 10 000 (довжина речення в символах), інша — 0.00001 (мала activation). Без балансу gradient «заглушить» дрібні сигнали або вибухне від великих. Scaling і normalization ставлять числа на спільне поле — як диригент, що вирівнює гучність оркестру перед тактом.

Scaling: спільна шкала

Min-max scaling зводить значення однієї ознаки до діапазону від 0 до 1: відняти мінімум, поділити на розмах. Для значень [10, 50, 80] найменше стане 0, найбільше — 1, а 50 стане приблизно 0.57. Порядок «хто більший» не змінюється, змінюється лише шкала: тепер усі значення живуть у спільному діапазоні.

Значення однієї ознаки з відрізка [10,80][10,80] переходять на [0,1][0,1]: 10↦010\mapsto0, 50↦0.5750\mapsto0.57, 80↦180\mapsto1.
Python
values = [1000, 0.5, 200]
min_v, max_v = min(values), max(values)
scaled = [(v - min_v) / (max_v - min_v) for v in values]
print("Оригінал:", values)
print("Scaled 0..1:", scaled)
# [1.0, 0.0, 0.199...] — тепер порівнянні
Вивід

Натисніть «Запустити» — вивід зʼявиться тут

Підказка

Додайте в список одне велике значення, наприклад 100000, і подивіться, що станеться з рештою: min-max беззахисний перед викидом.

Normalization: центр і розкид

Z-score normalization віднімає mean і ділить на standard deviation. Для [2.0, 4.0, 6.0] mean = 4, std ≈ 1.63 — після нормалізації середнє ≈ 0, розкид ≈ 1. Саме так працює LayerNorm: перед наступним шаром activations «видихають» — не занадто великі, не занадто малі. Це допомагає gradient текти стабільно.

z=x−μσz = \frac{x - \mu}{\sigma}

Вправа

Python

Напишіть функцію normalize(values), яка повертає список, зведений до середнього 00 і розкиду 11 за формулою z=(x−μ)/σz = (x - \mu) / \sigma. Стандартне відхилення рахуйте як корінь із середнього квадрата відхилень. Якщо всі значення однакові, розкид нульовий і ділити ні на що — поверніть у такому разі список нулів.

Python
import math


def normalize(values):
    # ваш код
    return values

Тести

Ще не перевіряли

    Порада

    Функція, яку ви щойно написали, і є ядро LayerNorm. У справжньому шарі до неї додано два вивчені параметри — масштаб і зсув, — щоб модель могла частково повернути потрібний їй діапазон, і маленьке число в знаменнику проти ділення на нуль. Але арифметика та сама, і вона вже у вас у руках.

    Приклад

    Список [2, 200, 2000]: поділіть усі на 2000 — отримаєте [0.001, 0.1, 1.0]. Потім відніміть mean і поділіть на std — числа «танцюють» навколо нуля. Спробуйте на папері з [1, 5, 9, 13] — який набір «щільніший»?

    Gradient explosion — коли числа під час backprop ростуть як снігова куля; vanishing — коли стають мікроскопічними. Normalization — один із запобіжників: шар не отримує «крик» 10 000 і «шепіт» 0.0001 в одному такті. BatchNorm дивиться на batch; LayerNorm — на один приклад. У decoder-only LLM частіше побачите LayerNorm — він не залежить від розміру batch під час inference.

    Уявіть три activation в шарі: 0.001, 1.0, 500.0. Без normalization gradient «кричить» лише на третьому neuron, перші два глухнуть. Після z-score усі три говорять однією гучністю — optimizer чує кожен канал. Саме тому scaling і normalization — не косметика, а умова стабільного навчання на великих моделях.

    Що запамʼятати

    Scaling вирівнює діапазони; normalization — центр і розкид. Вони не змінюють суть даних, лише спосіб вираження, щоб шари й gradient працювали рівно. У трансформерах LayerNorm — тихий герой стабільного навчання.

    Перевірка

    4 питання

    Кілька питань за матеріалом уроку. Спроб — скільки завгодно.

    1.Навіщо scaling у моделі?
    2.Що робить z-score normalization?
    3.LayerNorm у трансформері — це переважно…
    4.Чи змінює normalization «сенс» embedding?