Усі тридцять шість попередніх тем мережа щось розпізнавала: казала клас, малювала рамку, фарбувала маску, міряла глибину. На вході було зображення, на виході — відповідь, і відповідь була коротшою за вхід. Тепер повернемо стрілку. Вхід — коротке, вихід — зображення. Мережа має не описати картинку, а намалювати її.
Найпростіший спосіб підійти до цього — навіть не намагатися генерувати. Візьмемо мережу й попросимо її зробити щось безглузде на вигляд: віддати на виході рівно те, що прийшло на вхід. Тотожність. Задача, яку розвʼязує оператор присвоєння.
ГорлоСтиснути, щоб зрозуміти
Безглуздою вона лишається рівно доти, доки ми не поставимо посередині пляшкове горло (bottleneck) — шар із дуже малою кількістю чисел. Тоді зображення 28×28, тобто 784 числа, мусить пролізти крізь горло з восьми — і аж тоді задача стає осмисленою. Пройти крізь горло можна, тільки викинувши все зайве, а «зайве» мережа мусить визначити сама.
Мережа з таким горлом зветься автоенкодером (autoencoder) і складається з двох половин:
Стискає зображення до восьми чисел. У нас це дві згортки з кроком 2 (28×28 → 14×14 → 7×7) і лінійний шар. Ті вісім чисел звуться латентним кодом (latent code), а простір, у якому вони живуть, — латентним простором.
Розгортає вісім чисел назад у 28×28. Дзеркало енкодера: лінійний шар і дві транспоновані згортки. Це та сама будова, що в U-Net із теми 30, тільки без скіп-зʼєднань — бо саме вони дозволили б обійти горло, а нам потрібно, щоб обійти було неможливо.
Транспонована згортка (ConvTranspose2d) робить те саме, що
звичайна згортка з кроком 2, тільки навпаки: та зменшувала сторону вдвічі, ця
вдвічі її збільшує. Кожен вхідний піксель множиться на ядро й «розсіюється» на
кілька сусідніх вихідних, а там, де розсіяне від сусідів накладається, значення
додаються — саме так із карти 7×7 виходить 14×14.
Порівнюємо вихід із входом попіксельно. Середній квадрат різниці — і все. Ані міток, ані розмітки, ані людини. Це різновид самонаглядового навчання з теми 16, і привід тут найпростіший з можливих: відповіддю є сам вхід.
Куди дівається зображення дорогою до восьми чисел
Той самий шлях, що описаний вище словами. Під кожним кроком стоїть розмір того, що з нього виходить; горло намальоване вузьким навмисне — саме воно змушує мережу вибирати, що лишити.
Наскрізний приклад теми — той самий набір, що й у решті блоку: шість фігур 28×28 (коло, квадрат, ромб, кільце, хрест, трикутник), центр гуляє на пʼять пікселів у будь-який бік, радіус від пʼяти до восьми, зверху гаусів шум 0.06. Автоенкодер з латентом 8 має 16 769 ваг — менше, ніж пікселів у двадцяти двох картинках.
ШиринаСкільки чисел треба фігурі
Наскільки вузьким має бути горло? Питання не риторичне: у ньому весь сенс конструкції. Занадто широке горло — і мережа просто перепише вхід на вихід, нічого не зрозумівши. Занадто вузьке — і вона фізично не встигне вкласти туди форму.
Порахуємо спершу руками, скільки інформації в наших фігурах узагалі є. Шість класів, одинадцять положень центра по вертикалі, одинадцять по горизонталі, чотири радіуси: 6 × 11 × 11 × 4 = 2904 різні фігури. Щоб занумерувати їх усі, досить дванадцяти двійкових розрядів — бо 212 = 4096, а це більше за 2904. Вісім дійсних чисел вміщають незрівнянно більше, тож із погляду самої лише ємності горло в нас із величезним запасом.
Але ємність — не те саме, що досяжність. Ми навчили автоенкодери з латентом 1, 2, 4, 8, 16 і 32, по три зерна на кожну ширину, і подивились, що дає кожне подвоєння.
Що дає кожне подвоєння горла
Ліворуч — та сама фігура, відновлена автоенкодером цієї ширини. Праворуч — похибка відновлення на всіх шести ширинах; пунктир — шумова підлога 0.00180, нижче якої не буває.
Злам виразний, і спокуса прочитати його просто: мовляв, форма вклалась у вісім чисел, а далі йдуть дрібниці. Картинка ліворуч цю спокусу знімає. Наш пробний приклад — кільце, тобто фігура з діркою посередині, і жодна з шести ширин цієї дірки не відтворила. Навіть при латенті 32.
Прочитаймо тоді числа чесніше. Похибка спиняється на 0.02472, а шумова підлога — 0.00180: ми зупинились майже в чотирнадцять разів вище за межу. Отже впертися ми могли в що завгодно, тільки не в ємність горла — 2904 варіанти фігури вклалися б у дванадцять двійкових розрядів, а в нас їх вісім дійсних чисел. Уперлись ми в мережу: маленький декодер із двох транспонованих згорток за 12 епох навчився ставити пляму потрібного розміру в потрібне місце, і на цьому спинився.
Зверни увагу на розкид при латенті 1: ±0.02644 при середньому 0.09612. Це майже третина від значення, і три зерна дали 0.13350, 0.07845 і 0.07642. Одне число тут вирішує, у яку канаву впаде навчання, і саме тому міряти на одному зерні не можна. При латенті 16 розкид уже ±0.00087 — навчання стабільне.
СуддяСуддя, який завжди відповідає
Тепер найцікавіше. Автоенкодер уміє відновлювати. А чи вміє він малювати нове? Щоб відповісти, треба спершу навчитися це питання ставити числом — і ось тут починається справжня тема.
Перша ідея очевидна: візьмемо окремий класифікатор шести фігур, навчений на справжніх даних, і покажемо йому те, що намалювала модель. Назвемо його суддею. Якщо суддя впевнено каже «це квадрат» — мабуть, квадрат і намальовано.
Суддя влаштований звичайно: два згорткові блоки й лінійна голова. На справжніх фігурах він дає точність рівно 1.0000 із середньою впевненістю 0.9914 — задача для нього тривіальна, а отже будь-яка його невпевненість на згенерованому щось означає.
Так здається. Насправді ні, і причину видно з будови задачі, ще до першого заміру.
КалібруванняСпершу калібруй вимірювач
Метрика генерації — не термометр, перевірений на заводі. Це саморобний прилад, який ми щойно спаяли самі. Перш ніж вірити його показанням на невідомому, треба подивитись, що він показує на завідомо поганому.
Ми зібрали вісім наборів по 600 зображень, кожен зіпсований по-своєму, і пропустили їх крізь чотири кандидати в метрики. Ось ці кандидати:
| Кандидат | Що рахує | Логіка |
|---|---|---|
| впевненість судді | середня найбільша ймовірність | гарний зразок суддя впізнає впевнено |
| покриття класів | скільки з шести фігур набрали хоч 1 % вибірки | модель має малювати всі фігури, а не одну |
| зразок → найближча справжня | для кожного зразка шукаємо найсхожішу справжню фігуру й міряємо відстань до неї | зразок має бути схожий хоч на щось справжнє |
| справжня → найближчий зразок | для кожної справжньої фігури шукаємо найсхожіший зразок і міряємо відстань до нього | зразки мають покрити все розмаїття, а не куточок |
Дві останні потребують одного уточнення: відстань тут — відстань між двома картинками. Ми віднімаємо одну від одної піксель за пікселем і дивимось, наскільки великою вийшла різниця; нуль означає точний збіг, а що більше пікселів розійшлось і що сильніше — то число більше. Одиниць у нього немає, тож саме по собі воно нічого не каже: сенс має тільки порівняння з тим, що дають справжні фігури. Саме тому першим рядком таблиці калібрування стоїть «справжні, інша вибірка» — це й є та риска, відносно якої читаються всі інші числа.
Що показує вимірювач на завідомо поганому
Обери набір — і подивись, як поводиться кожен із чотирьох кандидатів. Риска на смужках — те, що дають справжні фігури.
Дві метрики з чотирьох провалились, і кожна по-своєму.
Впевненість судді провалилась повністю. Біле полотно не містить жодної фігури, і суддя впевнений у ньому більше, ніж у справжньому колі. Це не поганий суддя й не помилка навчання — це прямий наслідок того, що в нього немає варіанта «нічого з переліченого». Біле полотно просто лежить дуже далеко від межі між класами, а softmax тим упевненіший, чим далі точка від межі.
Відстань «зразок → найближча справжня» провалилась теж, і це менш очевидно. У наборі «лише кола» вона дорівнює 4.3182, а в справжніх фігур — 4.4583. Тобто повний колапс мод виглядає за цією метрикою краще за справжні дані. Логіка прозора: якщо малювати самі кола, то кожне намальоване коло справді дуже схоже на якесь справжнє коло з полиці. Метрика міряє якість окремого зразка й за побудовою сліпа до того, що всі зразки однакові.
ПараПара, яка працює
Два кандидати, що лишились, поодинці теж не годяться — але разом закривають один одного.
Покриття класів ловить колапс: «лише кола» дає 1, «кола + квадрати» дає 2 замість шести. Але воно сліпе до якості. Подивись на «чистий шум»: суддя розкидав випадкові плями по чотирьох класах, і покриття чесно показало 4.
Відстань «справжня → найближчий зразок» ловить решту. Вона питає інше: чи для кожної справжньої фігури знайдеться схожий зразок. У колапсі не знайдеться — для справжнього кільця немає жодного схожого кола, і число росте з 4.3831 у справжніх до 5.0618. У шумі воно злітає до 14.8129.
| набір | впевненість | класів | зразок → спр. | спр. → зразок |
|---|---|---|---|---|
| справжні, інша вибірка | 0.9913 | 6 | 4.4583 | 4.3831 |
| лише кола | 0.9777 | 1 | 4.3182 | 5.0618 |
| кола + квадрати | 0.9827 | 2 | 4.0639 | 5.0592 |
| розмита каша | 0.6264 | 3 | 5.1070 | 5.5796 |
| середнє всіх фігур | 0.7253 | 1 | 5.2523 | 7.8265 |
| усе чорне | 0.9925 | 1 | 6.6102 | 10.0414 |
| чистий шум | 0.8233 | 4 | 15.1786 | 14.8129 |
| усе біле | 0.9997 | 1 | 23.6225 | 25.4007 |
Правило теми звідси таке: модель добра тоді, коли обидва числа пари добрі. Високе покриття при великій зворотній відстані означає різноманітне сміття. Мала зворотна відстань при низькому покритті означає охайний колапс. Кожен із восьми зіпсованих наборів провалюється хоча б за одним числом — і таблиця вище показує це рядок за рядком.
І ще один доказ, що впевненість судді треба викинути. Ми навчили трьох суддів — на 10, 20 і 40 епохах — і показали їм ті самі зображення. Змінюється лише те, хто дивиться.
| суддя | точність | справжні | автоенкодер | VAE β=0.2 | лише кола | чистий шум |
|---|---|---|---|---|---|---|
| 10 епох | 0.9317 | 0.7775 | 0.7593 | 0.6200 | 0.5611 | 0.6351 |
| 20 епох | 0.9950 | 0.9610 | 0.8371 | 0.7182 | 0.9191 | 0.6905 |
| 40 епох | 1.0000 | 0.9914 | 0.8922 | 0.7921 | 0.9777 | 0.8233 |
Впевненість на колапсі виросла з 0.5611 до 0.9777 — у той час, як самі зображення не змінилися ані на піксель. Отже це число описує не зразки, а суддю. Довше навчений класифікатор просто гостріший, і гострий він однаково на всьому: і на фігурах, і на сміттях.
ПорожнечаЗвідки беруть z
Тепер повернімось до питання, заради якого все це будувалось. Щоб намалювати
нову картинку, ми не подаємо на вхід нічого. Ми беремо вісім чисел з повітря
й просимо декодер їх намалювати. «З повітря» на практиці означає з нормального
розподілу: кожен вимір тягнемо з N(0, 1).
Питання, яке тут пропускають майже завжди: а чи лежать у тому місці коди справжніх зображень? Порахуємо руками. Довжина вектора з восьми стандартних нормальних чисел у середньому близька до кореня з восьми, тобто до 2.83. Тепер подивимось, де насправді лежать коди автоенкодера.
Куди ми цілимось, тягнучи z із N(0, 1)
Ліворуч — у масштабі: кулька, з якої ми беремо z, і хмара, де насправді лежать коди. Праворуч — вісім зразків, які видав декодер.
Це і є відповідь на питання, чому автоенкодер не є генератором, і вона не метафорична. Ми питаємо декодер про точку, у якій він ніколи не навчався. Під час навчання на вхід декодера приходили вектори довжиною близько тридцяти; ми подаємо йому вектор довжиною три. Що він намалює — не визначено нічим.
Слово «дірка» тут навіть занадто мʼяке. Це не проміжок між двома кластерами кодів — це зовсім інша область простору, куди навчання не заглядало.
ХмаркаХмарка замість точки
Полагодити це можна одним рухом: змусити коди жити там, звідки ми потім братимемо z. Не «десь поруч», а саме там — у стандартному нормальному розподілі.
Спосіб, який для цього придумали, зветься варіаційним автоенкодером, або
просто VAE. Ідея на один абзац: енкодер видає не точку, а хмарку.
Замість восьми чисел він видає шістнадцять — вісім центрів mu й вісім
ширин sigma, по одній парі на вимір. Кодом зображення стає не одна
точка, а цілий розподіл навколо неї.
З цього одразу випливають дві речі. По-перше, декодерові тепер щоразу показують трохи іншу точку з тієї самої хмарки, тож він мусить навчитися малювати одне й те саме з цілого околу — а не з єдиної точки. Порожнеч між кодами стає менше просто тому, що кожен код займає обʼєм, а не нуль.
По-друге — і це головне — тепер є за що вхопитися, щоб притягнути коди до нуля. Хмарку можна порівняти зі стандартним нормальним розподілом і покарати за відхилення. Ця відстань між розподілами зветься розбіжністю Кульбака — Лейблера й у нашому випадку рахується формулою:
Розберімо її по частинах, бо вона виглядає страшніше, ніж є.
Вимірів у нас вісім, тож усередині дужок рахується вісім однакових виразів і всі складаються. Ніякої іншої математики в цьому символі немає.
Чим далі центр хмарки від нуля, тим більше mu², тим більший штраф. Це прямо те, чого нам бракувало в автоенкодері.
Якщо хмарка надто вузька, sigma² мале, і log sigma² іде в мінус нескінченність — штраф величезний. Якщо надто широка, великим стає сам sigma². Мінімум цієї пари припадає рівно на sigma = 1.
Вони потрібні лише для того, щоб при mu = 0 і sigma = 1 весь вираз дорівнював нулю. Підстав ці значення: log 1 = 0, і в дужках лишається 1 + 0 − 0 − 1 = 0. Штрафу немає — саме те, чого ми хотіли.
Тобто KL — це один вимірювач: наскільки хмарка, яку видав енкодер, не схожа на стандартну. Нуль означає «точнісінько така, як треба».
Що саме штрафує KL
Ліворуч — та сама пара чисел, яку тепер видає енкодер: замість однієї точки центр і ширина. Праворуч — сам штраф, порахований за формулою вище: окремо як функція центра (при ширині 1) і окремо як функція ширини (при центрі 0).
ХитрістьРепараметризація
Лишилось одне місце, і воно тонке. Декодерові треба одна точка з хмарки. Здавалося б, візьми та й насемпли.
Не вийде — і причина не в тому, що це складно, а в тому, що після цього мережа перестане навчатися. Згадаймо, як узагалі працює навчання: ми рахуємо втрату, потім похідну втрати по кожній вазі, потім зсуваємо ваги проти градієнта. Щоб градієнт дійшов до енкодера, кожен крок від ваги до втрати має бути записаною операцією, яку можна продиференціювати.
А вибірка з розподілу такою операцією не є. Витягнеш число зі свого генератора,
запишеш його в тензор — і звʼязок обірвано: результат ніяк не памʼятає, що центр
хмарки був 1.5, а не 1.4. Перевірити це просто: у такого тензора
requires_grad дорівнює False, а графа обчислень немає
взагалі. Похідної не існує не тому, що її важко порахувати, — її немає що
рахувати.
Хитрість, яка це розвʼязує, зветься репараметризацією (reparameterization trick) й полягає в тому, щоб винести випадковість убік:
Подивись, що змінилось. Випадкове число eps тепер тягнеться
окремо й не залежить ані від mu, ані від sigma. А сам z виходить із них
звичайними додаванням і множенням — операціями, які диференціюються тривіально.
Похідна z по mu дорівнює одиниці, похідна по sigma дорівнює eps. Градієнт
проходить наскрізь.
Розподіл при цьому не змінюється: якщо eps стандартне нормальне, то mu + sigma·eps має рівно те саме нормальне з центром mu й шириною sigma. Ми не підмінили задачу, ми лише інакше її записали.
torch.normal(mu, sigma) виглядає бездоганно: у результату є
grad_fn, тобто граф обчислень будується. Але похідна по
mu в нього дорівнює нулю. Градієнт проходить крізь цей вузол і
не приносить нічого. Це найгірший вид відмови: код працює, навчання йде, енкодер
мовчки не вчиться. Правильні імена — наша формула руками або
Normal(mu, sigma).rsample(), де r означає рівно
reparameterized; звичайний sample() градієнта не має
взагалі.Обійтися без репараметризації теоретично можна: існує оцінка градієнта через логарифм щільності, і вона незміщена, тобто в середньому правильна. Питання не в правильності, а в розкиді.
Чому обхідний шлях не годиться
Задача, де відповідь відома точно: похідна середнього від z² по mu дорівнює 2·mu, тобто при mu = 1.5 рівно 3.0. Обидві оцінки в середньому правильні — подивись на ширину.
Двадцять чотири рази більше зразків на кожному кроці навчання — це не уточнення, це вирок. Саме тому VAE став практичним лише разом із репараметризацією, а не раніше.
ВагиДві половини втрати й що робить β
Тепер зберімо втрату VAE. У ній рівно дві половини, і вони тягнуть у різні боки:
Перша половина хоче, щоб код ніс якнайбільше інформації про конкретне зображення. Друга хоче, щоб код був схожий на випадковий шум. У межі друга виграє повністю — усі коди сходяться в нуль, декодер малює одне й те саме, і KL дорівнює нулю. Це відомий провал, який зветься колапсом апостеріорного розподілу (posterior collapse): «апостеріорний» тут означає той самий розподіл, який енкодер видає після того, як побачив зображення, — тобто нашу хмарку. Колапс — це коли хмарка перестає залежати від зображення взагалі.
Множник β вирішує, кого слухати. Ще одна деталь, яку часто ховають: похибка відновлення в нас — середнє по 784 пікселях, а KL — сума по восьми вимірах латента. Щоб β означало те саме, що в статтях, KL ділиться на 784: тоді обидві половини стають «на один піксель». Без цієї домовленості число β не означає нічого, і порівнювати його з чужою роботою не можна.
| β | відновлення | розмах кодів | класів | спр. → зразок |
|---|---|---|---|---|
| 0 (автоенкодер) | 0.02129 | 6.77 | 3.00 | 7.1035 |
| 0.2 | 0.02260 | 1.10 | 4.33 | 5.2020 |
| 1 | 0.03168 | 0.78 | 3.67 | 5.1762 |
| 4 | 0.05103 | 0.43 | 3.00 | 5.4614 |
Компроміс видно в двох перших стовпчиках: від β=0.2 до β=4 похибка відновлення росте з 0.02260 до 0.05103, а розмах кодів падає з 1.10 до 0.43. Хмарки стискаються до прописаної їм одиничної ширини — рівно те, чого KL і вимагає.
Але четвертий стовпчик суперечить очікуванню, і це варте окремої уваги. Логіка «більше β — щільніший латент — краще покриття» тримається лише до певної межі. Після неї друга половина втрати вже не впорядковує латент, а псує декодер: при β=4 похибка відновлення 0.05103, тобто в 2.4 раза гірша за автоенкодерну, і декодер малює розмиті плями. Суддя такі плями розкладає по двох-трьох класах, і покриття падає.
У нашому замірі найкраще генерує β=0.2: покриття 4.33 — найбільше з чотирьох моделей. Зворотна відстань у нього 5.2020 проти 5.1762 у β=1, але купи по зернах тут перетинаються ([5.1798, 5.1864, 5.2398] проти [4.8983, 4.9411, 5.6893]), тож різниці між ними немає. Головне інше: найкращий β — проміжний, а не найбільший.
РозбіжністьХто виграє, залежить від метрики
Тепер головна таблиця теми. Чотири моделі з однаковим кістяком і латентом 8, по три зерна кожна, пʼять чисел на кожну.
| модель | відновлення | впевненість | класів | зразок → спр. | спр. → зразок |
|---|---|---|---|---|---|
| автоенкодер | 0.02129 | 0.8239 | 3.00 | 8.1355 | 7.1035 |
| VAE β=0.2 | 0.02260 | 0.7961 | 4.33 | 6.0850 | 5.2020 |
| VAE β=1 | 0.03168 | 0.7785 | 3.67 | 4.7747 | 5.1762 |
| VAE β=4 | 0.05103 | 0.7384 | 3.00 | 4.7987 | 5.4614 |
Візьми поглядом два рожеві рядки — автоенкодер і β=4 — і прочитай їх у двох стовпчиках. За похибкою відновлення автоенкодер кращий у 2.4 раза. За зворотною відстанню кращий β=4. Одні й ті самі дві моделі, дві метрики, протилежне впорядкування.
І це не гра середніх. Купи по трьох зернах не перетинаються в обох випадках, а за критерієм курсу (тема 26) саме це є доказом справжньої різниці:
| метрика | автоенкодер, три зерна | VAE β=4, три зерна | купи |
|---|---|---|---|
| відновлення | 0.02002 · 0.02050 · 0.02336 | 0.04757 · 0.04906 · 0.05646 | не перетинаються |
| спр. → зразок | 6.7896 · 6.9806 · 7.5402 | 5.1295 · 5.2800 · 5.9745 | не перетинаються |
Переможець змінюється разом із метрикою
Обери метрику — і подивись, хто виявиться найкращим. Крапки — окремі зерна, смуга — середнє.
Особливо повчальний стовпчик впевненості. Він ставить автоенкодер першим (0.8239) — тобто найгіршу з чотирьох моделей за генерацією називає найкращою. Але чесність вимагає додати: розкид тут ±0.0493, і купи по зернах перетинаються з усіма трьома іншими моделями. Тобто метрика, яка впорядковує неправильно, ще й не показує жодної доведеної переваги: її не можна ані підтвердити, ані спростувати — і саме тому нею не користуються.
ШляхШлях між двома кодами
Класична демонстрація автоенкодерів виглядає так: беруть коди двох різних зображень, зʼєднують відрізком і малюють те, що виходить у проміжних точках. Підручникова обіцянка: у VAE середина осмислена, а в автоенкодері — привид із двох фігур, накладених одна на одну.
Ми цю обіцянку перевірили числом, і вона не підтвердилась. Розкажемо чесно, як міряли.
Беремо 40 пар тестових зображень різних класів, зʼєднуємо їхні коди відрізком і йдемо по ньому девʼятьма кроками.
Розрив — відстань від точки шляху до найближчого справжнього коду, поділена на типову відстань між сусідніми кодами. Ділення обовʼязкове: коди автоенкодера живуть на масштабі 3.701, а коди VAE — на масштабі 0.675, і без нормування числа непорівнянні взагалі.
У середині шляху розрив дорівнює 1.75 кроку сітки в автоенкодера й 1.69 у VAE. Різниця — шість сотих кроку.
Іти від однієї фігури до іншої
Веди повзунок від однієї фігури до другої й дивись, що декодер малює по дорозі. Внизу — розрив у кожній із девʼяти точок шляху.
Чому так вийшло — зрозуміло, якщо згадати попередні розділи. Декодер — це гладка функція, і будь-яка точка латента щось малює. Різниця між автоенкодером і VAE не в тому, що між двома справжніми кодами по-різному порожньо. Різниця в тому, де ці коди лежать: у VAE — там, звідки ми потім тягнемо z, а в автоенкодера — за тридцять одиниць від того місця.
КартаКарта латентного простору
Лишилось подивитись, що взагалі опинилось у тих восьми числах. Вісім вимірів намалювати не можна, тож стиснемо їх у два методом головних компонент: шукаємо той напрямок у восьмивимірному просторі, уздовж якого точки розкидані найсильніше, потім другий такий напрямок, перпендикулярний до першого, — і малюємо на площині тіні всіх точок на цю пару напрямків. Тіні зберігають те, чим точки різняться найбільше, і гублять решту; підпис під картинкою каже, яку частку розкиду ці два напрямки втримали. Фарбуємо точки за справжніми класами — тими самими, яких мережа не бачила жодного разу.
Число «сусіди дають клас» під картинкою рахується не по цих двох напрямках, а по всіх восьми: беремо кожну точку, знаходимо найближчі до неї коди інших зображень і питаємо, чи збігається їхній клас із її власним. Якщо латент нічого про клас не знає, збігів буде стільки, скільки дасть випадкове вгадування, — одна шоста.
Що групується в латенті насправді
Перемкни розфарбування — і подивись, яка ознака дає охайніші купи: клас фігури чи те, у якій чверті кадру вона стоїть.
Це чесніша картинка, ніж звична ілюстрація з охайними кольоровими островами. Автоенкодер не має жодних підстав вважати клас важливішим за положення: обидва однаково потрібні, щоб відновити зображення. У наших даних центр гуляє на пʼять пікселів у кожен бік, і це просто більша частина мінливості, ніж вибір однієї фігури з шести.
Висновок звідси практичний і переноситься далеко за межі теми: латент кодує те, що потрібно для відновлення, а не те, що цікаво тобі. Якщо потрібен латент, у якому групується саме клас, доведеться або прибрати мінливість положення з даних, або додати в задачу щось, що про клас питає.
ПідсумокЩо з цього забрати
Коротко про кожну з чотирьох речей, які тема заміряла.
| Твердження | Чим доведено |
|---|---|
| пляшкове горло змушує вивчити суть | восьми чисел досить; далі подвоєння дає 11 % замість 30 % |
| впевненість класифікатора не є мірою якості генерації | біле полотно дістає 0.9997 проти 0.9913 у справжніх фігур |
| автоенкодер не є генератором | 0.0 % його кодів лежать там, звідки ми тягнемо z |
| дві метрики впорядковують протилежно | непересічні купи в обидва боки на автоенкодері й β=4 |
І окремо — про метод, бо він у цій темі важливіший за результат. Метрику генерації калібрують перед тим, як їй вірити. Не після того, як числа не зійшлися, а до першого заміру. Вісім завідомо поганих наборів коштують десяти рядків коду й рятують від охайної таблиці з протилежним до правди висновком.
Це та сама лінія, що йде крізь увесь курс. У темі 29 точність по пікселях 0.9001 стояла поруч із mIoU рівно нуль. У темі 32 mIoU дорівнював одиниці при PQ 0.5292. У темі 35 ті самі ознаки давали 0.4000 при усередненні по часу і 1.0000 при розгортці часової осі. Блок 8 доводить її до межі: у генерації метрики, яку можна цитувати саму, не існує взагалі — і саме тому для неї довелося вигадувати окрему метрику FID, що дивиться на розподіл, а не на окремий знімок; наступна тема розбирає її формулу.
Що лишилось незробленим. VAE полагодив місце, звідки беруть z, але заплатив розмиттям: наші зразки при β=0.2 упізнавані, та жоден із них не має різкого краю. Причина проста й неусувна в межах цього підходу — втрата відновлення усереднює. Коли модель не впевнена, де саме межа фігури, найдешевший спосіб зменшити середній квадрат різниці — намалювати межу трохи скрізь.
Наступна тема відмовляється від явної втрати відновлення взагалі. Замість того щоб порівнювати намальоване з оригіналом попіксельно, вона ставить проти генератора суперника — другу мережу, яка вчиться відрізняти підробку від справжнього. Розмиття зникає, бо суперник його одразу помічає. А натомість зʼявляється хвороба, якої в автоенкодерів немає: генератор може знайти дві-три картинки, що надійно обманюють суперника, і почати малювати тільки їх. Ця хвороба зветься колапсом мод, і міряти її ми вже вміємо — покриттям класів, яке ця тема відкалібрувала.