У кінці теми 18 ми поставили питання й лишили його без відповіді. Усі девʼять архітектур, які ми розібрали, — від AlexNet 2012 року до EfficientNet 2019-го — стоять на одному припущенні: сусідні пікселі повʼязані, далекі — ні. А що буде, якщо цю ставку зняти? Якщо дозволити кожній частині зображення дивитися одразу на будь-яку іншу, без вікна й без сусідства? Відповідь називається увага, і в цій темі ми розберемо саму операцію: звідки береться її формула, чому в ній стоїть ділення на корінь, що вона вміє задарма і за що доводиться платити.
СпадокЩо згортка вирішила за нас
Повернімось до теми 06. Там ми брали повнозвʼязну мережу, показували, що на зсунутих предметах вона падає до рівня вгадування, і вводили згортку як ліки. Ліки подіяли: та сама задача, у тринадцять разів менше ваг, точність на зсунутих предметах удвічі вища.
Але кожні ліки — це вибір, і за нього чимось платять. Згортка не просто «краще працює». Вона ухвалює за нас три рішення, ще до того, як мережа побачить перший приклад. Ось вони.
| рішення | що воно каже | що з нього випливає |
|---|---|---|
| Локальність | значення має лише те, що лежить у вікні 3×3 | далекий звʼязок треба збирати з багатьох шарів |
| Спільні ваги | те саме ядро працює в кожній точці кадру | ознака, вивчена в кутку, працює по всьому кадру |
| Порядок | піксель знає, хто його лівий сусід, а хто верхній | геометрія кадру закладена в саму операцію |
Третє рішення варто розжувати, бо його майже ніколи не називають окремо. Коли ядро 3×3 множить свою верхню ліву клітинку на верхній лівий піксель вікна, воно тим самим знає, що цей піксель — верхній лівий. Це знання не вивчене, воно вбудоване в те, як записано операцію. Згортка отримує геометрію кадру безкоштовно, разом із формулою.
Три рішення разом і є та ставка, про яку йшлося в кінці теми 18. Вона виявилась блискучою — але лишається ставкою: локальність не є властивістю зображень, вона є нашим припущенням про них. У цій темі подивимось на ті самі три рішення з іншого боку — як на обмеження. Почнемо з першого.
МежаДе локальність заважає
Уяви фотографію кімнати: у лівому нижньому кутку склянка, у правому верхньому — вона ж у дзеркалі. Щоб зрозуміти, що це відображення, мережі треба звести обидва кутки в одне число. Скільки на це потрібно згорткових шарів?
У темі 07 ми вводили рецептивне поле — ділянку входу, здатну вплинути на одне число на виході. Для згортки 3×3 із кроком 1 воно росте на два пікселі за шар: перший шар бачить 3×3, другий — 5×5, третій — 7×7. Формула:
Слово за словом: кількість шарів L множимо на два й додаємо одиницю — це сторона квадрата вхідних пікселів, які можуть вплинути на одне число після цих шарів. Множник два — бо кожен шар додає по пікселю з кожного боку; одиниця — бо нульовий шар бачить сам себе.
Наші фігури — 28×28. Підставляємо: щоб рецептивне поле накрило 27×27, тобто майже весь кадр, треба L = 13. Тринадцять шарів згортки, щоб перший піксель нарешті «побачив» останній. Це не оцінка, а арифметика: підстав L = 13 у формулу вище й дістанеш 2·13 + 1 = 27.
Проти цього — операція, яку ми зараз розберемо. Вона накриває весь кадр з першого шару, бо в неї взагалі немає поняття вікна. І це не хитрість: далі ми побачимо, скільки саме за це платять.
Чесна поправка: на практиці тринадцять шарів 3×3 поспіль ніхто не ставить — пулінг і крок 2 подвоюють рецептивне поле разом із кожним зменшенням карти. Але суть не міняється: далекий звʼязок у згортці доводиться будувати, а не брати. Він збирається через ланцюжок посередників, і на кожній ланці частина інформації розмивається.
Локальність проти всеосяжності
Ліворуч — рецептивне поле центрального нейрона після заданої кількості згорток 3×3. Праворуч — та сама сітка з увагою, яка накриває все з першого шару, і ціна цього під нею. Тягни повзунок і дивись, коли квадрат дістане до країв — і скільки пар за це платить сусідня панель.
padding=1, один канал.
«Ваг у стосі» — 9·L, тобто скільки ядерних чисел довелося поставити,
щоб дотягнутись. Увага накриває 100 % кадру при будь-якому положенні повзунка —
але рахує 49² = 2 401 пару патчів, і рахує їх заново для кожного
зображення. Обидві половини правди на одній картинці: згортка платить шарами,
увага — парами.ІдеяХай кожен сам обере, з ким рахуватися
Слово «увага» тут заважає більше, ніж допомагає: воно натякає, що мережа кудись дивиться й чогось хоче. Нічого такого не відбувається. Точне формулювання вміщається в одне речення: для кожної позиції ми рахуємо зважену суму всіх позицій, і самі ваги теж рахуються з даних.
Перша половина — «зважена сума всіх позицій» — це те, що робить і згортка: множимо сусідів на числа й додаємо. Різниця в тому, що сусідів тепер не девʼять, а всі. Друга половина — і саме вона нова — ваги не фіксовані. У згортці ядро вивчається один раз, і далі те саме число множить верхнього сусіда в кожній точці кадру. В увазі ваг не існує заздалегідь: вони обчислюються щоразу заново, для конкретного зображення.
Далі — три слова, які треба ввести, бо без них не читається жоден код. Кожна позиція отримує три різні описи себе, і кожен потрібен для свого:
| назва | питання, на яке відповідає | де вживається |
|---|---|---|
| Запит Q (query) | що я шукаю? | у позиції, яка збирає інформацію |
| Ключ K (key) | що я можу запропонувати? | у позиціях, які інформацію віддають |
| Значення V (value) | що саме я віддам, якщо мене оберуть? | там само |
Побутова аналогія — бібліотечний каталог. Ти приходиш із запитом («книжка про мости»), у кожної картки є ключ (тема, за якою її знайдуть) і значення (сама книжка). Збіг запиту з ключем вирішує, наскільки ця картка тобі потрібна.
Де аналогія бреше. У бібліотеці ти береш одну книжку — ту, що збіглась найкраще. Увага не бере одну: вона бере всі, змішує їх у пропорції «наскільки збіглось» і віддає суміш. Навіть найдальша картка отримує ненульову частку. Правильний образ — не пошук, а усереднення з нерівними вагами.
І ще одне, важливе для наступних розділів. Три описи — запит, ключ, значення — отримують із того самого вектора позиції, помноживши його на три різні матриці ваг. Оці матриці й є те, що вчиться. Самі ваги уваги не вчаться ніколи; вчиться лише те, як їх рахувати.
ФормулаФормула по кроках
Ось вона повністю. Не лякайся — далі кожен символ буде розібраний, а потім ми порахуємо все руками на чотирьох числах.
Що є що:
- Q, K, V — три таблиці чисел: рядків стільки, скільки токенів (49), колонок — скільки чисел в описі токена (32). Рядок — це один токен;
- Kт — та сама таблиця, покладена набік: рядки стали колонками. Значок «т» читається «транспонована»;
- · — множення матриць: клітинка результату — сума добутків рядка на колонку;
- d — довжина опису токена, у нас 32. √d — квадратний корінь із неї, тобто число, яке при множенні саме на себе дає 32 (приблизно 5.66);
- softmax — функція з курсу машинного навчання: перетворює рядок довільних чисел на набір невідʼємних часток, що в сумі дають одиницю. Що більше вхідне число, то більша частка.
Тепер по кроках. Візьмемо чотири токени по два числа — так усі числа влізуть на екран і їх можна перевірити олівцем. Матриці ваг візьмемо одиничні, тобто Q, K і V просто дорівнюють входу. Це законний окремий випадок формули, а не спрощення: справжні матриці лише повертають і розтягують ці вектори, а вся механіка нижче лишається та сама.
Q = K = V = X. Кожен токен виступає одночасно і як запит, і як ключ, і як значення. Саме тому операція зветься самоувагою (self-attention): токени дивляться самі на себе, а не на якийсь інший набір.
Множимо Q на K набік. Клітинка (i, j) — це скалярний добуток токена i на токен j: перемножили перші числа, перемножили другі, склали. Наприклад, t1·t3 = 2·2 + 0·2 = 4. Що більший добуток, то краще збіглись напрямки.
Рядок t1 каже, наскільки перший токен збігається з кожним із чотирьох. Найкраще — із собою й із t3 (по 4), найгірше — із t4 (мінус 4: вони дивляться в протилежні боки).
Розмірність d = 2, отже √2 ≈ 1.414. Ділимо кожну клітинку на це число. Навіщо — цілий наступний розділ; поки просто зроби.
Кожен рядок окремо перетворюємо на частки. Для рядка t1: підносимо e (число 2.718…) до степеня кожного елемента — виходить 16.92 · 1.00 · 16.92 · 0.059 — і ділимо кожне на їхню суму 34.90.
Оце і є матриця уваги. Рядок t1 читається так: «збираючи свій новий опис, перший токен візьме 48.5 % від себе, 48.5 % від t3, 2.9 % від t2 і майже нічого від t4». Зверни увагу на рядок t4: він майже цілком складається з самого себе (93.8 %) — бо ні з ким не збігся.
Тепер множимо матрицю уваги на V. Кожен новий токен — це суміш усіх старих у щойно порахованих пропорціях. Для t1:
В останній таблиці видно всю ідею. Токен t1 був [2, 0], а став [1.94, 1.03] — його підтягнуло до t3, з яким він збігся. Токен t4 не збігся ні з ким і майже не змінився. Ніхто нічого не вчив: усі ці числа вийшли з самого входу, за один прохід.
Увага по кроках, усі числа на екрані
Той самий приклад: чотири токени по два числа. Тисни «крок» і проходь усі пʼять етапів формули. Повзунок рухає четвертий токен від −2 (як у тексті вище) до +2, де він стає копією першого. Дивись, що від цього робиться з першим рядком матриці уваги.
А тепер те саме на справжніх даних: наша фігура 28×28, порізана на 49 патчів 4×4, і матриця уваги 49×49 — вона теж уміщається на екран.
Матриця уваги: хто в кого бере інформацію
Ліворуч — сітка 7×7 патчів фігури, праворуч — матриця уваги 49×49: рядок i показує, звідки бере інформацію патч i. Наведи мишу на рядок матриці або на патч ліворуч. Повзунок міняє дільник у формулі.
LayerNorm у справжній
мережі). Q = K = V = сам патч, тобто матриці ваг одиничні й нічого не навчено.
Ентропія рядка міряє, наскільки увага розмазана: 3.892 — рівномірно по всіх 49,
нуль — увесь вміст узято з одного патча. Рівномірна вага для 49 патчів —
0.0204; «середній максимум» — найбільша вага в рядку, усереднена по всіх
49 рядках. √d тут дорівнює 4.Навіть без жодного навчання видно головне: рядок патча, що лежить на фігурі, підсвічує інші патчі фігури — по всьому кадру, зокрема ті, що на протилежному боці. Ніякого вікна тут немає. Це та сама всеосяжність із розділу 02, тільки тепер її видно.
МасштабНавіщо ділити на корінь із d
У формулі стоїть / √d, і в кроці 3 ми його просто зробили. Тепер розберемось, звідки він, — бо це один із тих випадків, коли крихітна деталь вирішує, працюватиме навчання взагалі чи ні.
Беремо два випадкові вектори довжини d — кожне число незалежне, із середнім нуль і одиничним розкидом (саме так виглядають ваги на початку навчання). Скалярний добуток — це сума d поелементних добутків. Середнє такої суми нуль, а дисперсія — міра розкиду — дорівнює рівно d: розкид суми незалежних доданків дорівнює сумі їхніх розкидів, кожен дає одиницю, доданків d штук. Отже, типовий розмір добутку росте як √d: при d = 4 це приблизно 2, при d = 256 — приблизно 16.
А softmax підносить e до степеня кожного числа. Різниця у входах на 16 перетворюється на різницю у виходах у e16 ≈ 9 мільйонів разів: один елемент забирає майже всю вагу.
Це і поміряно. Девʼять тисяч вісімсот випадкових рядків по 49 елементів, чотири розмірності:
| d | дисперсія QKᵀ | макс. вага без ділення | з діленням | ентропія без | з діленням |
|---|---|---|---|---|---|
| 4 | 3.99 | 0.300 | 0.123 | 2.599 | 3.442 |
| 16 | 16.06 | 0.599 | 0.126 | 1.284 | 3.427 |
| 64 | 63.96 | 0.798 | 0.126 | 0.555 | 3.427 |
| 256 | 255.50 | 0.903 | 0.127 | 0.249 | 3.425 |
Друга колонка підтверджує теорію до другого знака: дисперсія дорівнює d. Третя — головна: без ділення при d = 256 один елемент забирає 90 % ваги рядка з 49. Увага перестає бути зваженою сумою й вироджується у вибір одного. Четверта показує, що ділення тримає максимум коло 0.12–0.13 при будь-якій розмірності.
Ентропія в останніх колонках міряє «розмазаність» розподілу: 3.892 — ідеально рівномірно по 49 позиціях, нуль — уся вага в одному. Без ділення при d = 256 вона падає до 0.249.
І чому це вбиває навчання
Виродження не просто негарне — воно зупиняє навчання. Щоб градієнт пройшов крізь softmax, зміна входу має міняти вихід. Наскільки — показує сума p(1−p) по рядку: якщо всі частки коло нуля або коло одиниці, цей добуток теж коло нуля, і сигнал не проходить.
| d | сума p(1−p) без ділення | з діленням | у скільки разів гірше |
|---|---|---|---|
| 4 | 0.827 | 0.948 | 1.1 |
| 16 | 0.534 | 0.949 | 1.8 |
| 64 | 0.281 | 0.950 | 3.4 |
| 256 | 0.138 | 0.950 | 6.9 |
Кожне збільшення розмірності вчетверо приблизно вдвічі зменшує здатність softmax пропускати градієнт. З діленням на √d ця величина стоїть на 0.95 при будь-якій розмірності — рівно тому, що дисперсія після ділення завжди одиниця. У цьому й уся ідея: ділення робить масштаб оцінок незалежним від розмірності.
Що робить ділення на корінь
Дві криві: як росте типовий максимум у рядку softmax зі зростанням розмірності — без ділення й із діленням на √d. Числа рахуються тут-таки, у браузері, на випадкових векторах. Тягни повзунок розмірності й дивись, коли увага перестає бути сумою.
ГоловиКілька голів
У розібраній формулі є мовчазне обмеження. Матриця уваги одна на всі числа опису. Якщо токен вирішив узяти 48 % від сусіда, то він бере 48 % від усіх тридцяти двох чисел цього сусіда. Взяти колір звідси, а форму звідти не можна: пропорція одна на весь вектор.
Ліки прості: поріж опис на шматки й порахуй увагу в кожному окремо. Було 32 числа й одна матриця уваги — стало чотири шматки по 8 чисел і чотири незалежні матриці. Кожен шматок називають головою (head), а конструкцію — багатоголовою увагою (multi-head attention). Результати склеюють назад у 32 числа й проганяють через одну вихідну матрицю.
Тепер найцікавіше — скільки це коштує. Порахуємо параметри руками. Матриць чотири: три вхідні (Wq, Wk, Wv) і одна вихідна, кожна розміром d×d, і в кожної є зсув на d чисел:
Підставляємо d = 32: 4·1024 + 128 = 4224. А тепер той самий рахунок
для восьми голів. Кожна голова має свої матриці розміром d×(d/8)… але їх вісім,
і 8 · d · (d/8) = d·d. Те саме число. Заміряно на
nn.MultiheadAttention:
| d | голів | розмір голови | ручний рахунок | sum(p.numel()) |
|---|---|---|---|---|
| 32 | 1 | 32 | 4 224 | 4 224 |
| 32 | 4 | 8 | 4 224 | 4 224 |
| 32 | 8 | 4 | 4 224 | 4 224 |
| 768 | 1 | 768 | 2 362 368 | 2 362 368 |
| 768 | 12 | 64 | 2 362 368 | 2 362 368 |
Це й є відповідь на питання «чи не те саме одна велика голова?». Ні, і не тому, що параметрів більше — їх рівно стільки ж. Різниця в операції: одна голова рахує одну зважену суму, вісім голів — вісім різних. За ті самі ваги отримуємо вісім незалежних поглядів замість одного.
Це видно навіть на випадкових вагах. При чотирьох головах і розмірності 32 кожен токен має в середньому 3.94 різних цілі з чотирьох можливих, а взаємна кореляція матриць уваги — −0.012, тобто фактично нуль. Голови незалежні за побудовою, ще до навчання. (В інтерактиві 5 нижче та сама величина виходить меншою — 3.49 з 4, — бо там опис патча вдвічі коротший, 16 чисел замість 32, і на голову лишається по чотири. Це не суперечність, а той самий ефект, з якого починається наступна врізка.)
Кілька голів дивляться в різні місця
Один обраний патч (тягни повзунок) і те, куди він дивиться кожною зі своїх голів. Перемикай кількість голів і стеж за лічильником параметрів: він не міняється.
ПорядокУвага не бачить порядку
Тепер головне відкриття теми. Воно доводиться в три рядки, без навчання, і з нього випливає все, що буде далі.
Подивись іще раз на формулу. Де в ній сказано, що токен №1 стоїть перед токеном №2? Ніде. Скалярний добуток не знає, звідки взялися вектори; softmax працює по рядку; значення підсумовуються — а сума не залежить від порядку додавання.
Звідси випливає точне твердження. Переставмо токени на вході в будь-якому порядку. Тоді вихід переставиться рівно так само, і більше не зміниться нічого. Ця властивість зветься еквіваріантністю щодо перестановки (permutation equivariance).
Перевіримо. Беремо 49 токенів нашої фігури, беремо
nn.MultiheadAttention зі щойно створеними випадковими вагами
й рахуємо два числа: вихід від перемішаного входу і перемішаний вихід
від нормального входу. Якщо твердження правильне, вони мають збігтися.
| операція | найбільша різниця | що це означає |
|---|---|---|
| увага без позиційного | 1.8·10⁻⁷ | нуль із точністю float32 |
| увага з позиційним | 0.135 | порядок тепер видно |
| згортка Conv1d(3) | 1.700 | порядок було видно завжди |
Перший рядок — і є доказ. 1.8·10⁻⁷ — не «мала різниця», а арифметичний шум float32 при виході масштабу 0.82: відносна похибка дві десятимільйонні. Увага не «майже не помічає» перестановку — вона не помічає її взагалі.
Третій рядок для контрасту: та сама перевірка на згортці дає 1.700 — величину порядку самого сигналу. Згортка ловить перестановку негайно.
Чому це руйнує класифікацію
Ось наслідок, який робить абстракцію відчутною. Візьмемо два зображення: маленька фігура у верхньому лівому куті та вона ж у нижньому правому. Друге отримано з першого чистою перестановкою патчів — жоден піксель не змінився, змінилися лише їхні місця. Пропускаємо обидва через увагу, усереднюємо 49 виходів і подаємо в лінійний класифікатор:
Це не результат навчання й не питання кількості даних. Мережа без позиційного кодування ніколи не навчиться відрізняти «фігура вгорі» від «фігура внизу», скільки їй прикладів не показуй. Вихід у неї буквально той самий.
Перестановка: головна демонстрація теми
Зліва — фігура, порізана на 49 патчів. Тисни «перемішати» і дивись на число внизу: наскільки вихід перемішаного відрізняється від перемішаного виходу. Перемкни позиційне кодування — і число ожине.
torch (там float32 і 1.8·10⁻⁷).
Згортка по токенах — фіксоване ядро з трьох чисел.ГеометріяПозиційне кодування
Раз увага не знає порядку, порядок треба їй сказати. Спосіб, який виявився робочим, дивовижно грубий: до кожного токена просто додають вектор, який залежить від його номера. Не множать, не приклеюють збоку — додають, число до числа.
Тобто якщо токен описується 32 числами, то вектор позиції теж має 32 числа, і вони додаються поелементно. Після цього два патчі з однаковим вмістом, але з різних місць кадру, стають різними векторами — і скалярний добуток нарешті може їх розрізнити.
Додавання спочатку виглядає підозріло: ми ж псуємо вміст! Відповідь така: розмірність 32 (а в справжніх мережах 768) — це багато місця. Мережа може відвести частину напрямків під «що це» і частину під «де це» й навчитися читати їх окремо. Ніхто їй цього не наказує — вона просто має таку можливість.
Два способи взяти вектор позиції
| навчуване | синусоїдальне | |
|---|---|---|
| Що це | таблиця «номер → вектор», ініціалізована випадково й навчена разом з усім | вектор, порахований формулою з синусів і косинусів різної частоти |
| Параметрів | кількість позицій × d | нуль |
| Нові довжини | не працює: для позиції 200 рядка немає | працює: формула визначена для будь-якого номера |
| Де вживають | ViT і майже всі трансформери зору | початковий Transformer, частина мовних моделей |
Синусоїдальний варіант виглядає елегантніше, але в зорі переміг навчуваний:
кількість патчів фіксована розміром входу, розтягуватись нікуди не треба. Скільки
за нього платять — порахуємо на справжній моделі. Беремо vit_b_16
із torchvision, збираємо з weights=None (нічого
не завантажується) і рахуємо:
Сто пʼятдесят одна тисяча ваг із вісімдесяти шести мільйонів. Дві тисячні частки моделі. І це вся геометрія, яку модель має — усе, що вона знає про те, що ліворуч, а що праворуч, сидить у цих 0.175 %. Порівняй зі згорткою, де геометрія роздана безкоштовно в кожному з мільйонів ядерних чисел.
Чи потрібне позиційне кодування завжди? Правило просте й випливає з розділу 07: воно допомагає рівно тоді, коли положення має значення. Якщо клас предмета не залежить від того, де предмет лежить у кадрі, кодування додає ваги, які нема чому вчити, — і на малих даних це може навіть заважати. Але щойно задача починає залежати від розташування — «фігура вгорі проти фігури внизу» з попереднього розділу — без кодування модель не працює взагалі, а не «гірше».
ЦінаЦіна квадратична
Тепер рахунок, який визначає все проєктування трансформерів зору. Матриця уваги має розмір «токенів × токенів». При n токенах у ній n² клітинок, і кожну треба порахувати. Подвоїв кількість токенів — учетверо збільшив роботу.
Для кадру 28×28 усе залежить від одного числа — розміру патча:
| патч | токенів | пар уваги | множень у матриці | множень у проєкціях |
|---|---|---|---|---|
| 14×14 | 4 | 16 | 1 024 | 16 384 |
| 7×7 | 16 | 256 | 16 384 | 65 536 |
| 4×4 | 49 | 2 401 | 153 664 | 200 704 |
| 2×2 | 196 | 38 416 | 2 458 624 | 802 816 |
Розмір патча зменшився в сім разів — з 14 до 2, — а кількість пар зросла з 16 до 38 416, тобто в 2 401 раз. Ось за що платять дрібними патчами.
Дві останні колонки варто прочитати окремо, бо в них є перелом. «Множення в проєкціях» — вартість трьох матриць Q, K, V і однієї вихідної; вона росте лінійно за кількістю токенів. «Множення в матриці» ростуть квадратично. При 4 токенах проєкції коштують у 16 разів більше, а при 196 токенах — уже втричі менше. Точка рівноваги:
Тобто при розмірності 32 матриця уваги стає дорожчою за проєкції, коли токенів більше 64. До цієї межі квадратичність нікого не турбує; після неї вона починає визначати все.
Час на реальній машині це підтверджує — і показує, де саме починається
квадратичний режим. Прямий прохід nn.MultiheadAttention,
розмірність 64, один потік CPU:
| токенів | пар | час, мс | час × від 49 | пар × від 49 |
|---|---|---|---|---|
| 49 | 2 401 | 0.121 | 1.0 | 1 |
| 196 | 38 416 | 0.522 | 4.3 | 16 |
| 784 | 614 656 | 5.930 | 48.9 | 256 |
| 1 568 | 2 458 624 | 41.592 | 342.8 | 1 024 |
| 3 136 | 9 834 496 | 195.776 | 1 613.7 | 4 096 |
Абсолютні мілісекунди в тебе будуть інші — вони залежать від того, чим ще зайнята машина. Стале тут співвідношення, і воно каже ось що. На малих числах час росте повільніше за кількість пар: від 49 до 196 токенів пар стало в 16 разів більше, а часу — лише в 4.3. Квадратичність не зникла: на таких розмірах помітну частку зʼїдають накладні витрати виклику, а не множення. Зате від 784 токенів іде чистий квадратичний режим — подвоєння токенів учетверо збільшує кількість пар і в пʼять-сім разів час. На 3 136 токенах один прохід уваги займає вже пʼяту частину секунди.
Ціна: розмір патча як головна ручка
Два повзунки: розмір патча (він задає кількість токенів) і робоча розмірність. Стовпчики показують, куди йдуть множення — у матрицю уваги чи в проєкції. Знайди положення, де вони міняються місцями.
ПорівнянняУвага проти згортки: чесне порівняння
Тепер можна покласти дві операції поруч. Головне питання не «яка краща», а що кожна дає задарма, а що доводиться вчити.
| згортка | увага | |
|---|---|---|
| Локальність | задарма: вікно 3×3 вбудоване | треба вивчити з даних, якщо вона потрібна |
| Далекий звʼязок | треба будувати: 13 шарів на кадр 28×28 | задарма з першого шару |
| Порядок і геометрія | задарма: закладений у форму операції | треба додати окремо, коштує 0.175 % ваг |
| Спільні ваги по кадру | задарма: те саме ядро скрізь | задарма: ті самі матриці для всіх токенів |
| Ваги залежать від входу | ні: ядро те саме для всіх зображень | так: матриця уваги рахується заново щоразу |
| Ціна від розміру входу | лінійна | квадратична за кількістю токенів |
Перший і третій рядки — це і є відповідь на питання, чому трансформерам потрібно більше даних. Згортка приходить із двома готовими правилами про світ: «важливе поруч» і «ось де ліворуч». Ці правила не безкоштовні в іншому сенсі — вони обмежують, — але вони правильні для зображень, і мережа отримує їх задарма, ще до першого прикладу.
Увага не приходить ні з чим. Вона починає з чистого аркуша, на якому всі позиції рівноправні, і мусить вивести локальність із даних — тобто самотужки дійти до того, що сусідні патчі корисніші за далекі. Це можливо, але за це платять прикладами: правило, яке згортці подарували, трансформер має відкрити. Наскільки більше прикладів для цього треба й що буває, коли їх бракує, — із заміряними числами в темі 20.
Останній рядок таблиці — «ваги залежать від входу» — те, чого згортка не вміє взагалі. Ядро після навчання застигає: воно однакове для котика й для креслення. Матриця уваги перераховується для кожного зображення окремо, і в цьому її сила, яку ніяким збільшенням глибини не заміниш.
ІсторіяУвага не нова для зору
Легко подумати, що увага прийшла в зір із трансформерів у 2020 році. Насправді вона працювала всередині згорткових мереж на кілька років раніше — просто скромніше й під іншими назвами.
SE-блок (squeeze-and-excitation, 2017) — найпростіший із них. Після згорткового шару він стискає кожну карту ознак в одне число, проганяє їх через крихітну мережу й отримує по коефіцієнту на канал, на який цю карту множить. Це увага по каналах: мережа вирішує, які ознаки зараз важливі, і робить це залежно від конкретного зображення. Той самий SE-блок стоїть усередині EfficientNet і MobileNet-v3 із теми 15 — ти вже з ним працював, просто ми не називали це увагою.
Non-local блок (2018) — уже майже те, що ми розібрали: повна матриця «кожна позиція з кожною» всередині згорткової мережі. Її ставили одним-двома блоками в глибині, де карта ознак уже маленька й квадратична ціна терпима.
Тобто ідея визріла всередині згорткового світу як доповнення. Питання, яке поставив 2020 рік, було іншим і значно різкішим: а якщо згортки прибрати зовсім? Відповідь — наступна тема.
ПідсумокПідсумок і що далі
Операцію розібрано до останнього символу. Що варто винести:
- Увага — зважена сума всіх позицій, де ваги рахуються з самих даних. Запит, ключ і значення — три описи того самого токена. Вчаться матриці, якими їх отримують; самі ваги уваги не вчаться ніколи.
- Ділення на √d — не гіперпараметр. Дисперсія скалярних добутків дорівнює d, і без поправки softmax при d = 256 віддає 90 % ваги одному елементу, а здатність пропускати градієнт падає всемеро.
- Кілька голів нічого не коштують у параметрах — 4d² + 4d при будь-якій їх кількості. Вони дають не більше ваг, а більше різних зважених сум за ті самі ваги.
- Увага еквіваріантна щодо перестановки. Це не властивість навченої моделі, а наслідок форми формули: 1.8·10⁻⁷ проти 1.700 у згортки. Із цього випливає, що геометрію треба додавати окремо.
- Позиційне кодування — уся геометрія моделі, і коштує вона 0.175 % ваг ViT-B/16.
- Ціна квадратична за кількістю токенів. Патч 2×2 на кадрі 28×28 дає 38 416 пар замість 16. Розмір патча — головна ручка вартості.
І головне про метод. Усі шість пунктів вище перевіряються без жодного навчання — випадковими вагами, за секунди. Це рідкість: більшість тверджень про мережі доводиться перевіряти прогонами, розкидом від зерна й трьома повтореннями, як у темі 18. Якщо твердження про архітектуру можна перевірити алгеброю — перевіряй алгеброю; це дешевше й надійніше за будь-який експеримент.
Останнє перед наступною темою: матриця уваги на ненавчених вагах майже
рівномірна. Заміряно на нашій фігурі з випадковими матрицями
Q, K, V —
такими, які стоять у щойно створеному nn.MultiheadAttention: ентропія
рядка 3.863 із максимальних 3.892, тобто 99.3 % від ідеально рівномірного
розподілу, а найбільша вага 0.034 проти рівномірних 0.020. Красиві карти уваги
зі статей — результат навчання, а не властивість операції.
Не сплутай це з інтерактивом 3: там матриці ваг одиничні, тобто патчі порівнюються самі з собою напряму, і розподіл виходить помітно гострішим: на кільці при дільнику 4.00 ентропія рядка № 10 — 2.718, а найбільша вага в рядку, усереднена по всіх 49 рядках, — 0.3700. Випадкова матриця перемішує вміст патча й тим згладжує збіги; одинична лишає їх як є. Конфігурація тут важить не менше за саму операцію, тож числа двох замірів порівнювати між собою не можна.
Місток до теми 20
Наступний крок очевидний: зібрати з операції цілу мережу — порізати зображення на патчі, додати позиційне кодування, покласти дюжину шарів уваги поспіль. Саме це зробили автори Vision Transformer, і саме це розбирає тема 20.
А вийде там несподіване. Мережа справді працює — але на наших даних програє згортковій, яка в рази менша, і розрив із кількістю прикладів не зменшується, а росте. Чому так — там, із числами.