P01
Практичне заняття 1: Налаштування середовища та математичний апарат
- Курс: Проблеми штучного інтелекту
- Тиждень: 1
- Спирається на: Лекція 1
- Тривалість: 2 академічні години
- Тип заняття: практична робота під наглядом викладача
Python, NumPy, PyTorch · операції з матрицями й тензорами · автоматичне диференціювання як інструмент
Структура заняття
| Блок | Час | Що відбувається |
|---|---|---|
| Організаційний блок | 10 хв | репозиторій, перевірка середовища, порядок здачі |
| Завдання 1-2 | 25 хв | масиви й операції у NumPy |
| Завдання 3 | 15 хв | тензори PyTorch, пристрої, спільна пам'ять |
| Завдання 4 | 20 хв | автоматичне диференціювання |
| Завдання 5 | 10 хв | емпіричний ризик і три способи взяти градієнт |
git commit і git push |
10 хв | обов'язкова здача напрацьованого |
Це заняття суто інструментальне: воно готує середовище й навички, на які спираються всі наступні практичні. Теорію зворотного поширення похибки тут не розглядаємо, вона належить Лекціям 2 і 5.
Завдання 5 підсумовує заняття й прив'язує його до формалізму Лекції 1. Якщо не встигаєте в аудиторії, завершуйте вдома до дедлайну здачі, це не штрафується.
Результати навчання
Після завершення заняття студент зможе:
- Відтворити робоче середовище курсу й підтвердити його працездатність відтворюваною перевіркою.
- Виконувати операції з векторами, матрицями й тензорами у NumPy, свідомо розрізняючи поелементне множення й матричний добуток.
- Пояснювати правила трансляції розмірностей (broadcasting) і передбачати форму результату до запуску коду.
- Переносити дані між NumPy і PyTorch, розуміючи, коли масив і тензор поділяють спільну пам'ять.
- Обчислювати градієнти засобами автоматичного диференціювання й перевіряти їх скінченними різницями.
- Записати емпіричний ризик простої моделі й обчислити його градієнт аналітично, чисельно та через autograd, отримавши збіжні результати.
Підготовка до заняття
Виконайте до початку заняття: аудиторного часу на встановлення не передбачено.
-
Python 3.10 або новіший. Перевірте:
python3 --version. -
Віртуальне середовище й пакети. З кореня вашого репозиторію:
python3 -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install numpy torch matplotlib jupyterPyTorch із підтримкою GPU встановлюється окремою командою під вашу платформу: візьміть її на pytorch.org/get-started. Підтримка GPU для цього заняття не обов'язкова, але знадобиться з Практичного заняття 6.
-
Репозиторій. Ви отримаєте запрошення до репозиторію
practices-<ваш логін пошти НаУКМА>. Прийміть його й склонуйте репозиторій. Створіть текуP01/. -
Повторіть Лекцію 1, зокрема формальну постановку задачі навчання: ризик, емпіричний ризик, функція втрат. Завдання 5 спирається саме на неї.
Якщо запрошення до репозиторію не надійшло, напишіть викладачу практичних до заняття, а не під час нього.
Завдання
Усі файли створюються у теці P01/ вашого репозиторію й нумеруються за порядком: 01_, 02_ і так далі.
1. Перевірка середовища (10 хв)
Файл: P01/01_env_check.py
Напишіть скрипт, який друкує:
- версію Python, NumPy і PyTorch;
- доступний обчислювальний пристрій:
cuda,mpsабоcpu; - результат найпростішої тензорної операції на цьому пристрої, щоб підтвердити, що він справді працює.
Пристрій визначайте явно, а не припускайте:
import torch
device = (
"cuda" if torch.cuda.is_available()
else "mps" if torch.backends.mps.is_available()
else "cpu"
)
Зафіксуйте зерно генератора випадкових чисел (numpy.random.default_rng(0), torch.manual_seed(0)) і поясніть у коментарі, чому відтворюваність важлива для порівняння результатів між запусками.
2. Вектори, матриці та операції NumPy (15 хв)
Файл: P01/02_numpy_basics.py
- Створіть матрицю
Aрозміру 4×3 і матрицюBрозміру 3×5 з випадковими числами. - Обчисліть матричний добуток
A @ B. Перед запуском запишіть у коментарі очікувану форму результату, потім перевірте. - Покажіть на власному прикладі різницю між
A * AіA @ A.T: що означає кожна операція й чому форми результатів різні. - Обчисліть середнє значення матриці
Aтрьома способами: по всій матриці, по рядках і по стовпцях. Поясніть у коментарі, що саме робить аргументaxis. - Пастка трансляції. Візьміть вектор
vдовжини 3 і векторwдовжини 4. СпробуйтеA + vіA + w. Один вираз спрацює, другий викине помилку. Поясніть обидва результати через правила трансляції розмірностей, а не через текст повідомлення про помилку.
3. Тензори PyTorch і спільна пам'ять (15 хв)
Файл: P01/03_torch_tensors.py
- Перетворіть масив NumPy на тензор двома способами:
torch.from_numpy(arr)іtorch.tensor(arr). - Змініть один елемент вихідного масиву NumPy. Надрукуйте обидва тензори.
- Поясніть спостережену різницю у коментарі. Один зі способів створює тензор, що поділяє пам'ять із масивом, другий копіює дані. Визначте, який саме, і сформулюйте, коли ця різниця може призвести до помилки в реальному коді.
- Перенесіть тензор на доступний пристрій через
.to(device)і назад наcpu. Спробуйте виконати операцію між тензором на пристрої й тензором наcpu; зафіксуйте, що станеться. - Покажіть різницю між
float32іfloat64: створіть той самий тензор обох типів, порівняйтеelement_size()і результат ділення, де проявляється похибка округлення.
Типовий тип у PyTorch це
float32, а у NumPyfloat64. Мовчазне перетворення між ними стає джерелом розбіжностей у результатах, тому тип варто задавати явно.
4. Автоматичне диференціювання (20 хв)
Файл: P01/04_autograd.py
На цьому кроці autograd цікавить нас як інструмент: що саме він обчислює й як переконатися, що обчислює правильно. Механізм зворотного поширення розбирається на Лекціях 2 і 5.
-
Створіть скалярний тензор
xзі значенням 2.0 іrequires_grad=True. -
Обчисліть
y = x**3 + 5*x, викличтеy.backward(), надрукуйтеx.grad. -
Виведіть похідну аналітично на папері й запишіть її в коментарі. Порівняйте з отриманим значенням.
-
Повторіть для функції двох змінних, наприклад
f(x, y) = x**2 * y + sin(y), і перевірте обидві часткові похідні. -
Перевірка скінченними різницями. Реалізуйте функцію
def numeric_grad(f, x, eps=1e-5): return (f(x + eps) - f(x - eps)) / (2 * eps)і порівняйте її результат із
x.grad. Підберітьepsтак, щоб розбіжність була найменшою, і поясніть у коментарі, чому надто малеepsпогіршує результат. -
Загорніть обчислення у
with torch.no_grad():і покажіть, що градієнт більше не накопичується. Поясніть, навіщо цей режим потрібен.
Градієнти у PyTorch накопичуються: другий виклик
backward()додасться до наявногоx.grad. Перед новим обчисленням викликайтеx.grad = Noneабоx.grad.zero_(). Це джерело помилок, які не падають, а тихо дають неправильні числа.
5. Емпіричний ризик і три способи взяти градієнт (10 хв)
Файл: P01/05_empirical_risk.py
Це завдання прив'язує інструменти заняття до формалізму Лекції 1.
Візьміть лінійну модель з одним параметром, h(x) = w·x, і квадратичну функцію втрат. Емпіричний ризик на вибірці з n точок:
- Згенеруйте 50 точок за правилом y = 3x + ε, де ε це невеликий гаусів шум.
- Обчисліть
у точціw = 0.5трьома способами й переконайтеся, що вони збігаються:- явним циклом по точках;
- векторизованою операцією NumPy без циклу;
- тензорною операцією PyTorch.
- Обчисліть
у тій самій точці трьома способами:- аналітично (виведіть формулу самостійно й запишіть її в коментарі);
- скінченними різницями з попереднього завдання;
- через
backward().
- Надрукуйте всі три значення поруч і зафіксуйте розбіжність між ними.
- Побудуйте графік
дляwвід 0 до 6 і позначте на ньому точку мінімуму. Збережіть якP01/risk_curve.png.
Питання для роздумів (відповіді у P01/README.md, по кілька речень на кожне):
- Чому векторизована реалізація швидша за цикл, хоча виконує ту саму кількість арифметичних операцій?
- Три оцінки градієнта дали різні числа. Яка з них точна за побудовою, яка наближена принципово через сам метод, і яка математично точна, але обмежена розрядністю чисел? Найважливіше: автоматичне диференціювання не є чисельним, поясніть, чим воно відрізняється від скінченних різниць.
- Градієнт у точці
w = 0.5виявився від'ємним. Що це говорить про напрям, у якому треба змінюватиw, щоб зменшити ризик, і чому знак саме такий?
Домашнє завдання та відео
Дедлайн: за 24 години до початку Практичного заняття 2 за вашим розкладом.
- Завершіть завдання, які не встигли в аудиторії (зазвичай це завдання 5).
- Запишіть Loom-відео до 5 хвилин і покладіть посилання на нього у
P01/video.txt.
Що має бути на відео
Відео підтверджує, що код написали й розумієте ви. П'ять хвилин це мало, тому показуйте головне, а не все підряд.
- Запуск. Коротко покажіть, що
01_env_check.pyі05_empirical_risk.pyсправді працюють, разом із графіком ризику. - Пастка трансляції (завдання 2). Поясніть, чому
A + vспрацював, аA + wні. Обґрунтуйте правилами трансляції розмірностей. - Спільна пам'ять (завдання 3). Покажіть різницю між двома способами створення тензора й назвіть ситуацію, у якій вона призведе до помилки.
- Автоматичне диференціювання (завдання 4). Назвіть значення, яке дав
backward(), і вашу аналітичну похідну. Поясніть, чим автоматичне диференціювання відрізняється від скінченних різниць. - Знак градієнта (завдання 5). Скажіть, у який бік треба змінювати
w, щоб зменшити ризик, і чому знак саме такий.
Вимоги до запису
- Ваш голос і екран. Обличчя не обов'язкове.
- Українською.
- До 5 хвилин. Після шостої хвилини відео не переглядається.
- Посилання відкривається без авторизації: перевірте його в режимі анонімного перегляду браузера.
Пояснення, а не переказ. Зачитування коментарів із коду вголос не є поясненням. На відео має звучати причина: чому результат саме такий, а не лише який він. Робочий код без розуміння на відео прирівнюється до невиконаної роботи, як того вимагає розділ силабуса про використання інструментів ШІ.
Здача
- Усі файли лежать у теці
P01/вашого репозиторіюpractices-<логін>. P01/README.mdмістить відповіді на питання для роздумів і перелік того, що не вдалося завершити, якщо таке є.P01/video.txtмістить посилання на Loom-відео.
git add P01/
git commit -m "P01: середовище, NumPy, PyTorch, autograd"
git push
Незавершена робота, здана вчасно з переліком того, що не вийшло, оцінюється вище за мовчазну відсутність файлів.
Запізнення. Кожна розпочата доба після дедлайну знижує оцінку за заняття на 25%. Через три доби робота не приймається без попереднього узгодження. Узгоджувати перенесення треба до дедлайну, а не після нього.
Критерії оцінювання
| Складова | Вага |
|---|---|
| Участь у занятті та коміт наприкінці пари | 15% |
| Завдання 1-3: середовище, NumPy, тензори PyTorch | 20% |
| Завдання 4: autograd і перевірка скінченними різницями | 20% |
| Завдання 5: емпіричний ризик і три способи взяти градієнт | 20% |
Пояснення в коментарях і відповіді в README.md |
10% |
| Пояснення й демонстрація у Loom-відео (до 5 хв) | 15% |
| Разом | 100% |
Пояснення оцінюються нарівні з кодом. Робочий код без коментаря, що показує розуміння, отримує неповний бал: на захисті потрібно вміти пояснити кожен результат.
Відсутнє відео коштує більше за власні 15%. Решта складових оцінюється за тим, що викладач бачить у репозиторії, і без вашого пояснення сумнівні місця тлумачаться не на вашу користь.
За силабусом усі 16 практичних занять разом складають 40% підсумкової оцінки.
Що далі
Практичне заняття 2 реалізує градієнтний спуск та його варіації «з нуля». Завдання 5 цього заняття дає йому вихідну точку: там ви обчислили градієнт емпіричного ризику в одній точці, далі ви побудуєте з цього ітеративний метод і порівняєте траєкторії збіжності.