# Домашнє завдання · Оптимізатори

> Лекція: [lecture.html](lecture.html) · Практика: [practice.ipynb](practice.ipynb) · Тест: [quiz.html](quiz.html)

Усюди рахуй **кроки**, а не секунди. Секунди залежать від того, який у тебе комп'ютер
і що ще на ньому крутиться; кроки — не залежать ні від чого.

---

## 🟢 Рівень 1 — База

Візьми з практики функції `спуск_простий`, `спуск_із_моментом` і `спуск_adam`, але
**зроби собі новий яр**: змінюй лише кривизну крутого напрямку. Постав її по черзі
рівною 5, 20 (як у лекції), 50 і 100, лишивши пологу 0.05 без змін. Для кожної
кривизни візьми найбільший крок, який ще дозволений простому спуску (це `2/кривизна`,
взяте з невеликим запасом — наприклад, 0.96 від межі), і порахуй, за скільки кроків
кожен із трьох методів заходить у коло радіуса 0.20.

Побудуй таблицю з чотирьох рядків: кривизна, кроки простого, кроки моменту, кроки Adam.

**Зроблено, якщо:** таблиця побудована, і ти написав(ла) двома реченнями, як
змінюється **відношення** «кроки простого / кроки моменту» з ростом кривизни — росте,
падає чи стоїть на місці, і чому саме так.

---

## 🟡 Рівень 2 — Плюс

Повернись до мережі з частини 3 практики й перевір твердження з розділу 08 лекції:
«Adam кращий з коробки, SGD із моментом кращий після налаштування».

Прожени кожен із трьох методів (простий спуск, момент, Adam) на сітці кроків
`[0.01, 0.03, 0.1, 0.3, 1.0, 3.0]` і для кожної пари «метод × крок» запиши фінальну
крос-ентропію на навчальній вибірці та точність на тестовій. Побудуй графік: по
горизонталі крок (логарифмічна шкала), по вертикалі точність, три криві.

**Зроблено, якщо:** графік побудований і ти відповів(ла) на два питання числами.
Перше: у скільки разів ширший діапазон кроків, на якому Adam дає точність не гіршу
за 0.90, порівняно з простим спуском? Друге: чи знайшовся крок, на якому момент
обійшов найкращий результат Adam, і на скільки?

---

## 🔴 Рівень 3 — Виклик

Реалізуй **AdamW** — варіант Adam зі спадом ваг (weight decay), винесеним з градієнта
в саме правило кроку. Різниця з класичним підходом в одному рядку:

* звичайна L2-регуляризація додає `λ·w` **до градієнта**, і далі це число проходить
  крізь обидва накопичувачі Adam, ділиться на `√ŝ` і перестає бути тим, чим було;
* AdamW віднімає `η·λ·w` **окремо**, після кроку оптимізатора, не чіпаючи накопичувачі.

Додай обидва варіанти до функції `навчити` і порівняй їх на мережі з практики при
`λ` з набору `[0, 0.001, 0.01, 0.1]`.

**Зроблено, якщо:** ти показав(ла) таблицею, як при кожній `λ` різняться дві речі —
норма ваг наприкінці навчання (`√(сума квадратів усіх параметрів)`) і точність на
тесті, — і пояснив(ла) одним абзацом, чому в класичному варіанті фактична сила
регуляризації для різних параметрів виходить **різною**, хоча `λ` одна на всіх.

---

## Підказки

* На рівні 1 не забудь, що межу стійкості задає **крутий** напрямок: якщо взяти крок
  за формулою від пологої кривизни, простий спуск вибухне на першій же ітерації, і ти
  отримаєш `nan` замість числа.
* На рівні 2 крок 3.0 майже напевно зламає щось із трьох методів. Це не помилка в коді:
  запиши результат як є, розбіжність — теж результат. Щоб графік не зіпсувався, замінюй
  `nan` на нуль і роби це видимим у підписі.
* На рівні 3 найпростіший спосіб побачити різницю — подивитись на параметри з дуже
  малими градієнтами. У класичному варіанті знаменник `√ŝ` для них малий, тож той самий
  доданок `λ·w` після ділення перетворюється на великий крок; у AdamW він лишається
  рівно `η·λ·w` для всіх.
