Попередні чотири теми блоку вчили мережу вчитись: як влаштований граф із нейронів, як порахувати градієнт, які активації й початкові ваги не дають градієнту згаснути, і як оптимізатор перетворює градієнт на крок. Усе разом дає одну здатність: довести навчальну втрату майже до нуля.
Ця тема — про те, що з цієї здатності нічого доброго само по собі не випливає. Навчальна втрата нуль означає рівно одне: мережа відтворює відповіді на тих прикладах, які бачила. Про нові приклади вона при цьому не сказала нічого. Розрив між двома цими речами — центральна проблема, яка лишилась нерозвʼязаною, і остання тема блоку займається саме нею.
01 / ДіагнозМережа, що вчить напам'ять
Ми вже проходили перенавчання на многочлені п'ятнадцятого степеня й шістнадцяти оголошеннях. Там усе було наочно: параметрів шістнадцять, точок шістнадцять, і крива фізично мала змогу пройти через кожну. У мережі ситуація та сама, лише в іншому масштабі.
Візьмімо задачу з попередніх тем блоку — відрізнити шахрайське оголошення про продаж телефона від чесного за двома ознаками. Мережа з двома прихованими шарами по сорок нейронів має 1801 параметр. Навчальна вибірка — 120 оголошень. Тобто на кожен приклад припадає пʼятнадцять вільних чисел, які можна крутити як завгодно. Це не екзотика, а звичайна пропорція глибокого навчання: у справжніх мережах параметрів буває більше, ніж прикладів, у сотні разів.
Що з цього виходить, видно на числах. За триста епох навчальна крос-ентропія падає до 0.0562, а точність на навчальних оголошеннях доходить до 0.9833 — мережа помиляється на двох прикладах зі ста двадцяти. Втрата на відкладеній валідації за той самий час не падає, а росте: 0.4565 проти найкращого значення 0.2637, досягнутого аж на 51-й епосі. Розрив між навчальною й валідаційною втратою — 0.40. Це і є перенавчання, тільки замість кривої, що пірнає в мінус, ми бачимо дві розбіжні криві.
Експеримент, який вирішив суперечку
Довго вважалося, що мережі якось «самі» уникають запамʼятовування: мовляв, градієнтний спуск шукає прості розвʼязки й тому не чіпляється за окремі точки. Перевірити це можна жорстко — і перевірка стала одним із найвідоміших експериментів у галузі.
Беруть звичайний набір даних і перемішують мітки. Тепер між ознаками й відповіддю немає геть жодного звʼязку: мітка кожного прикладу випадкова. Вивчити тут нема чого — закономірності просто не існує. І мережу навчають на цьому.
Вона навчається. Навчальна втрата спадає майже до нуля, точність доходить до ста відсотків. Наша мережа на перемішаних мітках за дві тисячі епох дає навчальну втрату 0.0128 і точність 1.0000 — жодної помилки на ста двадцяти прикладах, у яких відповіді проставлені навмання. Тобто мережа не «шукає закономірність»: коли закономірності немає, вона спокійно запамʼятовує таблицю.
Схема 1 · Та сама мережа, два набори міток
Ліворуч — справжні мітки, праворуч — ті самі мітки, випадково перемішані між прикладами. Мережа, дані й код однакові.
Висновок звідси не «мережі погані», а точніший і незручніший. Здатність запамʼятати весь навчальний набір закладена в архітектуру. Ніщо всередині мережі не заважає їй це зробити, і ніщо в градієнтному спуску не обіцяє, що вона цього не робитиме. Отже, стриманість має прийти ззовні — з того, як ми ставимо задачу, як подаємо дані й коли зупиняємось. Це і є регуляризація.
02 / ПеренесенняСпад ваг: старий штраф на новому місці
Перший спосіб ми вже знаємо повністю. У темі про регуляризацію ми додали до функції втрат другий доданок — суму квадратів ваг, помножену на силу штрафу — і перенавчений многочлен сам собою став спокійним. Та сама конструкція без жодних змін працює для мережі:
Читається так само, як раніше. Перший доданок — крос-ентропія, яка міряє, наскільки
мережа промахується. Другий — сума квадратів усіх ваг мережі (зсуви зазвичай не
штрафують, як не штрафували вільний член у лінійній моделі). λ — одне
додатне число, ціна одиниці «розгону». У світі мереж цей самий прийом частіше називають
спадом ваг (weight decay), і назва пояснюється похідною: доданок
λ·Σw² дає в градієнті 2λw, тож кожен крок навчання додатково
стягує кожну вагу до нуля на частку, пропорційну їй самій. Ваги спадають.
Чому це лікує саме мережу, а не лише многочлен, теж зрозуміло геометрично. Великі ваги означають різкі перепади виходу: маленький зсув входу дає великий стрибок відповіді. Саме з таких стрибків складається межа рішень, що обростає острівцями навколо окремих точок. Стримуючи ваги, ми стримуємо кривизну межі.
Інтерактив 1 · Сила спаду ваг на мережі
Мережа 2 → 10 → 1 на 70 навчальних точках, з яких 14 % розмічені неправильно. Змінюється одне число — λ.
03 / ТонкістьЧому спад ваг — не завжди L2
Тепер деталь, яку зазвичай проминають, а вона коштувала галузі окремої статті й окремого оптимізатора в кожній бібліотеці.
Є два способи реалізувати ту саму, здавалося б, ідею. Перший —
дописати λ·Σw² у функцію втрат. Тоді до градієнта кожної ваги додається
2λw, і далі цей доданок іде звичайним шляхом — крізь оптимізатор.
Другий — не чіпати втрату взагалі, а після кроку оптимізатора окремо
відняти від кожної ваги η·λ·w.
Для простого градієнтного спуску ці
два способи дають абсолютно однакові числа. Крок першого способу —
w − η·(g + 2λw), крок другого — w − η·g − η·λ'·w. Розкрий дужки
в першому: те саме, тільки λ' = 2λ. Різниця в позначенні, не в поведінці.
Для Adam це вже різні методи.
Adam ділить крок на власний масштаб градієнта: m̂/(√ŝ + ε). Якщо доданок
2λw потрапив у градієнт, він проходить крізь обидва накопичувачі й крізь це
ділення. Значить, фактична сила стягування до нуля залежить від того, наскільки великі
градієнти отримувала ця конкретна вага. Параметр із дрібними градієнтами має
малий знаменник — і його стягує сильно; параметр із великими градієнтами стягує ледь-ледь.
Одне число λ перетворюється на різну силу для різних ваг, і залежність ця
випадкова.
Другий спосіб від цього вільний: η·λ·w віднімається окремо і ділення не
бачить. Оптимізатор, у якому спад ваг реалізовано саме так, зветься
AdamW — літера W від weight decay. Практичний наслідок простий: у
бібліотеках параметр weight_decay в Adam і в AdamW означає різні речі, і
значення, підібране для одного, для другого не годиться.
√ŝ — це два різні методи з однаковою назвою.
Якщо ти вчиш мережу на Adam і регуляризація не працює так, як очікувалось, першим ділом
перевір, який саме із двох варіантів у тебе ввімкнено.04 / DropoutDropout
Спад ваг — прийом, який мережа успадкувала від лінійних моделей. Наступний прийом успадковувати не було звідки: він придуманий для мереж і має сенс тільки в них.
Ідея звучить так, ніби це помилка в коді. На кожному кроці навчання випадково
вимикаємо частину нейронів — просто ставимо їхній вихід у нуль. Вимкнені
нейрони на цьому кроці ні в чому не беруть участі: ні в прямому проході, ні в градієнті.
Наступного кроку жереб кидається наново, і вимикається вже інша частина. Частка вимкнених
p — параметр методу, звичайні значення від 0.1 до 0.5.
Інтерактив 2 · Dropout наочно
Два приховані шари по дванадцять нейронів. Повзунок задає частку вимкнених; кнопка кидає жереб заново.
1 − p — це третя комірка табло. Тисни «наступний крок» кілька разів:
на окремому кроці це число гуляє навколо повної суми, іноді помітно. А середнє за
200 кроків тримається біля повної суми майже точно — ділення вирівнює саме
середнє, і більшого від нього не вимагають.Чому це працює: дві інтуїції
Перша: неможливо покластись на сусіда. Уяви нейрон, який навчився
розпізнавати «дуже низька ціна» і передавати це далі одним каналом. Наступний шар
природно вибудує все своє рішення навколо цього каналу — навіщо шукати щось інше, коли є
готовий надійний сигнал. Так виникає співадаптація: група нейронів працює
злагодженим механізмом, у якому кожна деталь незамінна, а вся конструкція тримається на
особливостях конкретних навчальних прикладів. Dropout цю розкіш забирає. Будь-який
нейрон, на який ти зібрався покластись, з імовірністю p зникне саме на цьому
кроці. Єдина стратегія, що виживає, — дублювати: тримати кілька частково надлишкових
шляхів до тієї самої відповіді.
Друга: це прихований ансамбль. Кожен крок навчання ми фактично навчаємо іншу мережу — ту, що лишилась після викидання вимкнених нейронів. Мереж таких астрономічно багато: якщо прихованих нейронів 24, різних підмереж — 224, тобто понад шістнадцять мільйонів. Усі вони ділять між собою одні й ті самі ваги, тому навчання однієї підмережі покращує решту. А коли ми вимикаємо dropout на передбаченні, повна мережа поводиться приблизно як усереднення всіх цих підмереж. Це рівно та ідея, з якої в темі про випадковий ліс виріс сам ліс: багато навмисне різних моделей, усереднених разом, помиляються менше за одну. Різниця лише в тому, що ліс тримає тисячу окремих дерев у памʼяті, а dropout — одну мережу, яка грає роль усіх підмереж одразу.
Найважливіше місце: що робиться на передбаченні
Ось де реалізації помиляються найчастіше. На етапі передбачення dropout вимикають: усі нейрони працюють, нічого не обнуляється. І тут виникає розбіжність, яку треба виправити руками.
Порахуймо на числах. Нехай нейрон наступного шару отримує суму від дванадцяти
попередніх, і за повного складу ця сума дорівнює 6.00. При
p = 0.25 під час навчання в середньому активні девʼять із дванадцяти, тож
сума в середньому дорівнює 4.50 — три чверті від повної. Мережа
налаштовувала свої ваги під цей рівень сигналу. Якщо на передбаченні подати їй
повні 6.00, кожен наступний нейрон отримає на третину більше, ніж очікує. У глибокій
мережі така похибка множиться від шару до шару, і на виході з'являється систематичний
зсув.
Лікується це масштабуванням, і робити його можна з двох боків:
- Масштабувати на передбаченні. Помножити виходи шару на
1 − p: 6.00 × 0.75 = 4.50, рівно те, під що мережа налаштована. Це класичний варіант із першої статті про dropout. - Масштабувати на навчанні (inverted dropout). Ділити виходи тих
нейронів, що лишились, на
1 − p: 4.50 ÷ 0.75 = 6.00. Тоді на передбаченні не треба робити нічого — і саме тому так роблять усі сучасні бібліотеки. Код передбачення не залежить від того, який бувp.
Схема 2 · Навчання проти передбачення
Той самий шар у двох режимах. Числа — активації нейронів; унизу — що дістається наступному шару.
1 − p. Праворуч мовчить лише сам dropout — і саме
тому там нічого ділити не треба. Забудеш будь-яку з двох половин — і мережа на
передбаченні працює не в тому масштабі, у якому вчилась.p = 0.5 і забудемо масштабування на
передбаченні. Точність від цього майже не змінюється: 0.8897 проти
0.8910 — межа рішень зсунулась мало. А от крос-ентропія псується вдвічі:
0.5132 замість 0.2981, і середній прогноз падає з 0.1582 до 0.1033 при
справжній частці шахрайських оголошень 0.1628. Тобто мережа лишилась приблизно правою у
відповідях «так / ні», але стала систематично занижувати ймовірності. Якщо ти дивишся
лише на точність, ця помилка проживе в проєкті роками.05 / BatchNormПакетна нормалізація
Наступний прийом до регуляризації взагалі не планувався. Його придумали, щоб мережі швидше вчились, а те, що він заодно трохи стримує перенавчання, — побічний ефект.
Ідея проста. Ми вже нормуємо входи мережі: віднімаємо середнє, ділимо на стандартне відхилення, щоб усі ознаки жили в одному масштабі. Але глибока мережа — це ланцюжок шарів, і вхід кожного наступного шару — це вихід попереднього, який ніхто не нормує. Він може поїхати куди завгодно: розтягнутись, зсунутись, стиснутись у точку. Пакетна нормалізація (batch normalization) робить із внутрішніми активаціями те саме, що ми робимо з входом: усередині шару бере поточний пакет (batch) прикладів, рахує по ньому середнє й розкид кожної активації й приводить її до середнього нуль і розкиду одиниця. А щоб мережа не втратила свободу, після цього її пропускають крізь двійку власних навчальних параметрів — множник і зсув, — які мережа підбирає сама.
Схема 3 · Що робить пакетна нормалізація
Розподіл однієї активації по прикладах пакета: до нормалізації й після неї. Праворуч — та сама активація одного прикладу в трьох різних пакетах.
Звідси й регуляризаційна дія. Приклад більше не обробляється сам по собі: його нормалізоване значення залежить від випадкового складу пакета, у який він потрапив. Це той самий механізм, що й у dropout, лише слабший і не такий керований — мережа щоразу бачить трошки інакшу версію того самого прикладу й тому не може вчепитись за точні числа. Побічний наслідок: на передбаченні пакетів немає, і статистики брати нізвідки — тому їх накопичують під час навчання ковзним середнім і на передбаченні використовують збережені. BatchNorm на навчанні й на передбаченні працює по-різному, і забути перемкнути режим — класична причина того, що модель у продакшені поводиться не так, як у зошиті.
06 / ЗупинкаРання зупинка
Найдешевший прийом у цій темі не додає до мережі нічого. Він лише каже, коли припинити.
У темі про перенавчання ми бачили U-подібну криву: зі зростанням складності помилка на нових даних спершу падає, потім розвертається вгору. З мережею ту саму криву дає час навчання. Перші епохи мережа вчить закономірність, і обидві втрати спадають разом. З якогось моменту закономірність вичерпана, і мережа береться за шум конкретних навчальних прикладів: навчальна втрата спадає далі, валідаційна розвертається. Точка розвороту — момент, коли треба зупинитись.
Механіка проста: після кожної епохи міряємо втрату на валідаційній вибірці й запамʼятовуємо ваги, коли вона найменша. Проблема одна — крива шумна, і одне випадкове погіршення ще нічого не означає. Тому вводять терпіння (patience): скільки епох поспіль дозволено не покращувати рекорд, перш ніж зупинитись. І зупинившись, повертають найкращі ваги, а не останні. Це важливо: інакше терпіння в двадцять епох означає, що ти віддаєш модель, яка двадцять епох поспіль ставала гіршою.
Інтерактив 3 · Де саме зупинитись
Дві криві втрат протягом 300 епох. Повзунок ставить «стоп» на обрану епоху; кнопки — терпіння.
На нашій мережі рання зупинка дає найбільший ефект за найменші зусилля. Навчання до кінця (300 епох) дає валідаційну втрату 0.4565. Зупинка з терпінням 20 спрацьовує на 71-й епосі й повертає ваги 51-ї, де валідаційна втрата 0.2637 — майже вдвічі краще, і при цьому 229 епох із 300 просто не виконуються. Терпіння 5 на цій самій кривій зупиняється аж на девʼятій епосі й віддає ваги четвертої: втрата 0.3629, помітно гірша за досяжну. Занадто нетерплячий сторож шкодить.
07 / ДаніБільше даних і аугментація
Усі попередні прийоми стримують модель. Є один, який замість цього посилює другий бік рівняння, і він найнадійніший: більше даних. Перенавчання — це завжди співвідношення між тим, скільки в моделі свободи, і тим, скільки прикладів цю свободу обмежують. Подвоївши вибірку, ти вдвічі здешевив кожен параметр.
Проблема відома: справжні приклади коштують грошей і часу, а розмічені — ще й уваги людини. Коли додати справжніх не можна, роблять аугментацію (augmentation) — варіації наявних прикладів, які змінюють вигляд, але не змінюють відповіді.
- Зображення. Відображення зліва направо, повороти на кілька градусів, випадкове обрізання, зміна яскравості й контрасту, легкий шум. Кіт лишається котом після всього переліченого — а мережа бачить його щоразу інакше й перестає запамʼятовувати розташування конкретних пікселів. Обережно з тим, що змінює суть: перевернуте догори дриґом «6» стає «9».
- Текст. Заміна слів синонімами, викидання випадкових слів, переклад на іншу мову й назад. Тут ризик більший: одне слово легко перевертає зміст речення, тож аугментації тексту завжди перевіряють очима на вибірці.
- Таблиці. Найважчий випадок — довільно змінене число просто зіпсує приклад. Працює хіба що додавання малого шуму до неперервних ознак у межах їхньої природної похибки вимірювання.
Спільний принцип один: аугментація — це спосіб розповісти мережі, що саме не має значення. Кожне перетворення, яке ти дозволяєш, — це твердження «відповідь від цього не залежить». Тому набір аугментацій завжди залежить від задачі й ніколи не буває універсальним.
08 / ВибірЩо з чим поєднувати
Таблиця 1 · Пʼять способів поруч
Числа — точність на відкладеній вибірці для мережі з практики цієї теми: 1801 параметр, 120 навчальних оголошень. Без жодної регуляризації вона дорівнює 0.8795.
| спосіб | коли брати першим | точність на тесті | з чим обережно |
|---|---|---|---|
| рання зупинка | завжди — вона майже безкоштовна | 0.9038 | ні з чим не конфліктує; вимагає валідації |
| спад ваг | коли розрив великий і мережа явно розігналась | 0.9103 | в Adam це не те саме, що L2; бери AdamW |
| dropout | широкі повнозвʼязні шари, багато даних | 0.8846 | душить малу мережу; ставити перед BatchNorm не можна |
| BatchNorm | глибока мережа, яка погано вчиться | — | інша поведінка на передбаченні; малі пакети ламають |
| більше даних | завжди, якщо можна купити | — | аугментація мусить зберігати відповідь |
Три правила поєднання, які варто знати наперед.
Dropout перед BatchNorm — типова помилка. BatchNorm рахує середнє й розкид по пакету. Якщо перед ним стоїть dropout, ці статистики зняті з прорідженого сигналу — а на передбаченні dropout вимкнено, і в BatchNorm приходить сигнал іншого розміру, ніж той, за яким він накопичував свої збережені середні. Розбіжність між навчанням і передбаченням подвоюється. Правильний порядок — спершу BatchNorm, потім активація, потім dropout; або взагалі не поєднувати ці два в одному блоці.
Регуляризація не лікує недонавчання. Діагноз читається за двома
помилками поруч, як у темі 20: великий розрив між навчальною й валідаційною — можна
додати штрафу; обидві однаково високі — штраф навпаки треба зменшити, а модель
ускладнити. Наш dropout це показав буквально: при p = 0.1 точність на тесті
виросла з 0.8795 до 0.8846, при p = 0.2 вона впала до 0.8205, а при
p = 0.3 і 0.5 мережа з двома ознаками й ста двадцятьма
прикладами задихнулась зовсім. Її прогнози злиплись у вузьку смужку навколо базової
частки, жоден не перетнув поріг, і точність стала рівно 0.8372 — стільки дає відповідь
«усі оголошення чесні». Навчальна втрата при цьому 0.4475 проти 0.4506 у справжньої
сталої відповіді. Це не поламаний код, це недонавчання від надлишку регуляризації.
Більше — не краще. На наших даних спад ваг найкраще спрацював при
λ = 0.3 (точність 0.9103), а при λ = 3.0 валідаційна втрата
знову виросла до 0.3435. Ця крива має дно, і воно посередині — так само, як мала дно
крива α в темі 23. Загальний висновок цієї теми, якщо звести його до одного
рядка: сила регуляризації — гіперпараметр, а не константа, і підбирати
його треба вимірюванням, а не переконанням.
09 / ДаліКуди далі
Блок про нейромережі на цьому закінчується. Пʼять тем склались в одну робочу схему: будова мережі → градієнт → активації й старт → крок → стриманість. Останній пункт тримається на пʼятьох прийомах:
- спад ваг — той самий L2, що й у лінійних моделях, але в Adam реалізований інакше, ніж штраф у втратах;
- dropout — випадкове вимикання нейронів на навчанні; масштабування обовʼязкове, інакше передбачення зміщене;
- пакетна нормалізація — прискорює навчання, регуляризує побічно шумом від складу пакета;
- рання зупинка — найдешевша й найдієвіша: дно валідаційної кривої плюс терпіння;
- дані й аугментація — єдиний спосіб, який не забирає в моделі свободу, а додає обмежень ззовні.
І тепер найцікавіше. Уся ця тема — і вся тема 20 — стоять на одному твердженні: складність треба стримувати, бо надлишкова складність псує узагальнення. Твердження правильне, перевірене й підтверджене всіма числами вище. Але воно не є повною правдою.
Якщо продовжувати нарощувати мережу далі — за точку, де вона вже ідеально запамʼятала навчальні дані, — помилка на нових даних після піку починає знову падати, і падає нижче за найкраще значення класичної U-подібної кривої. Явище зветься подвійним спуском (double descent), і воно пояснює, чому сучасні мережі з мільярдами параметрів працюють усупереч усьому, що ми щойно розібрали. Наступний блок починається саме з цього: тема 36 показує криву на числах, а тема 37 — її математику.
practice.ipynb ти навмисно
перенавчиш мережу на 120 прикладах і побачиш розрив 0.40 власними очима; додаси спад ваг
і подивишся, як розрив стискається до 0.08; напишеш dropout з нуля —
маску на навчанні й масштабування на передбаченні — і забудеш масштабування, щоб
побачити ціну; поставиш ранню зупинку з терпінням і порахуєш зекономлені епохи; а
наприкінці зведеш усі способи в одну таблицю на тих самих даних.Далі в темі
Теорію прочитано. Тепер закріпи її на практиці.