Три попередні теми розібрали мережу на деталі. Тема 06 пояснила, чому
повнозвʼязна мережа не годиться для зображень; тема 07 дала згортковий шар — ядро, канали, stride,
padding; тема 08 дала пулінг. Питання
цієї теми одне: як із цих деталей складається мережа, яка справді працює —
що йде за чим, скільки разів, і що відбувається з числами всередині.
Відповідь буде неочікуваною двічі. У класичній згортковій мережі більшість ваг сидить зовсім не в згортках, а памʼять під час навчання їдять зовсім не ті шари, у яких ці ваги лежать. Обидва факти ми порахуємо руками на маленькій мережі, а потім перевіримо на VGG-16 — і числа збіжаться до частки відсотка.
ЗведенняТри деталі, одна мережа
Коротко — за що відповідає кожна деталь.
| Деталь | Що вона робить у мережі |
|---|---|
| Згортка | Шукає одну й ту саму дрібну прикмету в кожній точці зображення. Ядро — це кілька десятків ваг, які вивчаються; кожен вихідний канал відповідає одній вивченій прикметі. |
| Нелінійність | Розриває ланцюг: без неї дві згортки поспіль — це знову одна згортка. |
| Зменшення | Скорочує карту вдвічі по кожній стороні. Дає дві речі одразу: наступна згортка бачить учетверо більшу ділянку оригіналу, і рахувати її вчетверо дешевше. |
Друга деталь варта окремого слова, бо без неї конструкція розсипається. Дві згортки
поспіль математично дорівнюють одній згортці з іншим ядром — стос
глибиною десять шарів мав би рівно стільки ж сили, скільки один. Саме ReLU
між ними робить кожен наступний шар справді новим.
БлокТиповий блок
Одиниця, з якої збирають згорткову мережу, зветься блоком і складається з трьох кроків:
Спершу шукаємо прикмети згорткою, потім прибираємо відʼємні відгуки нелінійністю, потім удвічі зменшуємо карту. На виході — менша за розміром, але глибша за каналами карта ознак, і такий самий блок можна поставити ще раз. Порядок усередині блока не випадковий.
Це єдиний крок із вагами, і він мусить дивитись на найдетальнішу картинку, яка є на цьому рівні: після пулінгу половина деталей уже викинута. Спершу міряємо, потім спрощуємо.
Пулінг вибирає з кожного квадрата 2×2 одне число. Робити це має сенс тоді, коли в квадраті вже лежать відгуки прикмет, а не сира яскравість: тоді «взяти максимум» означає «прикмета в цій околиці десь є» — і саме це дає часткову терпимість до зсуву з теми 08.
Лишається питання, яке зазвичай оминають: а що буде, якщо переставити ReLU і Pool? Відповідь залежить від того, який саме пулінг стоїть у блоці, і різниця тут не в смаку, а в арифметиці.
Візьми квадрат 2×2 зі значеннями -5, 3, -1, 4.
Спершу ReLU, потім максимум: числа стають 0, 3, 0, 4,
максимум — 4. Навпаки: максимум сирих чисел 4, і ReLU(4) —
знову 4.
Це не збіг, а властивість: ReLU ніколи не переставляє числа за
величиною. Хто був більшим — лишається більшим (або обидва стають нулями).
Спершу ReLU, потім середнє: (0 + 3 + 0 + 4) / 4 =
1.75. Навпаки: (−5 + 3 − 1 + 4) / 4 = 0.25. Різниця в сім
разів.
Причина: у другому варіанті відʼємні числа встигають погасити додатні ще до обнулення. Сильний відгук прикмети в одному кутку квадрата гине, бо в сусідньому відгук був відʼємним. У першому варіанті гасити нічим — там уже нулі.
Висновок: для max-пулінгу порядок вільний, для avg-пулінгу — ні, і
правильний порядок саме Conv → ReLU → Pool. Одна схема на обидва випадки
зручніша за дві — тому в бібліотеках закріпилась саме вона.
Чи можна переставити ReLU і Pool
Ліворуч — карта ознак 6×6 одразу після згортки, з відʼємними числами. Далі два ланцюжки в різному порядку й карта різниці між ними.
ReLU перед пулінгом дає
більше або стільки ж.Conv і
ReLU зазвичай стоїть ще один шар — батчнорм (batch
normalization). Він належить не до конструкції мережі, а до її навчання, тому розбирається
в темі 11; поки просто знай, що повний сучасний блок виглядає як
Conv → BatchNorm → ReLU → Pool. Наша мережа обходиться без нього свідомо —
щоб рахунок параметрів лишався прозорим.СтосСтос блоків і правило подвоєння
Один блок бачить дуже мало: після нього один нейрон охоплює квадрат 4×4 пікселі оригіналу — цього вистачить на «тут є коротка риска», але не на «тут коло». Тому блоки ставлять один за одним, і з кожним блоком дві речі змінюються одночасно.
| Що | Куди йде | Чому |
|---|---|---|
| Просторовий розмір | падає вдвічі по стороні | це робить пулінг; заразом росте ділянка оригіналу, яку бачить один нейрон |
| Кількість каналів | росте вдвічі | різних складних прикмет буває більше, ніж різних простих |
Друга сходинка не автоматична — її ставить інженер, обираючи кількість вихідних каналів у кожній згортці. У першому блоці мережа шукає найпростіші речі: риску під одним кутом, під іншим, світлу пляму — таких прикмет мало. У третьому блоці прикмети складніші («кут», «дуга», «перехрестя»), і комбінацій із простих деталей значно більше. Щоб було де їх тримати, каналів дають більше.
64, 128, 256, 512 — це вся згорткова
частина VGG). Сучасні архітектури його часто порушують. Але як стартова конструкція
подвоєння працює добре.Тепер порахуємо, що саме подвоєння тримає сталим. Це найцікавіша його властивість, і її зазвичай формулюють неточно.
Карта ознак після першої згортки нашої мережі — 8 каналів по 28×28, тобто 8 × 28 × 28 = 6 272 числа. Після другої — 16 каналів по 14×14, тобто 3 136. Після третьої — 32 канали по 7×7, тобто 1 568.
Чисел стає удвічі менше з кожним блоком, а не стільки ж: сторона ділиться на два двічі (вчетверо менше клітинок), а каналів більшає лише вдвічі.
А ось скільки множень робить згортка. На кожну клітинку виходу вона перемножує ядро k × k на всі вхідні канали:
Тут H і W — висота й ширина карти на виході, C — кількість каналів на вході та виході, k — сторона ядра.
Друга згортка: 14 × 14 × 16 × 8 × 3 × 3 = 225 792 множення.
Третя згортка: 7 × 7 × 32 × 16 × 3 × 3 = 225 792 множення.
Однаково, до останньої одиниці. Причина видна з формули: H і W поділились на два кожен (разом на чотири), обидва C помножились на два кожен (теж на чотири).
Ось точне формулювання: правило подвоєння тримає сталим не кількість чисел, а обсяг роботи на шар. Кожен наступний шар коштує стільки ж, скільки попередній, зате памʼяті просить удвічі менше.
Конструктор мережі
Задай кількість блоків і скільки каналів дає перший із них. Схема перерахує форми наскрізь — і скаже, чи мережа взагалі збереться.
ФормиНаскрізний рахунок форм
Тепер проведемо крізь конкретну мережу одне зображення. Це головна навичка теми: взяти опис мережі й порахувати рукою, що буде на виході кожного шару. Помилка тут не прощається — мережа просто не запуститься.
body = Conv(1→8, 3×3, padding=1) → ReLU → MaxPool(2)
Conv(8→16, 3×3, padding=1) → ReLU → MaxPool(2)
Conv(16→32, 3×3, padding=1) → ReLU → MaxPool(2)
head = Flatten → Linear(288→64) → ReLU → Linear(64→6)
Два правила, за якими рахують форми, ми вже маємо з тем 07 і 08. Обидва — на одну дію.
пулінг 2×2 з кроком 2: розмір ділиться на два (дробову частину відкидаємо)
padding=1 означає, що навколо карти дописується рамка в один піксель
нулів. Ядро 3×3 без рамки зʼїдає по одному пікселю з кожного боку (з 28 виходить 26);
рамка ці два пікселі повертає, і на виході знову 28. Тому звʼязка «ядро 3×3 плюс
padding=1» зустрічається всюди: весь рахунок форм зводиться до пулінгів.
Друге: 28 ділиться на 2 — виходить 14, ще раз 7, ще раз 3 з половиною, і половина відкидається. Ось звідки береться 288 на вході голови: 32 канали × 3 × 3.
| шар | вхід | вихід | чисел | параметрів |
|---|---|---|---|---|
| вхід | — | 1×28×28 | 784 | 0 |
| Conv 1→8 | 1×28×28 | 8×28×28 | 6 272 | 80 |
| ReLU | 8×28×28 | 8×28×28 | 6 272 | 0 |
| MaxPool 2 | 8×28×28 | 8×14×14 | 1 568 | 0 |
| Conv 8→16 | 8×14×14 | 16×14×14 | 3 136 | 1 168 |
| ReLU | 16×14×14 | 16×14×14 | 3 136 | 0 |
| MaxPool 2 | 16×14×14 | 16×7×7 | 784 | 0 |
| Conv 16→32 | 16×7×7 | 32×7×7 | 1 568 | 4 640 |
| ReLU | 32×7×7 | 32×7×7 | 1 568 | 0 |
| MaxPool 2 | 32×7×7 | 32×3×3 | 288 | 0 |
| Flatten | 32×3×3 | 288 | 288 | 0 |
| Linear 288→64 | 288 | 64 | 64 | 18 496 |
| ReLU | 64 | 64 | 64 | 0 |
| Linear 64→6 | 64 | 6 | 6 | 390 |
| усього | — | — | — | 24 774 |
Звідки беруться числа в колонці «параметрів» — розберемо в наступному розділі. А зараз подивись на колонку форм: висота й ширина падають (28 → 14 → 7 → 3), глибина росте (1 → 8 → 16 → 32). Карта ознак стає все меншою на площі й усе товщою в каналах. Це і є геометричний портрет будь-якої згорткової мережі.
Одне зображення крізь усю мережу
Повзунок веде по шарах. Карта ознак намальована в масштабі — видно, як вона худне на площі й товстішає в каналах. Перемикач бере другу мережу, справжню, 1998 року.
ВагиДе живуть параметри
Тепер головне відкриття теми. Ядро згортки має розмір k × k і повторюється для кожної пари «вхідний канал → вихідний канал», плюс кожен вихідний канал має власний зсув (bias):
Підставимо для трьох наших згорток:
Разом згорткова частина — 5 888 параметрів. Повнозвʼязний шар звʼязує кожне вхідне число з кожним вихідним, тож параметрів у нього стільки, скільки пар, плюс зсув на кожен вихід:
Разом голова — 18 886. І ось співвідношення, заради якого писався цей розділ:
| частина | параметрів | частка |
|---|---|---|
| три згортки | 5 888 | 23.8 % |
| перший Linear | 18 496 | 74.7 % |
| останній Linear | 390 | 1.6 % |
| усього | 24 774 | 100 % |
Три чверті всіх ваг сидять в одному шарі — першому повнозвʼязному. Не в згортках, які власне й роблять роботу зі зображенням, а в шарі, що приймає розпластаний стовпчик і множить його на матрицю. Це не особливість нашого прикладу: далі ми побачимо ту саму картину в LeNet-5 і у VGG-16.
Те саме число тема 08 бачила з іншого боку. Там голова стояла після нестиснутої карти 16 × 28 × 28, тобто діставала 12 544 входи замість наших 288, — і забирала 97 % усіх ваг мережі. Тут карту тричі зменшили пулінгом, і частка голови впала до 76.2 % (18 886 із 24 774), а найбільший окремий шар важить 74.7 %. Правило, спільне для обох тем: частка голови — це міра того, наскільки стиснули карту перед нею, а не властивість самої архітектури.
Причина видна з двох формул. Згортка перевикористовує те саме ядро в кожній точці карти: 4 608 ваг третьої згортки працюють на всіх 49 клітинках виходу. Повнозвʼязний шар не перевикористовує нічого — у нього окрема вага на кожну пару чисел, і кожна працює рівно один раз.
Тепер поверни цей факт іншим боком. Друга й третя згортки роблять по 225 792 множення
кожна, а перший Linear — 288 × 64 = 18 432. Порахуймо все
разом, щоб було від чого рахувати відсотки: перша згортка 28 × 28 × 8 × 1 × 3 × 3 =
56 448, друга й третя по 225 792, два лінійні шари 18 432 і 384. Разом на одне
зображення — 526 848 множень.
Звідси прямо росте ідея, яку ти вже бачив у темі
08: глобальне усереднення (global average pooling, GAP). Замість
розпластувати карту 32×3×3 у 288 чисел — узяти від кожного каналу середнє по всій його
площі й отримати 32. Тоді голова — це один Linear(32→6) на 198 параметрів
замість 18 886, і вся мережа схудне з 24 774 до 6 086. У розділі 7
побачимо, що дешевизна — не єдина вигода.
Де живуть ваги
Кожен стовпчик — один шар, довжина — його частка в загальній кількості параметрів. Перемикач бере три мережі: нашу з Flatten, нашу з глобальним усередненням і VGG-16.
ПамʼятьДе живе памʼять
Тепер про другий кінець мережі: коли модель навчається, що саме займає відеопамʼять? Інтуїція каже «ваги» — і помиляється.
Щоб порахувати градієнти, зворотне поширення мусить памʼятати вихід кожного шару на прямому проході — усі числа, які він видав, для кожного зображення в батчі. Ці числа звуться активаціями, і саме вони головний споживач памʼяті. Візьмемо колонку «чисел» із таблиці розділу 4 окремо:
| після шару | чисел на 1 зображення | параметрів у цього шару |
|---|---|---|
| Conv 1→8 | 6 272 | 80 |
| MaxPool | 1 568 | 0 |
| Conv 8→16 | 3 136 | 1 168 |
| MaxPool | 784 | 0 |
| Conv 16→32 | 1 568 | 4 640 |
| MaxPool | 288 | 0 |
| Linear 288→64 | 64 | 18 496 |
| Linear 64→6 | 6 | 390 |
Прочитай два підсвічені рядки поруч. Перша згортка тримає 6 272 числа й має 80 параметрів. Перший повнозвʼязний шар — 64 числа й 18 496 параметрів. Різниця в сотні разів, і в протилежних напрямках.
активації збираються на початку
Логіка симетрична. На початку мережі карта величезна за площею (28×28) і тонка за каналами — багато чисел, мало ваг, бо ядро одне на всю площу. У кінці карта розпластана в короткий стовпчик — мало чисел, багато ваг, бо кожна пара має свою.
Переведемо це в мегабайти. Одне число типу float32 — це 4 байти. Склади колонку «чисел на 1
зображення» в таблиці вище — 6 272 + 1 568 + 3 136 + 784 + 1 568 + 288 + 64 + 6: уся наша
мережа на одне зображення тримає 13 686 активацій, тобто близько 53 КБ; батч на 64
зображення — 3.3 МБ. Дрібниця. А тепер те саме для VGG-16 на зображенні 224×224:
| що | чисел | у float32 |
|---|---|---|
| ваги моделі | 138 357 544 | 528 МБ |
| активації, 1 зображення | 15 087 080 | 58 МБ |
| активації, батч 64 | 965 573 120 | 3 683 МБ |
| з них — дві перші згортки | 411 041 792 | 1 568 МБ |
Ось і відповідь на питання, чому батч не влазить у відеокарту. Ваги важать пів гігабайта і не залежать від батча зовсім; активації важать у сім разів більше й ростуть строго пропорційно. І 43 % цієї памʼяті зʼїдають дві перші згортки, у яких лежить 0.03 % ваг моделі.
Параметри проти памʼяті
Два ряди стовпчиків по тих самих шарах: угорі ваги, унизу активації. Повзунок множить батч; перемикач бере нашу мережу або VGG-16 на 224×224.
ГоловаГолова: Flatten проти GAP
Згорткова частина мережі зветься тілом (backbone), а те, що перетворює її вихід на відповідь, — головою (head). Тіло видає карту ознак 32×3×3; голова мусить видати шість чисел — по одному на клас. Способів два.
Спосіб перший: розпластати
Flatten виписує всі числа карти 32×3×3 в один рядок завдовжки 288: спершу
весь перший канал по рядках, потім весь другий, і так далі. Далі — звичайний
повнозвʼязний шар.
Плюс: голова бачить, де саме лежала кожна ознака — число з лівого верхнього кута має власну вагу, відмінну від ваги числа з правого нижнього. Мінус ми вже порахували: 18 496 параметрів, три чверті мережі. Другий мінус, принциповіший, — далі.
Спосіб другий: усереднити
Глобальне усереднення замінює всю площу кожного каналу одним числом — середнім. Було
32 канали по 3×3 = 288 чисел, стало 32 числа, а голова — це Linear(32→6) на
198 параметрів.
Мінус: голова більше не знає, де була ознака, лише «наскільки сильно вона присутня в кадрі». Плюс — той самий: не знаючи положення, вона на нього й не переучується.
І тепер найцікавіше: розмір входу
Подай на нашу мережу зображення не 28×28, а 40×40, і подивись, що станеться з формами.
Згорткова частина відпрацювала бездоганно: їй байдуже, якого розміру карта, бо ядро
просто їде по ній. А от матриця Linear має жорсткий розмір 288 × 64,
зафіксований при створенні мережі. Подати в неї 800 чисел так само неможливо, як
помножити матрицю 5×3 на матрицю 4×2. PyTorch падає з такою помилкою:
А тепер те саме з глобальним усередненням. Вхід 40×40 → карта 32×5×5 → усереднюємо кожен канал по площі → 32 числа. Вхід 64×64 → карта 32×8×8 → знову 32 числа. Скільки б не було клітинок у каналі, середнє від них — одне число.
Flatten перетворює усі
клітинки на окремі входи, тому їхня кількість входить у форму матриці. Глобальне
усереднення перетворює кожен канал на один вхід, а кількість каналів
задається архітектурою й від розміру зображення не залежить взагалі. Тому мережа з GAP
приймає вхід будь-якого розміру, а мережа з Flatten — рівно того, під який її
зібрали.Саме на цій властивості стоять повнозгорткові мережі для сегментації і детектори, що
працюють на кадрах різної роздільності. Вона ж пояснює, чому мережу з Flatten
доводиться годувати зображеннями, заздалегідь приведеними до одного розміру, — а
перетворення розміру завжди щось спотворює.
Голова й розмір входу
Повзунок міняє розмір вхідного зображення, перемикач — тип голови. Схема веде форми наскрізь і показує, у якому саме місці ланцюг рветься.
Flatten працюють лише сторони від 24 до 31 — тільки
вони після трьох поділів навпіл дають карту 3×3. Уже 32 дає 512 чисел замість 288, і
мережа падає. Перемкни на GAP: на вхід у Linear завжди йдуть ті самі 32 числа, від 20
до 68.ОглядРецептивне поле цілої мережі
У темі 07 ми ввели рецептивне поле — ділянку вхідного зображення, від якої залежить одне число на виході шару. Для однієї згортки 3×3 це 3×3 пікселі. Тепер порахуємо його для цілої мережі: саме воно відповідає на питання, чи здатна мережа побачити предмет цілком. Рахунок ведеться двома числами одночасно, і про друге зазвичай забувають.
| Позначення | Що це |
|---|---|
| r — рецептивне поле | сторона квадрата на вході, яку бачить один нейрон цього шару |
| j — крок (jump) | на скільки пікселів входу зсувається вікно, коли переходимо до сусіднього нейрона цього шару |
Крок потрібен ось для чого. Після одного пулінгу сусідні клітинки карти відповідають ділянкам оригіналу, віддаленим на два пікселі, після двох — на чотири. Тому ядро 3×3 у третьому блоці, зачіпаючи трьох сусідів, розтягується на вчетверо більшу ділянку оригіналу. Формула це враховує:
Тут k — сторона ядра шару, s — його
крок (stride). Читається так: нове рецептивне поле — це старе плюс те, що
додали k − 1 сусідів, кожен вартістю j
пікселів. Починаємо з r = 1 і j = 1.
Пулінг 2×2 з кроком 2 — це k = 2, s = 2.
| шар | k | s | рахунок r | r | j |
|---|---|---|---|---|---|
| вхід | — | — | — | 1 | 1 |
| Conv 3×3 | 3 | 1 | 1 + 2×1 | 3 | 1 |
| MaxPool 2 | 2 | 2 | 3 + 1×1 | 4 | 2 |
| Conv 3×3 | 3 | 1 | 4 + 2×2 | 8 | 2 |
| MaxPool 2 | 2 | 2 | 8 + 1×2 | 10 | 4 |
| Conv 3×3 | 3 | 1 | 10 + 2×4 | 18 | 4 |
| MaxPool 2 | 2 | 2 | 18 + 1×4 | 22 | 8 |
Один нейрон останньої згортки бачить квадрат 18×18 на вхідному зображенні 28×28. Фігури в нашому датасеті мають діаметр від 14 до 18 пікселів — тобто рецептивне поле щойно-щойно їх покриває. Це умова, за якої мережа взагалі здатна відрізнити коло від кільця: якщо нейрон бачить лише шматок дуги, обидві фігури виглядають для нього однаково.
Зворотний бік теж варто бачити. Останній пулінг доводить r до 22, а четвертий блок дав би 38 — більше за все зображення. Це не помилка: нейрон із рецептивним полем, більшим за кадр, просто бачить кадр цілком. Але й користі від подальшого росту r немає — дивитись більше нема на що.
Рецептивне поле наскрізь
Квадрат показує, що бачить один нейрон обраного шару на вхідному зображенні 28×28. Другий повзунок міняє розмір фігури — стеж, коли квадрат перестає її покривати.
ІсторіяLeNet-5, 1998
Усе, що ми зібрали, придумали не вчора. Перша згорткова мережа, яка справді працювала в продакшені, зветься LeNet-5: опублікована 1998 року, читала суми на банківських чеках. Розберемо її по шарах — це найкращий спосіб перевірити, чи вмієш ти читати опис архітектури.
Вхід — 32×32 в одному каналі: рукописна цифра. Далі:
| шар | що робить | вихід | параметрів |
|---|---|---|---|
| вхід | цифра 32×32 | 1×32×32 | 0 |
| C1 | згортка 5×5, 6 карт | 6×28×28 | 156 |
| S2 | усереднення 2×2 | 6×14×14 | 12 |
| C3 | згортка 5×5, 16 карт | 16×10×10 | 1 516 |
| S4 | усереднення 2×2 | 16×5×5 | 32 |
| C5 | згортка 5×5, 120 карт | 120×1×1 | 48 120 |
| F6 | повнозвʼязний | 84 | 10 164 |
| вихід | 10 класів | 10 | 840 |
| усього | — | — | 60 840 |
Придивись до рядка C5. Формально це згортка 5×5, але вхідна карта теж 5×5: ядро вміщується в ній рівно один раз, і на виході кожної зі 120 карт лишається одне число. Згортка, яка бачить усю карту цілком, — це і є повнозвʼязний шар, просто записаний іншими словами. І він тримає 48 120 із 60 840 параметрів, тобто 79.1 %.
Порівняй із нашими 74.7 % і з 74.3 % у VGG-16. Три мережі різних епох і різних порядків розміру дають ту саму частку в тому самому місці — прямий наслідок того, що згортка ділить ваги між точками, а повнозвʼязний шар ні.
Що з LeNet лишилось, а що зникло
| Ідея LeNet | Доля |
|---|---|
| Чергування «згортка — зменшення» | Живе. Це і є типовий блок із розділу 2. Змінилось лише те, що перед пулінгом тепер буває стос із двох-трьох згорток. |
| Зростання каналів із глибиною | Живе. 6 → 16 → 120 — те саме правило подвоєння, тільки з іншими числами. |
| Сигмоїда й гіперболічний тангенс | Зникли. На глибоких мережах вони гасять градієнт: похідна сигмоїди майже нульова скрізь, крім вузької смуги біля нуля, і через десять шарів сигнал для навчання не доходить. |
| Усереднювальний пулінг | Майже зник із середини мережі: максимум зберігає сильний відгук, а середнє його розмиває. Але вижив у голові — це і є глобальне усереднення. |
| Часткова звʼязність каналів | Зникла. Про неї окремо. |
Часткова звʼязність пояснює дивне число 1 516 у рядку C3. За нашою формулою повнозвʼязна за каналами згортка 6→16 з ядром 5×5 мала б 6 × 16 × 25 + 16 = 2 416 параметрів. У LeNet їх 1 516, бо кожна з 16 вихідних карт була підключена не до всіх шести вхідних, а лише до трьох-чотирьох за наперед намальованою таблицею.
Мотивів було два: у 1998 році зайвих множень собі не дозволяли, а ще автори хотіли, щоб різні вихідні карти дивились на різні набори вхідних і тому вивчали різні речі. Другий мотив не витримав перевірки часом: мережа й так вивчає різне, достатньо випадкової ініціалізації. Сьогодні згортка звʼязує всі канали з усіма — хоч ідея й повернулась з іншого боку у вигляді групової згортки, де групи регулярні й задані одним числом, а не таблицею.
VGGVGG і однорідність
Тепер стрибнемо на сімнадцять років уперед. VGG — архітектура 2014 року, цікава не рекордами, а тим, що довела до крайності однорідність: уся мережа складена з деталей одного типу й описується одним рядком чисел.
Число — це згортка 3×3 з такою кількістю вихідних каналів, M — max-пулінг 2×2. Жодних інших розмірів ядра. Тринадцять згорток, пʼять пулінгів, потім голова з трьох повнозвʼязних шарів: разом шістнадцять шарів із вагами.
Зверни увагу на дві речі. Канали подвоюються рівно за нашим правилом (64 → 128 → 256 → 512) і на останніх двох блоках зупиняються — далі росли б параметри, а користі вже мало. І в блоці стоїть не одна згортка, а дві або три поспіль, і лише потім пулінг.
Чому дві згортки 3×3 краще за одну 5×5
Дві згортки 3×3 поспіль дають те саме рецептивне поле, що одна 5×5: за формулою з розділу 8 після першої r = 3, після другої r = 5. А тепер ціна:
На 28 % менше ваг при тому самому полі огляду. Але головне інше: між
двома згортками стоїть ReLU, тобто мережа отримує зайву нелінійність задарма.
Одна згортка 5×5 — одне лінійне перетворення; дві 3×3 з нелінійністю посередині — уже
композиція, здатна на складнішу форму відгуку. Детально цей рахунок вела тема 07.
І чесно про голову
А тепер зворотний бік однорідності, який зазвичай ховають за словами про елегантність.
| частина | параметрів | частка |
|---|---|---|
| тринадцять згорток | 14 714 688 | 10.6 % |
| Linear 25088→4096 | 102 764 544 | 74.3 % |
| Linear 4096→4096 | 16 781 312 | 12.1 % |
| Linear 4096→1000 | 4 097 000 | 3.0 % |
| усього | 138 357 544 | 100 % |
Уся згорткова частина — тринадцять шарів, які власне й дивляться на зображення, — це 10.6 % моделі. Решта 89.4 % лежить у трьох повнозвʼязних шарах, а три чверті всієї моделі — в одному, першому з них. Мережа, відома як приклад глибокої згорткової архітектури, на девʼять десятих складається з повнозвʼязних ваг.
Звідки береться 25 088: після пʼяти пулінгів зображення 224×224 стає 7×7 при 512
каналах, а 512 × 7 × 7 = 25 088. Помножити на 4 096 виходів — і виходить сто мільйонів
ваг. Той самий Flatten, що в нашій маленькій мережі, просто в іншому
масштабі.
Flatten стоїть глобальне
усереднення, і класифікатор — це один Linear. Наслідок видно на числах:
ResNet-50 глибший за VGG-16 утричі, а важить 25.6 мільйона параметрів проти 138 —
у пʼять разів менше. Прибрали не глибину, а голову.ГлибинаЩо вирішує глибина
Лишилось питання, яке напрошується весь час: якщо кожен наступний блок дає більше рецептивне поле й складніші ознаки — чому б не поставити сто блоків?
Глибина дає ієрархію: перший блок навчається бачити краї й плями — те саме, що ми рахували руками в темі 04 фільтром Собеля; другий складає з країв кути й дуги; третій збирає частини предметів; четвертий — цілі предмети. Кожен рівень працює не з пікселями, а з тим, що знайшов попередній, — і саме тому десять шарів по 3×3 сильніші за один шар із ядром 21×21, хоч рецептивне поле однакове.
А тепер межа. Просто додавати шари перестає працювати, і не через переучування. Виміряний факт, який свого часу здивував усіх: мережа з 56 шарів давала гіршу помилку і на навчальній вибірці теж, ніж мережа з 20 шарів — тобто не змогла навчитись навіть тому, що вміла мілкіша.
Причина й ліки — тема 14 у наступному блоці. Запамʼятай форму проблеми: глибина корисна, але сама по собі не безкоштовна, і щоб мережі глибші за два десятки шарів узагалі навчались, знадобився окремий винахід. До нього класична схема «блок за блоком» упирається в стелю приблизно на глибині VGG.
ПідсумокМережа зібрана
Три деталі перетворились на конструкцію. Що варто винести з теми:
- Блок — це
Conv → ReLU → Pool. Порядок не довільний: згортка мусить бачити повну карту,ReLU— стояти до avg-пулінгу (з max-пулінгом порядок не важить). - Стос блоків: розмір навпіл, канали вдвічі. Емпіричне правило, яке тримає сталим не кількість чисел, а обсяг обчислень на шар.
- Форми рахуються за двома правилами: згортка 3×3 з
padding=1розмір не міняє, пулінг 2×2 ділить його навпіл із відкиданням дробової частини. - Параметри й памʼять живуть у різних кінцях. 74.7 % ваг — у першому повнозвʼязному шарі; найбільше активацій — після першої згортки, у якої ваг 0.3 %.
- GAP приймає будь-який розмір входу,
Flatten— ні, бо кількість каналів задана архітектурою, а кількість клітинок — зображенням. - Рецептивне поле рахується наскрізь двома числами, і воно мусить покривати предмет, інакше жодне навчання не допоможе.
І тепер про те, чого ми не зробили. Мережа зібрана, форми зійшлись — але як тільки ми почнемо її навчати, зʼявиться проблема, якої в наших розрахунках немає взагалі.
Наша мережа має 24 774 параметри, а датасет фігур — близько тисячі зображень по 784 пікселі. Параметрів у мережі стільки ж, скільки пікселів у тридцяти картинках. Мережа з такою місткістю не мусить розуміти, що таке коло, — їй значно простіше запамʼятати конкретні картинки разом із відповідями. І вона це зробить: точність на навчальній вибірці піде до одиниці, а на новому зображенні мережа помилиться.
Даних більше не буде. Але зображення має властивість, якої немає в таблиці з цінами: його можна зсунути, повернути, віддзеркалити — і воно лишиться тим самим предметом. Коло, зсунуте на три пікселі вправо, — це досі коло, і мережа має право побачити його як новий приклад. Наступна тема — про те, як із одного зображення зробити багато.