Машинне навчання · Блок 5 · Тема 23

Штраф за складність

Перенавчену модель не обовʼязково спрощувати. Можна лишити її такою ж гнучкою — і просто зробити божевілля дорогим. Один доданок у функції втрат перетворює криву, що пірнала на пів мільйона гривень, на цілком розумну.

У темі про перенавчання ми залишили на дошці криву, яку неможливо забути. Шістнадцять оголошень про телефони рідкісної марки, многочлен пʼятнадцятого степеня — і крива, що проходить точно через кожну точку. Помилка на навчанні: 0 ₴. Помилка на трьохстах нових оголошеннях: 740 696 ₴. Між двома найстарішими оголошеннями та сама крива опускається до −610 412 ₴ — тобто обіцяє, що за телефон 2011 року тобі ще й доплатять шістсот тисяч.

01 / ПостановкаТретій спосіб

Тоді ми знали два способи це вилікувати, і обидва зводились до того, щоб змінити умови задачі.

Є третій спосіб, і він відрізняється від обох принципово. Модель лишається пʼятнадцятого степеня. Дані лишаються ті самі, шістнадцять оголошень. Ми не чіпаємо ані те, ані те — ми змінюємо саме́ завдання, яке ставимо оптимізатору. Досі ми просили його про одне: зроби помилку на навчальних даних якнайменшою. Тепер попросимо про дві речі одразу: зроби помилку малою і водночас не розганяй коефіцієнти.

Це і є регуляризація (regularization) — від латинського regula, «правило», «міра». Модель формально лишається такою самою гнучкою: у неї ті самі шістнадцять вільних чисел, вона все ще вміє намалювати ту божевільну криву. Просто тепер це стало дорого, і оптимізатор сам від такої кривої відмовиться.

Чому це важливо саме зараз. Спрощення моделі — рішення дискретне: степінь буває 3 або 4, проміжного не існує. Регуляризація дає плавну ручку: одне дійсне число, яке можна крутити від «свободи скільки завгодно» до «свободи нуль» і зупинитись рівно там, де треба. А підбирати одне число ми вже вміємо — крос-валідацією.

02 / ДіагнозЗвідки береться божевілля

Перш ніж лікувати, треба зрозуміти механізм. Питання просте: що саме всередині перенавченої моделі не так? Подивимось не на криву, а на її нутрощі — на числа, з яких вона складена.

Наша модель — це сума шістнадцяти доданків. Кожен доданок — це стандартна форма кривої, помножена на своє число. Форма №0 — горизонтальна пряма, форма №1 — похила, форма №2 — одна дуга, форма №3 — дві дуги, і так далі: чим більший номер, тим більше вигинів у формі. Числа-множники називають вагами (weights) або коефіцієнтами; це саме те, що модель підбирає під час навчання, як у звичайній лінійній регресії. Вага показує, скільки гривень ця форма додає до відповіді.

А тепер порівняй ваги двох моделей на тих самих 16 оголошеннях.

Схема 1 · Ваги моделі степеня 3 і моделі степеня 15

Одні й ті самі оголошення, той самий спосіб навчання. Відрізняється лише кількість форм, які моделі дозволено змішувати.

формастепінь 3, ₴степінь 15, ₴
07 442−41 119
17 574−366 460
23 443−207 960
31 050−896 431
4−267 975
5−1 375 011
6−204 081
7−1 615 407
8−85 333
9−1 468 394
103 651
11−1 003 378
1227 443
13−468 288
1413 368
15−115 757
сума модулів19 5088 160 052
Ось воно. У розумної моделі найбільша вага — 7 574 ₴, і це приблизно порядок самих цін на дошці. У перенавченої найбільша вага — 1 615 407 ₴, у двісті тринадцять разів більше. Сума модулів усіх ваг зросла з 19,5 тисячі до восьми мільйонів гривень — а прогнозує ця модель ті самі телефони по десять тисяч.

Звідки такі числа й до чого тут стрибки кривої? Механізм такий. Щоб крива пройшла точно через шістнадцять розкиданих точок, вона мусить робити різкі повороти. Різкий поворот можна зібрати з плавних форм єдиним способом: узяти їх з величезними множниками протилежних знаків, щоб у потрібних місцях вони гасили одне одного, а в одному місці — не догасили.

Підставмо число. Візьмімо рік 2010,67 — точку між двома найстарішими оголошеннями, де крива й пірнає. Модель рахує там шістнадцять доданків. Найбільший із них дорівнює −586 736 ₴, сума модулів усіх шістнадцяти — 2 582 897 ₴. А їхня алгебраїчна сума, тобто відповідь моделі, — −610 412 ₴. Тобто два з половиною мільйони гривень майже повністю знищили одне одного, і те, що лишилось, — це залишок, який ніхто не контролює.

Для порівняння: у моделі степеня 3 в тій самій точці сума модулів доданків — 17 448 ₴, а відповідь — 2 557 ₴. Тут нічого не гасне, бо нічого й не розганялось.

Це загальний закон, а не особливість многочленів. Величезні ваги, які майже гасять одне одного, — універсальний почерк перенавчання. Так поводиться і лінійна модель на корельованих ознаках, і нейромережа, у якої ваги розганяються під час навчання. Модель, у якої відповідь — це маленька різниця двох величезних чисел, завжди нестійка: зміни вхід на копійку, і різниця стрибне на тисячі.

03 / ІдеяДоданок, що змінює все

Якщо хвороба — великі ваги, то ліки очевидні: зробімо великі ваги невигідними. Не заборонімо (заборона — це знову дискретне рішення), а саме зробімо дорогими.

Досі оптимізатор мінімізував одну величину — суму квадратів промахів на навчальних оголошеннях. Додамо до неї другий доданок, який росте разом із вагами:

Втрата = Σ (ціна − прогноз)2  +  α · Σ wk2

Що це означає словами. Модель тепер платить за дві різні речі: за те, що промахується повз ціни, і окремо за те, що користується великими вагами. Найкращою вважається не та, що найточніше повторює дані, а та, у якої сумарна плата найменша.

Що означає кожен символ. Перша сума — стара знайома квадратична помилка: береться різниця між реальною ціною оголошення й прогнозом, підноситься до квадрата, і так по всіх шістнадцяти оголошеннях. Друга сума — по всіх вагах моделі, крім нульової: wk — вага k-ї форми. α (альфа) — одне додатне число, сила штрафу: наскільки дорого коштує одиниця «розгону» порівняно з одиницею помилки.

Навіщо вона тут. Щоб оптимізатор, який не вміє зупинятись сам, отримав причину зупинитись. Він і далі мінімізує те, що йому дали, — просто тепер у цьому «тому» записано, що ідеальна відповідь ціною восьмимільйонних ваг є поганою відповіддю.

Чому нульову вагу не штрафують? Вага w0 — множник при горизонтальній прямій, тобто загальний рівень цін. Якби ми штрафували і її, модель отримала б покарання просто за те, що телефони коштують десять тисяч, а не нуль. Це не має стосунку до складності: зсунь усі ціни на тисячу гривень — і модель має зсунутись слідом безкоштовно.

Тепер найцікавіше. Порахуймо цю нову втрату для двох конкретних кривих при α ≈ 0,32.

Крок 1 · божевільна крива

Та сама крива степеня 15, що проходить через усі 16 точок. Перший доданок дорівнює нулю: промахів немає. Другий — 0,32, помножене на суму квадратів ваг, а ваги там сягають півтора мільйона.

Втрата = 0 + 0,32 · 8,9·1012 ≈ 2,85·1012
Крок 2 · спокійна крива

Крива того самого степеня 15, але з вагами не більшими за 6 716 ₴. Вона вже не проходить через точки: промахується в середньому на 502 ₴, тобто сума квадратів промахів — близько чотирьох мільйонів. Зате штраф упав на пʼять порядків.

Втрата = 4,0·106 + 1,9·107 ≈ 2,31·107
Крок 3 · висновок

2,85·1012 проти 2,31·107: божевільна крива тепер програє спокійній у сто двадцять три тисячі разів. Ми не забороняли її й не зменшували степінь — ми зробили її невигідною, і оптимізатор сам обійшов її стороною.

Зверни увагу на те, чого ми не зробили. Ми не сказали моделі, якою має бути крива. Ми не заборонили жодного степеня. Ми лише виставили ціну — і дозволили моделі самій вирішити, скільки складності вона готова за цю ціну купити.

04 / L2Гребенева регресія

Штраф, який ми щойно виписали, — сума квадратів ваг. У такому вигляді метод називають гребеневою регресією (ridge regression), або просто L2-регуляризацією — за назвою тієї самої суми квадратів, яка в математиці зветься L2-нормою.

Квадрат обраний не випадково, і його поведінка варта окремого абзацу. Похідна від дорівнює 2w: чим більша вага, тим сильніше її тягне до нуля. Вага в мільйон гривень відчуває тиск у мільйон разів більший, ніж вага в одну гривню. Тому L2 нещадний до розгону — і майже байдужий до дрібниць. І тут ключове: коли вага стає малою, тиск на неї теж стає малим. Біля нуля похідна теж прямує до нуля, тож останній крок до самого нуля робити нема кому. L2 стискає ваги, але не обнуляє їх: у моделі лишаються всі шістнадцять форм, просто кожна звучить тихіше.

Крути α й дивись, що стається з тією самою кривою пʼятнадцятого степеня.

Інтерактив 1 · Сила штрафу на кривій степеня 15

Модель не змінюється: усі 16 ваг на місці, степінь той самий. Змінюється лише α — ціна, яку модель платить за їхню величину.

помилка на навчанні
помилка на тесті
найбільша вага, ₴
найкраща тестова
Прожени обидва краї. Ліворуч на шкалі (α = 10−12) штрафу фактично немає — і ти бачиш точно ту криву з теми про перенавчання: 0 ₴ на навчанні, 740 696 ₴ на тесті. Праворуч (α = 100 000) штраф роздавив усе: лишилась горизонтальна пряма, 4 327 ₴ помилки. Дно — при α ≈ 0,32: 1 146 ₴. Шкала помилки праворуч логарифмічна, інакше 740 тисяч розчавили б решту.

Проговоримо, що саме ти щойно побачив, бо тут ховається головна думка теми.

Мовою попередньої теми, зміщення проти дисперсії, це формулюється одним реченням: регуляризація купує зменшення дисперсії ціною збільшення зміщення. Стиснуті ваги роблять модель менш чутливою до конкретної вибірки — підміни 16 оголошень на інші 16, і крива зміниться значно менше. Розплата в тому, що навіть на нескінченних даних модель зі штрафом уже не зможе стати точною: штраф свідомо тягне її вбік від ідеалу. Обмін вигідний доти, доки виграш у дисперсії більший за програш у зміщенні, — а де саме ця межа, показує тестова крива на екрані вище.

05 / L1Ласо, що обнуляє

Тепер поміняємо в штрафі одну річ: замість квадрата візьмемо модуль.

Втрата = Σ (ціна − прогноз)2  +  α · Σ |wk|

Це L1-регуляризація, вона ж ласо (lasso). Заміна здається косметичною, а наслідок — якісно інший: частина ваг стає точно нулем. Не маленькими, не «майже нулем», а нулем, який дорівнює нулю. Вага, що дорівнює нулю, означає, що відповідної форми в моделі більше немає взагалі. Тобто ласо саме викидає ознаки — робить відбір ознак (feature selection) заодно з навчанням і безкоштовно.

Чому модуль обнуляє, а квадрат ні? Дивись на тиск біля нуля. Похідна від — це 2w, і біля нуля вона зникає: тиск слабшає рівно тоді, коли вага вже майже там. Похідна від |w| — це ±1 завжди, скільки б вага не важила. Тиск не слабшає ніколи, тож він доводить вагу до нуля й тримає її там: щоб вага зрушила з нуля, її внесок у зменшення помилки має перевищити цей сталий тиск. Якщо форма пояснює дані слабко, вона просто не окупає власного штрафу — і зникає.

Те саме можна побачити геометрично, і ця картинка варта того, щоб її запамʼятати.

Схема 2 · Чому кут обнуляє, а коло — ні

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

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

Це не доказ, а схема: у справжній задачі ваг не дві, а пʼятнадцять, і «ромб» стає багатовимірним тілом із безліччю кутів і ребер. Але сутність та сама, і вона зберігається в будь-якій розмірності: у ромба є гострі виступи на осях, у кулі — немає, тому L1 влучає в нуль, а L2 — практично ніколи.

Перевір це на наших вагах. Перемикач біля стовпчиків міняє тип штрафу, повзунок під ним — його силу.

Інтерактив 2 · Що штраф робить із пʼятнадцятьма вагами

Стовпчики — ваги форм з 1-ї по 15-ту (нульову не штрафуємо, тому й не показуємо). Угору — додатні, вниз — відʼємні.

найбільша вага
сума модулів
точних нулів
помилка на тесті
Головне порівняння курсу в одній фігурі. Прожени повзунок до кінця в режимі L2: найбільша вага падає з 7 595 до 38 ₴, але лічильник нулів усю дорогу показує 0 — жодна вага так і не зникла. Той самий шлях у режимі L1: нулів стає 2, 4, 5, 7, 12, 13, 14, 15. При α = 1 000 сім ваг із пʼятнадцяти вже точно нульові, а помилка на тесті — 865 ₴, найкраща в усій темі. Шкали α у двох режимів різні, і це не помилка: квадрат і модуль вимірюються в різних одиницях, тому й ціна за них інша.

Останній рядок підпису вартий уваги на практиці: перенести вдало підібране α з гребеневої регресії в ласо не можна, його треба підбирати заново.

Коли що обирати? Коротке правило таке.

ситуаціящо кращечому
ознак багато, більшість зайвіL1сам викине зайві й дасть коротку модель, яку легко пояснити
ознаки всі потроху корисніL2рівномірно притисне всіх, нічого не втративши
ознаки сильно корельованіL2L1 залишить одну з групи навмання й викине решту
потрібно і те, і теобидва разомсума двох штрафів зветься «еластична сітка» (elastic net)

06 / ВибірСкільки штрафу насипати

Ми весь час підглядали в тестову помилку, щоб знайти дно. У справжній задачі так робити не можна, і ми вже знаємо чому: дані, за якими ти щось обираєш, більше не годяться для оцінювання обраного. Якщо перебрати тридцять пʼять значень α і взяти те, де тестова помилка найменша, число 1 146 ₴ перестане бути чесною оцінкою — це буде мінімум із тридцяти пʼяти спроб, а такий мінімум систематично оптимістичний.

Правильний інструмент — крос-валідація. Наші 16 оголошень ділимо на чотири частини по чотири. Для кожного α: чотири рази навчаємось на дванадцятьох оголошеннях і міряємо помилку на четвірці, яку не бачили; чотири помилки зводимо в одну. Тестового конверта не торкаємось узагалі.

Схема 3 · Крос-валідація знаходить те саме дно

Бірюзова крива — помилка крос-валідації на 16 навчальних оголошеннях. Рожева — помилка на 300 відкладених, яку ми в реальній задачі не маємо права бачити.

Обидві криві мають мінімум в одній точці: α0,32. Крос-валідація, яка нічого не знає про тестові оголошення, вибрала рівно те саме значення. Рівні різні — 2 025 ₴ проти 1 146 ₴, — і це нормально: кожна модель у крос-валідації бачила лише дванадцять оголошень замість шістнадцяти, тож була слабшою. Але нам і не потрібен рівень, нам потрібне розташування дна.

Практичний рецепт виглядає так: узяти сітку значень α з кроком у порядок (0,001; 0,01; 0,1; 1; 10 …), прогнати крос-валідацію по кожному, узяти найкраще, за потреби згустити сітку навколо переможця. У бібліотеках це вже загорнуто в готові інструменти на кшталт RidgeCV і LassoCV. Ширший клас таких задач — «модель має число, яке не підбирається навчанням» — називають підбором гіперпараметрів, і йому присвячено окрему тему далі в курсі.

Дві помилки, які роблять тут найчастіше. Перша: підбирати α на тестових даних, як робили ми в цій лекції заради наочності. Друга, підступніша: масштабувати ознаки на всьому наборі до поділу на частини. Тоді середнє й розкид, порахований по всіх даних, просочується у навчальні частини — і крос-валідація починає брехати на свою користь. Масштабування має відбуватись усередині кожного розбиття.

07 / МасштабБез однакового масштабу не працює

А тепер про умову, без якої все написане вище просто не спрацює, — і про яку забувають частіше за все інше в цій темі.

Штраф α · Σ w² однаковий для всіх ваг. Він не питає, що це за ознака й у чому вона виміряна. А ваги живуть у різних масштабах саме через одиниці виміру: якщо пробіг записаний у кілометрах, вага при ньому буде порядку одиниць; якщо той самий пробіг записати в метрах, вага стане в тисячу разів меншою, а модель — рівно тією самою. Штраф же цього не знає: він побачить тисячократно меншу вагу й вирішить, що ця ознака скромна й чіпати її не варто. Ознака в гривнях і ознака в днях отримають несумірні покарання за однакову за суттю поведінку.

Порахуймо це на пальцях. Нехай ознака дає моделі вагу w. Запиши ту саму ознаку в одиницях, у тисячу разів дрібніших, — і вага стане в тисячу разів меншою, бо прогноз мусить лишитись тим самим. А от її внесок у штраф впаде в мільйон разів, бо в штрафі стоїть квадрат. Модель не змінилась ані на гривню; змінилось лише те, кого штраф тепер вважає скромним, а кого — розгонистим.

Це та сама пастка, на якій ламається метод найближчих сусідів: там відстань не питала про одиниці й дозволяла одній ознаці заглушити решту. Тут те саме, тільки з іншого боку: несумірні одиниці не заглушують модель, а спотворюють штраф.

Наші пʼятнадцять форм навмисне зроблені однакового розмаху, тому досі проблеми не було. Зруйнуймо цю зручність: у кожному «варіанті одиниць» нижче кожна форма записана у своїх одиницях — множники розкидані від тисячних до сотень. Дані ті самі, модель та сама, степінь той самий. Для кожного варіанта ми беремо найкращий для нього штраф — тобто даємо йому максимальну фору.

Інтерактив 3 · Одиниці виміру вирішують за тебе

Дванадцять варіантів того, у чому виміряні ознаки, і нульовий варіант — усі зрівняні. У кожному показано найкраще, чого штраф здатен досягти.

найкраще α
помилка на тесті
еталон
різниця
Прожени всі дванадцять. Зі зрівняними ознаками найкраще — 1 146 ₴ при α ≈ 0,32. Варіанти в різних одиницях дають від 980 до 4 292 ₴, і одинадцять із дванадцяти гірші за еталон. Дивись також на перший рядок праворуч: найкраще α переїжджає на чотири-пʼять порядків. Уся твоя робота з підбору сили штрафу знецінюється, щойно хтось перезапише ознаку в інших одиницях.

Найважливіше тут — не те, що стає гірше. Один варіант із дванадцяти виявився навіть кращим за еталон. Важливо те, що результат став некерованим: він тепер залежить від довільного вибору, який не має жодного стосунку до задачі, і дізнатись, пощастило тобі чи ні, можна лише за тестовою вибіркою — якої в реальній задачі під рукою немає.

Звідси просте правило, яке варто виконувати механічно: перед будь-якою регуляризованою моделлю ознаки зрівнюють. Найчастіше — відніманням середнього й діленням на стандартне відхилення (у scikit-learn це StandardScaler), щоб кожна ознака мала нульове середнє й одиничний розкид. Після цього результат перестає залежати від того, у чому ознака була записана: усі дванадцять варіантів дадуть одну й ту саму відповідь. Штраф стає нарешті відтворюваним — а «одиниця ваги» починає означати одне й те саме для всіх ознак.

08 / ШиршеТа сама ідея в інших моделях

Штраф у функції втрат — найпрозоріший вид регуляризації, але далеко не єдиний. Загальна ідея ширша: обмежити свободу моделі, щоб їй не було чим запамʼятати шум. Способи обмежити бувають зовсім різні на вигляд.

Схема 4 · Одна ідея під різними іменами

Спільне в усіх рядках: модель могла б описати дані точніше, але їй не дають.

методщо обмежуютьяк це виглядає
Ridge (L2)суму квадратів вагусі ваги стискаються, жодна не зникає
Lasso (L1)суму модулів вагчастина ваг стає точно нулем
глибина деревакількість питань підряддерево не може виростити гілку під один обʼєкт
dropoutкількість нейронів у кроцічастину нейронів вимикають випадково під час навчання
рання зупинкакількість кроків навчанняспуск зупиняють, щойно помилка на валідації розвернулась угору
згладжування Лапласакрайність оцінок імовірностідо кожного лічильника додають одиницю
розширення данихдовіру до конкретного прикладутой самий знімок показують повернутим і затемненим
Передостанній рядок ти вже проходив. У темі Наївний Баєс ми додавали одиницю до кожного лічильника слів, щоб жодне слово, якого не було у вибірці, не наклало вето своїм нулем. Тоді це називалось згладжуванням. Це була регуляризація: ми свідомо зіпсували оцінку на навчальних даних, щоб отримати кращу на нових.

Варто помітити, що рання зупинка (early stopping) робить те саме, що L2, майже буквально. Градієнтний спуск стартує з нульових ваг і поступово їх нарощує. Зупинити його раніше — означає не дати вагам вирости. Це той самий стиск, лише виражений через час, а не через штраф.

І ще одна деталь, яку легко пропустити: регуляризація — не безкоштовна й не завжди корисна. Якщо модель недонавчена, штраф зробить гірше, а не краще. Читати діагноз треба так само, як у темі про перенавчання: дві помилки поруч. Великий розрив між навчальною й тестовою — можна додати штрафу. Обидві однаково високі — штраф навпаки треба зменшити, а модель ускладнити.

09 / ПідсумокЩо варто винести

Ми не спростили модель і не добули жодного нового оголошення. Ми лише дописали в функцію втрат один доданок — і крива, що пірнала до −610 412 ₴, стала триматись між 2 298 і 16 707 ₴, а помилка на нових оголошеннях впала з 740 696 до 1 146 ₴, а з ласо й до 865 ₴.

ідеясутьчому важливо
симптомперенавчена модель має величезні вагивідповідь — різниця величезних чисел, тому нестійка
лікидоданок у втраті, що росте з вагамимодель платить і за помилку, і за складність
L2штраф — сума квадратівстискає всі ваги, не обнуляє жодної
L1штраф — сума модулівобнуляє частину ваг, тобто відбирає ознаки
αціна одиниці «розгону»нуль — перенавчання, забагато — недонавчання
вибір αкрос-валідація, не око й не тествибір по тесту псує оцінку
масштабознаки зрівнюють перед штрафомінакше штраф падає не на ті ваги
обмінменше дисперсії ціною більшого зміщеннявигідно лише до певної межі

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

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

Далі в практиці. У practice.ipynb ти надрукуєш коефіцієнти перенавченого многочлена й побачиш ті самі мільйони на власні очі, додаси Ridge і подивишся, як вони стискаються, додаси Lasso й порахуєш, скільки ваг стало точними нулями, підбереш α через RidgeCV і LassoCV, а наостанок побачиш, що без StandardScaler відповідь починає залежати від того, у чому виміряні ознаки.

Далі в темі

Теорію прочитано. Тепер закріпи її на практиці.