AlexNet і VGG

Дві мережі, з яких почалась сучасна історія зору. Їх памʼятають як «перші глибокі». Але якщо порахувати, де в них лежать ваги, виявиться, що глибина тут майже ні до чого.

Сім тем поспіль ми будували маленькі мережі. Наша ShapeNet із теми 09 має три блоки, 24 774 параметри й уміщається на одному аркуші — її можна порахувати рукою, і ми це робили. Тема 12 закінчилася обіцянкою: справжні архітектури вирішують ті самі задачі зовсім іншими засобами. Час подивитись, як саме.

Починається все з 2012 року й двох мереж — AlexNet і VGG. Про них у кожному підручнику написано те саме: вони довели, що глибина працює. Це правда, але не вся. У цій темі ми розберемо обидві по шарах через torchvision, порахуємо кожну вагу — і дійдемо до числа, яке в підручниках згадують рідко.

Головне число теми, наперед. У VGG16 сто тридцять вісім мільйонів параметрів. Із них 123 642 856 — майже 124 мільйони — сидять у трьох повнозвʼязних шарах голови. Мережа, відома як приклад глибокої згорткової архітектури, на 89.4 % складається зі звичайних повнозвʼязних ваг. Звідки це береться і що з цим зробили далі — і є сюжет теми.
Мережа не потрібна. Виклик torchvision.models.vgg16(weights=None) будує архітектуру локально: створює всі шари, розставляє форми, ініціалізує ваги випадковими числами — і нічого не завантажує. Тому кожне число цієї теми ти можеш відтворити на машині без інтернету. Ваги ImageNet ми не тягнемо жодного разу; там, де потрібна точність навчених мереж, ми цитуємо її з літератури й прямо про це кажемо.

2012Що сталося у 2012

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

ImageNet — набір фотографій, зібраний до 2009 року. На щорічному змаганні ILSVRC використовували його частину: тисяча класів і близько 1.2 мільйона навчальних зображень, ще 50 тисяч на перевірку. Класи дрібні й неприємні: не «собака», а сто двадцять окремих порід; не «гриб», а десятки видів. Людина на цій задачі помиляється приблизно в 5 % випадків — і це не фігура мови, а заміряне число, отримане на людях, які спеціально тренувалися.

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

рікпереможецьtop-5 помилка
2010класичні ознаки28.2 %
2011класичні ознаки25.8 %
2012AlexNet15.3 %
2012друге місце, класичні ознаки26.2 %
2014VGG (друге місце) / GoogLeNet7.3 % / 6.7 %

Придивись до рядків 2012 року. Річний прогрес до того був два-три відсоткові пункти. AlexNet виграла з відривом майже в одинадцять пунктів від другого місця — і друге місце при цьому не осоромилось, воно було на рівні минулорічного переможця. Розрив був такий, що заперечувати його не вийшло.

Що саме перемогло? Тут починається міфологія, тому назвемо речі по черзі — і чесно скажемо, що з цього було новим.

СкладникЩо це далоЧи було новим
Дані1.2 мільйона розмічених фотографій замість тисячНі. ImageNet зібрали за три роки до того. Просто ніхто не мав чим його переварити
ВідеокартиДві GTX 580 по 3 ГБ, навчання за 5-6 днів замість місяцівНі як ідея, так як реалізація: автори написали власні згорткові ядра під GPU
ReLUНавчання в кілька разів швидше за сигмоїдуНі. Функція відома давно, але саме тут стала стандартом
ДропаутМережа на 61 мільйон ваг перестала просто запамʼятовуватиМайже. Описаний того самого 2012 року
АугментаціяВипадкові вирізи 224×224 з кадру 256×256 і віддзеркалення — у 2048 разів більше прикладівНі. Але саме тут без неї нічого б не вийшло

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

Дві речі з цієї таблиці ти вже вмієш робити руками. Аугментацію ми розбирали в темі 10 — і навіть число 2048 там пояснене: 32 × 32 положення вирізу, помножені на два віддзеркалення. Дропаут і ReLU — у темі 11. Нового в цій темі не прийоми, а масштаб, у якому вони вперше спрацювали.

РозбірAlexNet по шарах

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

Один рядок будує архітектуру, не завантажуючи нічого:

from torchvision import models
model = models.alexnet(weights=None)   # лише будова, ваги випадкові

Вхід — кольорове зображення 224×224, тобто тензор форми 3×224×224. Далі:

шарядро / кроквихідпараметрівчастка
вхід—3×224×2240—
conv111×11, крок 4, поле 264×55×5523 2960.04 %
maxpool3×3, крок 264×27×270—
conv25×5, крок 1, поле 2192×27×27307 3920.50 %
maxpool3×3, крок 2192×13×130—
conv33×3, крок 1, поле 1384×13×13663 9361.09 %
conv43×3, крок 1, поле 1256×13×13884 9921.45 %
conv53×3, крок 1, поле 1256×13×13590 0800.97 %
maxpool3×3, крок 2256×6×60—
Flatten—9 2160—
Linear 19216 → 40964 09637 752 83261.79 %
Linear 24096 → 40964 09616 781 31227.46 %
Linear 34096 → 10001 0004 097 0006.71 %
усього——61 100 840100 %

Прочитаймо цю таблицю двічі — згори вниз і знизу вгору, бо вона говорить дві різні речі.

Згори вниз це звичайна згорткова мережа, побудована за правилом із теми 09: сторона карти падає (224 → 55 → 27 → 13 → 6), кількість каналів росте (3 → 64 → 192 → 384 → 256). Правило подвоєння тут витримане нестрого — 384 і 256 не подвоєння, — але напрямок той самий.

Знизу вгору це щось інше. Пʼять згорток разом важать 2 469 696 параметрів — 4.0 % мережі. Решта 96 % лежить у трьох повнозвʼязних шарах, які взагалі не дивляться на зображення: вони працюють із рядком у 9 216 чисел, що лишився після згорток.

AlexNet по шарах

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

вхід—
вихід—
параметрів—
частка ваг—
Ширина коробки — сторона карти, висота — кількість каналів, обидві в логарифмічній шкалі, інакше 224 і 6 не вміщаються поруч. Стовпчик праворуч від коробки — частка шару в 61 100 840 вагах мережі. Три останні шари намальовані як смуги: у них немає ані сторони, ані каналів, лише довжина рядка.
Чесно про версію. У torchvision лежить не та AlexNet, що виграла у 2012-му, а її пізніша однокарткова переробка. Відмінності невеликі, але вони є: у першій згортці 64 канали замість 96, у другій 192 замість 256, і немає поділу на дві гілки. Оригінал важив 60 965 224 параметри, версія torchvision — 61 100 840. Різниця в 0.2 %, тож усі висновки теми лишаються чинними, але число «61.1 мільйона» — саме про цю версію. Про дві гілки й куди вони зникли — розділ 4.

Груба оптикаЯдро 11×11 з кроком 4

Перший шар AlexNet виглядає дивно для того, хто вчився на сучасних мережах: ядро 11×11 з кроком 4. Це грубо у двох сенсах одразу, і обидва варто порахувати.

Спершу рецептивне поле — скільки пікселів вхідного зображення бачить один нейрон карти. Формулу ми вивели в темі 09; тут вона дає просту відповідь: після одного шару з ядром 11×11 поле дорівнює 11. Одинадцять на одинадцять пікселів — квадратик приблизно на двадцяту частину сторони кадру.

Тепер крок 4. Ядро зсувається не на піксель, а на чотири, тому карта на виході має сторону 55 замість 224. Крок 4 діє по обох осях, тож на кожні чотири положення вікна по горизонталі й чотири по вертикалі — усього шістнадцять — мережа рахує тільки одне: пʼятнадцять із шістнадцяти положень просто не обчислюються. Не «усереднюються», як у пулінгу, а зникають.

Порівняймо це з тим, що робить сучасна мережа. Щоб дійти до рецептивного поля 11 ядрами 3×3, потрібно пʼять шарів: кожен додає до поля 2, і 1 + 2·5 = 11. Ось два варіанти поруч, обидва на вході 3×224×224. Множення рахуємо так: скільки ваг має ядро, помножити на скільки разів воно прикладається, тобто на кількість позицій вихідної карти.

варіантрецептивне полепараметрівмноженькарта на виході
одна 11×11, крок 41123 29670 276 80064×55×55
пʼять 3×3, крок 111149 5047 485 456 38464×224×224

Ось і відповідь на питання «чому так робили». Стос 3×3 коштує в 6.4 раза більше ваг і — головне — у сто сім разів більше множень. Сто сім разів на двох відеокартах 2012 року означало не «повільніше», а «неможливо». Ядро 11×11 з кроком 4 — це не естетичний вибір, а найдешевший спосіб одразу зменшити картинку вчетверо й далі працювати з маленькими картами.

Чому ж так більше не роблять? Три причини, і жодна з них не про красу.

  1. Між шарами стоїть нелінійність, усередині ядра — ні. Пʼять шарів 3×3 дають пʼять ReLU; одне ядро 11×11 — одну. Мережа з пʼятьма нелінійностями здатна на складнішу відповідь при тому самому полі огляду. Цей самий аргумент ми вже бачили в темі 07.
  2. Крок 4 викидає інформацію назавжди. Пулінг хоча б дивиться на всі позиції й обирає максимум; крок їх не обчислює. Те, що не порахували, назад не повернеш.
  3. Заліза стало більше. Обмеження, що породило це рішення, зникло — а рішення лишилось у підручниках як «архітектурний прийом». Це трапляється частіше, ніж хочеться.

Одне грубе ядро проти стосу дрібних

Додавай шари 3×3 і дивись, коли їхнє рецептивне поле дожене одне ядро 11×11. Ціна показана поруч.

поле стосу—
поле 11×1111 × 11
ваг у стосі—
ваг проти 11×11—
Рецептивне поле стосу росте на 2 за шар: 3, 5, 7, 9, 11. Ваги рахуємо для каналів 3→64 у першому шарі й 64→64 у решті — так, як це робить сучасна мережа. Множення рахуємо на вході 224×224 без зменшення, тобто в найчесніших умовах для обох варіантів.

Дві гілкиДві гілки — не ідея, а вимушеність

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

Мережа не влізала у відеокарту. GTX 580 мала 3 гігабайти памʼяті. Модель на 61 мільйон параметрів у форматі float32 займає 233 мегабайти самих лише ваг, а під час навчання потрібно ще стільки ж під градієнти, стільки ж під моменти оптимізатора й окремо — під активації всього батча. Три гігабайти скінчились раніше, ніж навчання почалось.

Вихід був механічний: розрізати мережу навпіл і покласти половини на дві картки. Кожна гілка бачила свою половину каналів, і лише в кількох місцях гілки обмінювались даними. У сучасних термінах це групована згортка (grouped convolution) з двома групами.

Порахуймо, що вона дає. Друга згортка оригіналу — 96 вхідних каналів, 256 вихідних, ядро 5×5. Формула параметрів згортки з теми 07:

параметрів = cвх × cвих × k × k + cвих

Тут cвх — скільки каналів приходить, cвих — скільки виходить, k — сторона ядра, а останній доданок — по одному зсуву на кожен вихідний канал. Групи ділять вхідні канали на g частин, і кожна вихідна карта підключена лише до своєї частини:

без груп: 96 × 256 × 25 + 256 = 614 656 з groups=2: 96/2 × 256 × 25 + 256 = 307 456

Ваг стало рівно вдвічі менше — і це очікувано: кожне зʼєднання «канал з каналом» через групу або є, або немає, і половини немає. (У сумі різниця трохи менша за половину, бо зсуви не діляться: їх як було 256, так і лишилось.) Те саме сталося з четвертою та пʼятою згортками. По всій мережі дві гілки зекономили 1 413 120 параметрів: 60 965 224 замість 62 378 344.

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

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

Перевір сам. У версії torchvision гілок уже немає: model.features[3].groups поверне 1 для всіх пʼяти згорток. Обмеження зникло разом із відеокартою, під яку його вигадали, — і мережу склеїли назад в одну.

ОднорідністьVGG: одна ідея замість набору рішень

Через два роки після AlexNet вийшла VGG — і зробила протилежне за духом. AlexNet була набором рішень: тут ядро 11×11, там 5×5, далі 3×3, крок то 4, то 1, пулінг 3×3 із кроком 2, місцями групи. Кожне рішення мало свою причину, і жодне не випливало з іншого.

VGG прибрала всі рішення, крім одного. Правила три, і вони вміщаються в рядок:

Після цього від архітектури лишається одне: скільки згорток стоїть у кожному з пʼяти блоків. VGG16 описується так:

64, 64, M, 128, 128, M, 256, 256, 256, M, 512, 512, 512, M, 512, 512, 512, M

Число — згортка 3×3 з такою кількістю вихідних каналів, M — пулінг. Тринадцять згорток плюс три повнозвʼязні шари голови дають шістнадцять шарів із вагами, звідки й назва. Сторона карти йде рівно степенями двійки: 224 → 112 → 56 → 28 → 14 → 7.

Здається, що це просто акуратність. Але однорідність виявилась цінною сама собою, і причин чотири.

Чим корисна однорідністьЧому
Архітектуру можна описати числом«VGG16» і «VGG19» — та сама мережа з іншою кількістю повторів. Порівнювати глибину стало можливо, бо решта не міняється
Немає що підбиратиУ AlexNet сім архітектурних чисел, і кожне треба чимось виправдати. У VGG — одне на блок
Її легко різатиБеручи VGG як backbone для детекції чи сегментації, ти обрізаєш її по будь-якому пулінгу й точно знаєш форму карти
Вона добре переноситьсяСаме однорідність зробила VGG стандартним джерелом ваг на роки — про перенос ми говорили в темі 12

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

Однорідність VGG

Перемикай глибину. Схема мережі й числа міняються — стеж, наскільки саме.

глибина
згорток—
ваг у згортках—
ваг у голові—
усього—
Голова не змінюється ніколи — 123 642 856 ваг у всіх чотирьох варіантах, бо вона залежить лише від форми карти перед нею, а форма однакова: 512×7×7. Числа взяті з torchvision, побудованого з weights=None.

Ось що показує цей інтерактив, і це перше попередження про головний сюжет теми. Від VGG11 до VGG19 кількість згорток росте вдвічі — з восьми до шістнадцяти, — а згорткова частина важчає з 9.2 до 20.0 мільйона. Але вся мережа при цьому росте зі 132.9 до 143.7 мільйона, тобто лише на 8.1 %.

Подвоїти глибину мережі й додати вісім відсотків ваги — це можливо тільки в одному випадку: якщо основна вага лежить не там, де глибина. Куди саме вона лежить, ми порахуємо в розділі 7.

ЯдраДва 3×3 замість одного 5×5

Лишилось питання, чому саме 3×3, а не 5×5 чи 7×7. Відповідь ти вже знаєш: тема 07 вивела її на одному шарі, а тема 09 повторила на прикладі VGG. Стисло: дві згортки 3×3 поспіль дають те саме рецептивне поле 5, що одна 5×5, але коштують дешевше й дають зайву нелінійність між собою.

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

каналиодна 5×5дві 3×3дешевше на
64 → 64102 46473 85627.9 %
128 → 128409 728295 16828.0 %
256 → 2561 638 6561 180 16028.0 %
512 → 5126 554 1124 719 61628.0 %

Двадцять вісім відсотків на кожному масштабі — і це не збіг. Дві згортки 3×3 мають разом 2 × 9 = 18 клітинок ядра проти 25 в однієї 5×5, тож відношення дорівнює 18/25 плюс дрібка від зсувів; при зростанні кількості каналів зсуви тонуть, і лишається рівно 0.72.

Тепер інше питання, яке в темах 07 і 09 не ставилось: скільки коштувало б побудувати VGG16 на ядрах 5×5 — з тим самим планом каналів і тією самою кількістю шарів?

згорткова частина VGG16, ядра 3×3: 14 714 688 та сама структура, ядра 5×5: 40 866 624 різниця: + 26 151 936 (у 2.78 раза)

Множник 2.78 — це просто 25/9, відношення площ ядер. Але подивись на абсолютне число: вибір 3×3 замість 5×5 зекономив 26 мільйонів параметрів, тобто майже вдвічі більше, ніж важить уся згорткова частина VGG16. Одне рішення про розмір ядра дало більше, ніж коштує все, що мережа бачить у зображенні.

Дві різні відповіді на схожі питання. Не сплутай два числа цього розділу. 28 % — це «замінімо пару 3×3 однією 5×5, зберігши рецептивне поле»; тут шарів стає менше, а поле те саме. 2.78 раза — це «лишімо ту саму кількість шарів, але з більшими ядрами»; тут поле виросло б удвічі. Перше питання про ціну однакового результату, друге — про ціну однакової будови.

І ще одна деталь, яку легко проґавити. Однорідні ядра 3×3 зробили VGG передбачуваною не лише на папері: усі бібліотеки згорток оптимізовані саме під 3×3, і мережа з одного типу ядра рахується швидше за строкату при тій самій кількості множень. Це не задум авторів, а наслідок, який зʼявився пізніше.

ВагиДе сидять ваги

Це головний розділ теми. Усе, що ми рахували досі, вело сюди.

У темі 09 ти вже робив цей рахунок на нашій маленькій мережі й отримав неприємне число: 18 496 із 24 774 параметрів ShapeNet — 74.7 % — лежать в одному-єдиному шарі, першому Linear після Flatten. Тоді це виглядало як особливість навчального прикладу. Зараз ми побачимо те саме на мережах у тисячі разів більших.

мережапараметріву згорткаху лінійнихзгорткових шарів
AlexNet61 100 8404.0 %96.0 %5
VGG16138 357 54410.6 %89.4 %13
ResNet1811 689 51295.5 %4.4 %20

Прочитай третій рядок ще раз. ResNet18 має більше згорткових шарів, ніж VGG16, — двадцять проти тринадцяти, — і при цьому важить у дванадцять разів менше. Тобто справа не в глибині. Справа в голові.

Звідки береться 25 088

Розберімо по кроках, як зʼявляється найдорожчий шар VGG16.

крок 1 · що лишається після згорток

Вхід 224×224 проходить пʼять пулінгів, кожен ділить сторону навпіл: 224 → 112 → 56 → 28 → 14 → 7. Каналів на цей момент 512.

карта перед головою = 512 × 7 × 7
крок 2 · Flatten перетворює карту на рядок

Flatten виписує всі числа карти в один довгий рядок — спершу перший канал рядок за рядком, потім другий, і так усі 512.

512 × 7 × 7 = 25 088 чисел
крок 3 · повнозвʼязний шар зʼєднує кожне з кожним

Автори обрали ширину наступного шару 4096. Повнозвʼязний шар має окрему вагу на кожну пару «вхідне число — вихідне число», плюс по одному зсуву на вихід.

25 088 × 4 096 + 4 096 = 102 764 544
крок 4 · порівняння

Уся згорткова частина VGG16 — тринадцять шарів, які власне й дивляться на зображення, — важить 14 714 688. Один цей шар важчий за неї у сім разів.

У AlexNet усе те саме, тільки числа менші: карта перед головою 256×6×6, отже 256 × 6 × 6 = 9 216 чисел, а 9 216 × 4 096 + 4 096 = 37 752 832 — 61.8 % усієї мережі в одному шарі.

Чому саме перший Linear такий дорогий, а не другий чи третій? Бо в нього найширший вхід. Другий шар зʼєднує 4096 із 4096 і коштує 16 781 312 — теж багато, але вшестеро менше. Третій зʼєднує 4096 із тисячею класів: 4 097 000. Ціна повнозвʼязного шару — це добуток двох ширин, і найбільша ширина в мережі — саме та, що приходить із розпластаної карти.

Звідки взялося 4096. Ні звідки. Це кругле число, обране авторами AlexNet, і VGG успадкувала його без змін, разом із двома шарами по 4096 поспіль. Другий такий шар коштує 16.8 мільйона ваг і не робить нічого, крім змішування тих самих 4096 чисел ще раз. Ніхто не довів, що він потрібен, — його просто перестали ставити пізніше. Гарний привід не сприймати числа з чужих архітектур як істину.

Де сидять ваги

Кожен стовпчик — один шар із вагами. Три останні (голова) підсвічені. Перемикай мережу.

мережа
усього ваг—
частка в голові—
найтовщий шар—
його частка—
Висота стовпчика — частка шару в усіх вагах мережі. Згорткові шари ліворуч майже не видно не через похибку малюнка: у AlexNet найтовща згортка тримає 1.45 % ваг, а перший шар голови — 61.8 %. Числа взяті з torchvision, побудованого з weights=None.

Що станеться, якщо змінити розмір входу

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

Ціна голови

Міняй розмір вхідного зображення VGG16 і дивись, що робиться з першим шаром голови. Пунктир — скільки коштувала б та сама голова на глобальному усередненні.

карта перед Flatten—
довжина рядка—
ваг у першому Linear—
проти GAP-голови—
Голова з глобальним усередненням не залежить від розміру входу взагалі. Вона бере середнє по кожному з 512 каналів і подає 512 чисел у Linear на тисячу класів: 512 × 1000 + 1000 = 513 000 ваг за будь-якої сторони. Саме тому мережу з Flatten не можна годувати кадром іншого розміру, а мережу з усередненням — можна.

Цей інтерактив показує в чистому вигляді те, чого тема 09 досягла на маленькій мережі. Голова на Flatten прибита цвяхами до одного розміру входу — і платить за нього квадратично. Голова на глобальному усередненні (його ми вводили в темі 08) коштує 513 000 ваг завжди.

Порахуймо різницю в лоба. Якби VGG16 мала GAP-голову замість трьох повнозвʼязних шарів, то важила б 14 714 688 + 513 000 = 15 227 688 параметрів — у 9.1 раза менше за справжні 138 мільйонів. При тій самій згортковій частині. При тій самій глибині. Просто без голови.

ЦінаСкільки це коштує насправді

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

Памʼять на ваги

Один параметр у форматі float32 — чотири байти. Множимо:

мережапараметрівваги, МБ
ShapeNet (тема 09)24 7740.09
AlexNet61 100 840233.1
VGG16138 357 544527.8
ResNet1811 689 51244.6

Пів гігабайта. Саме тому файл ваг VGG16 качається помітно довше за все інше, і саме тому її не кладуть у телефон.

Памʼять на активації

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

мережачисел, батч 1активації, МБнайбільший шар
AlexNet582 5042.22conv1 — 0.74 МБ
VGG1615 087 08057.55conv1_1 — 12.25 МБ

І ось повторення того самого відкриття, що в темі 09: максимум ваг і максимум памʼяті стоять у різних кінцях мережі. У VGG16 найважчий шар за вагами — перший Linear (392 МБ), а найважчий за активаціями — найперша згортка, у якій ваг усього 1 792 штуки, зате карта 64×224×224 займає 12.25 МБ. Один шар важить у двісті тисяч разів більше за другий і водночас у пʼятдесят разів менше.

Це не курйоз, а робоче правило. Хочеш зменшити файл моделі — дивись на голову. Не влазить батч у памʼять — дивись на перші згортки.

Памʼять проти параметрів

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

мережа
ваги, МБ—
активації, МБ—
що більше—
перетин на батчі—
Стовпчики вгору — мегабайти ваг, униз — мегабайти активацій для поточного батча; шкала спільна й логарифмічна, інакше 0.01 МБ і 400 МБ не вміщаються на одному малюнку. Активації рахуємо як суму виходів усіх згорток, пулінгів і лінійних шарів у float32.

Час одного проходу

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

мережавхідчас, мсу скільки разів
ShapeNet (тема 09)1×28×28≈ 0.261×
AlexNet3×224×224≈ 40≈ 150×
VGG163×224×224≈ 480≈ 1 800×
ResNet183×224×224≈ 75≈ 290×

Тут ховається несподіванка, яку варто назвати. VGG16 важить лише вдвічі більше за AlexNet за параметрами, а рахується у дванадцять разів довше. Причина проста, щойно згадаєш розділ 3: час іде не на ваги, а на множення. AlexNet у першому ж шарі стискає картинку вчетверо кроком 4 і далі працює з картами 27×27 і 13×13. VGG16 чесно проганяє дві згортки по повній стороні 224×224, і тільки потім починає зменшувати.

Тобто параметри й обчислення — це різні ресурси. Голова VGG16 тримає 89 % ваг і майже не витрачає часу: помножити рядок на матрицю — одна операція на вагу. Згортки тримають 11 % ваг і зʼїдають майже весь час, бо кожна вага використовується стільки разів, скільки позицій має карта.

За що ми платимо

Чотири мережі, пʼять мірок. Перемикай мірку — і дивись, як міняється переможець.

мірка
найменше—
найбільше—
Точність — top-1 на ImageNet, цитована з опису ваг torchvision, а не заміряна нами: щоб її поміряти, потрібні самі ваги й увесь перевірочний набір. Наша ShapeNet вирішує іншу задачу на шести класах, тож у мірках точності її немає. Час і памʼять — наші власні заміри.

ПомерлоЩо з цього померло

Три речі з AlexNet не пережили наступних пʼяти років. Про кожну варто знати, бо вони досі трапляються в старих схемах і старому коді.

Локальна нормалізація відгуку

Локальна нормалізація відгуку (local response normalization, LRN) — шар, який ділив відгук кожного каналу на щось на кшталт середньої сили сусідніх каналів у тій самій точці. Ідея бралася з біології: сильно збуджений нейрон пригнічує сусідів, тож серед каналів виграє найяскравіший.

Автори AlexNet повідомили, що LRN дала їм приблизно 1.4 пункту top-1 точності. Через два роки автори VGG перевірили це на своїй мережі й написали прямо: покращення немає, а памʼять і час LRN їсть. Після цього шар зник. Сьогодні у файлі torchvision/models/alexnet.py його немає взагалі — те, що ти будуєш через alexnet(weights=None), іде без LRN.

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

Великі ядра

11×11 і 5×5 із розділу 3. Причина смерті порахована там же: те саме рецептивне поле дешевше набирається стосом 3×3, а нелінійностей при цьому більше. Великі ядра повернулись через десять років у зовсім іншому контексті — у мережах, що імітують трансформери, — але це вже інша історія й інші причини.

Дві гілки

Померли разом із трьома гігабайтами відеопамʼяті. У torchvision усі згортки AlexNet мають groups=1. Але сама групована згортка не померла, а перевідкрилась як спосіб економити обчислення — тема 15.

Спільна риса всіх трьох. Кожна з цих ідей була відповіддю на обмеження свого часу: LRN — на відсутність нормалізації, великі ядра — на брак обчислень, гілки — на брак памʼяті. Обмеження зникли, ідеї лишились у схемах. Це корисна звичка: побачивши в чужій архітектурі дивне рішення, спитай не «навіщо це», а «що було неможливим, коли це писали».

ЛишилосьЩо з цього лишилось

А тепер зворотний список — те, що з 2012 року не змінилось узагалі.

Що лишилосьДе ти це вже бачив
ReLU як стандартна нелінійністьТема 11. Варіанти зʼявилися (GELU, SiLU), але базова ідея «відрізати відʼємне» стоїть скрізь
ДропаутТема 11. Із згорткових шарів пішов, у головах і трансформерах лишився
АугментаціяТема 10. Випадковий виріз і віддзеркалення — досі перші дві аугментації в будь-якому рецепті
«Глибше — краще»Саме це довела VGG. Із застереженням, яке зʼясується вже в наступній темі
Ознаки треба вчити, а не придумуватиТема 05

Останній рядок — найважливіший, і на ньому варто зупинитись.

У темі 05 ми розбирали класичні ознаки: SIFT, HOG, кутові точки Гарріса. Кожну з них придумала людина, яка сіла й подумала, що саме треба виміряти на зображенні, щоб предмети розрізнялись. Це були розумні, добре обґрунтовані конструкції — і саме вони посідали друге місце на ImageNet 2012 з помилкою 26.2 %.

AlexNet не придумала жодної ознаки. Вона взяла 61 мільйон випадкових чисел і дозволила даним налаштувати їх так, як тим зручно. Результат — 15.3 %. І це, а не глибина й не відеокарти, і є справжній зміст 2012 року: перевірка на тому, що ознаки, знайдені даними, бʼють ознаки, придумані людиною, — і перевірку придумані ознаки програли з розгромним рахунком.

Ми вже бачили відлуння цього в самій бібліотеці. OpenCV 5 викинула HOGDescriptor і каскади Хаара цілком, а натомість додала навчені детектори ознак. Те, що у 2012 році було результатом змагання, за десять років стало рішенням про склад бібліотеки.

ПідсумокПідсумок

Що ми порахували в цій темі:

Головний висновок теми звучить дивно для теми про перші глибокі мережі: наступним кроком галузі було не «ще глибше», а «прибрати голову». Заміна трьох повнозвʼязних шарів на глобальне усереднення робить VGG16 у девʼять разів легшою, нічого не забираючи в згорток. Саме це й зробили далі — і саме тому ResNet18 із двадцятьма згортковими шарами важить менше за AlexNet із пʼятьма.

Що далі

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

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

Про це — тема 14, ResNet і скіп-зʼєднання. Далі йде тема 15, де ту саму задачу вирішують економією обчислень, і там знову спливе групована згортка з розділу 4 — уже як свідомий прийом, а не як обхідний маневр.