Сегментація мусить відповісти за кожен піксель. Але щоб зрозуміти, що
на картинці зображено, мережа стискає її: пулінг за пулінгом, доки від
полотна 64 × 64 не лишиться карта 8 × 8. У цій карті багато знання про предмет і
майже нічого про його край — один її піксель відповідає квадрату 8 × 8 вхідних.
Тема 29 показала два способи
жити з цим: не стискати взагалі (атрозні згортки) або розтягувати назад
(ConvTranspose2d). Є третій, і він виявився найживучішим: стиснути,
а деталі взяти з ранніх шарів, доки їх ще не викинули. Це U-Net. А головне
питання теми — не «чи допомагають скіпи», а з якої глибини вони починають
вирішувати, бо поки стискання невелике, губити просто нема чого.
ЗалишокЩо лишилось після теми 29
Зберемо, з чим ми прийшли. Постановку й метрики дала попередня тема, і ми беремо їх готовими, не переказуючи.
| що вже є | звідки й що це означає |
|---|---|
| постановка | тема 29: кожному пікселю — клас; вихід мережі має розмір входу |
| метрики | тема 29: mIoU й Dice, звʼязані як Dice = 2·IoU/(1+IoU); на поганих масках Dice майже вдвічі оптимістичніший |
| дисбаланс | тема 29: фон зʼїдає близько 90 % полотна, і модель, що фарбує все фоном, дає стільки ж правильних пікселів при mIoU рівно нуль |
| білінійне збільшення | тема 29: дешево, але нічого не додає — розмиває те, що є |
ConvTranspose2d | тема 29: навчений спосіб розтягнути карту. Можливостей у неї більше, ніж у білінійного збільшення, але вигадувати деталі з нічого їй так само нема з чого — на сценах теми 29 вона програла навіть йому (0.1673 проти 0.2268) |
| атрозні згортки й ASPP | тема 29: рецептивне поле росте без стискання, ціна — памʼять і час, бо карта лишається великою |
Обидва підходи теми 29 мають ту саму ваду, тільки з різних боків. Атрозна згортка не втрачає роздільність — але за це доводиться тягнути велику карту крізь усю мережу, а це памʼять і час. Збільшення повертає розмір — але не повертає інформацію: те, що витерли пулінгом, у карті 8 × 8 просто відсутнє, і жодне розтягування його не воскресить.
Ось третя думка, і вона до смішного проста. Інформація нікуди не поділась — вона лежить у ранніх шарах тієї самої мережі. Карта після першого згорткового блоку має повну роздільність 64 × 64. Її просто ніхто не питав. Треба взяти її і подати декодерові прямо, в обхід усього стискання.
ІдеяІдея U-Net
U-Net (2015) — мережа у формі букви U. Ліва половина, енкодер, іде вниз: згортковий блок, пулінг, згортковий блок, пулінг. З кожним кроком карта вдвічі менша, а каналів удвічі більше. Права половина, декодер, іде вгору дзеркально: розтягнути карту вдвічі, обробити, розтягнути ще раз.
Уся новизна — у горизонтальних перемичках. На кожному рівні декодер отримує дві карти: ту, що прийшла знизу, з глибших шарів, і ту, що прийшла збоку, прямо з енкодера того самого рівня. Ця бічна перемичка й зветься скіп-зʼєднанням (skip connection), або скіпом.
skip
тут означає, що сигнал оминає середину мережі, а не що якийсь шар не
працює. Усі шари працюють; просто в декодера зʼявляється друге джерело.Будова U-Net: що саме йде скіпом
Мережа глибини 3 на нашому полотні 64 × 64, базова ширина 6 каналів. Натисни рівень, щоб побачити розмір його карти, кількість каналів і скільки чисел іде перемичкою в декодер.
Формально одне зшивання виглядає так. Позначмо u — карту, розтягнуту
знизу, а s — карту зі скіпа того самого рівня. Обидві мають однаковий
розмір по висоті й ширині, але свою кількість каналів:
cat — це конкатенація, тобто «поставити поруч». Якщо в u
було 24 канали і в s теж 24, то на вході блоку їх стане 48. Жодне
число не змінилось: вони просто лежать в одному стосі, і наступна згортка сама
вирішує, кому яку вагу дати.
ЧомуЧому це працює
Щоб зрозуміти, чому перемичка дає так багато, треба побачити, що саме несуть карти на різних глибинах. Вони різні по двох осях одразу.
| рання карта (рівень 0) | глибока карта (дно) | |
|---|---|---|
| роздільність | висока: 64 × 64, піксель у піксель | низька: 8 × 8, один піксель на квадрат 8 × 8 |
| семантика | бідна: краї, плями, перепади яскравості | багата: «тут предмет, а не пляма шуму» |
| рецептивне поле | вузьке: кілька пікселів | широке: пів картинки |
Ані верхня карта, ані нижня самі по собі не дають того, що потрібно сегментації. Верхня знає, де край, але не знає, чий він. Нижня знає, чий предмет, але не знає, де саме проходить його межа. Скіп зшиває обидві — і декодер дістає відповідь на обидва питання одночасно.
Тепер поміряймо, скільки саме губиться при стисканні. Замір не потребує жодного
навчання: візьмімо еталонну маску, стиснімо її в 2, 4, 8 і 16 разів (у кожній
клітинці лишаємо клас, який займає в ній найбільшу площу), розтягнімо назад і
порахуймо mIoU проти оригіналу. Це стеля: краще за неї не
зробить навіть ідеальний декодер, який нічого не плутає, — бо решти інформації в
карті просто немає.
| рівень | стиснення | карта | mIoU | mIoU на межі | точність межі |
|---|---|---|---|---|---|
| 0 | 1 × | 64×64 | 1.0000 | 1.0000 | 1.0000 |
| 1 | 2 × | 32×32 | 0.9324 | 0.8052 | 0.8969 |
| 2 | 4 × | 16×16 | 0.8753 | 0.6547 | 0.7996 |
| 3 | 8 × | 8×8 | 0.7760 | 0.4928 | 0.6747 |
| 4 | 16 × | 4×4 | 0.6132 | 0.3801 | 0.5920 |
Читається це так. Стиснути маску вдвічі майже безпечно: стеля 0.9324, і хороша мережа підбереться до неї й без сторонньої допомоги. Стиснути ввосьмеро — уже боляче: стеля падає до 0.7760, а на смузі межі до 0.4928. При стисканні в шістнадцять разів від предмета лишається пляма з кількох клітинок: 0.6132 і 0.3801.
mIoU усереднювався по чотирьох
класах, у нас по двох.Що саме зникає при стисканні
Ліворуч — еталонна маска сцени. Праворуч — та сама маска, відновлена лише з карти вибраного рівня. Мережі тут немає взагалі: це чиста арифметика роздільності.
Ця таблиця вже підказує головне. Якщо стискання невелике, стеля висока — і скіп дає мало, бо декодерові й так є з чого відновити маску. Якщо стискання сильне, стеля низька — і без скіпа декодер приречений. Отже, десь між цими двома режимами має бути поріг. Знайдімо його.
ПорігПорогова глибина
Тепер головний замір теми. Одна й та сама мережа, чотири глибини стискання — від одного рівня (стискання вдвічі) до чотирьох (у шістнадцять разів), — у двох режимах: зі скіпами й без. Кожна точка навчена тричі, з трьох різних початкових наближень, і в таблиці стоїть середнє з розкидом.
| глибина | параметрів | mIoU зі скіпами | mIoU без скіпів | розрив | розкид |
|---|---|---|---|---|---|
| 1 рівень (2×) | 3 746 | 0.9969 ±0.003 | 0.9778 ±0.011 | +0.0191 | 0.0112 |
| 2 рівні (4×) | 16 790 | 0.9988 ±0.001 | 0.9466 ±0.029 | +0.0523 | 0.0294 |
| 3 рівні (8×) | 68 510 | 0.9986 ±0.001 | 0.8869 ±0.013 | +0.1117 | 0.0125 |
| 4 рівні (16×) | 274 478 | 0.9983 ±0.001 | 0.7448 ±0.013 | +0.2535 | 0.0129 |
Перше, що видно: мережа зі скіпами дає майже одне й те саме на будь-якій глибині — від 0.9969 до 0.9988. Тобто глибина сама по собі задачі не псує. Псує її глибина без скіпів: 0.9778, потім 0.9466, потім 0.8869, потім 0.7448. Чим сильніше стискання, тим більше втрачено — і тим гірший результат.
Друге: розрив росте не абияк, а приблизно вдвічі з кожним рівнем: 0.0191, 0.0523, 0.1117, 0.2535. Кожен зайвий пулінг подвоює ціну відсутнього скіпа.
Порогова глибина: де скіпи починають вирішувати
Дві криві — та сама мережа зі скіпами й без. Вуса — розкид по трьох зернах. Повзунок обирає глибину; табло порівнює розрив із розкидом.
А тепер — власне порогова глибина. Формальний критерій у нас один: розрив більший за розкид. За ним поріг дорівнює одному рівню: уже при стисканні вдвічі розрив 0.0191 перевищує розкид 0.0112. Тобто на наших сценах скіпи вирішують від самого початку.
Практичний поріг — інша річ, і він теж вимірюваний. Якщо питати «з якої глибини без скіпів мережа втрачає більше за десяту частину якості», відповідь — три рівні: там розрив уперше перевищує 0.1. До того скіпи корисні, але без них можна жити; починаючи з трьох рівнів — уже ні.
Порівняй ці числа зі стелею роздільності з розділу 3, і картина складеться остаточно. При одному рівні стеля 0.9324, а мережа без скіпів дає 0.9778 — вище за стелю. Протиріччя тут немає: стеля рахувалась для тупого «взяти переважний клас у клітинці», а навчений декодер розумніший — він знає, що предмети опуклі й гладкі, і домальовує край правдоподібно. Порахуймо цей запас на всіх чотирьох глибинах — просто відніміть один рядок від другого:
| глибина | стеля (розділ 3) | мережа без скіпів | запас над стелею | падіння стелі від 1 рівня |
|---|---|---|---|---|
| 1 рівень (2×) | 0.9324 | 0.9778 | +0.0454 | — |
| 2 рівні (4×) | 0.8753 | 0.9466 | +0.0713 | −0.0571 |
| 3 рівні (8×) | 0.7760 | 0.8869 | +0.1109 | −0.1564 |
| 4 рівні (16×) | 0.6132 | 0.7448 | +0.1316 | −0.3192 |
Мережа стоїть вище за стелю скрізь, і запас навіть росте з глибиною: 0.0454 → 0.1316, майже втричі. Тобто що грубіша карта, то більше навчений декодер додає понад тупе «переважний клас у клітинці» — він домальовує форму, якої в карті вже немає. Але останній стовпчик показує, чому це не рятує: поки запас додав 0.0862, стеля втратила 0.3192 — майже вчетверо більше. Провал мережі без скіпів — це провал стелі, а не декодера: декодер працює навіть краще, просто йому дають дедалі гірший матеріал.
РозкидСкіпи стабілізують навчання
У тій самій таблиці ховається другий результат, який легко проґавити. Подивись не на середні, а на розкиди.
| глибина | розкид зі скіпами | розкид без скіпів | у скільки разів більший |
|---|---|---|---|
| 1 рівень | 0.0025 | 0.0112 | 4.4 × |
| 2 рівні | 0.0005 | 0.0294 | 55.2 × |
| 3 рівні | 0.0013 | 0.0125 | 9.6 × |
| 4 рівні | 0.0013 | 0.0129 | 9.6 × |
⚠️ Останній стовпчик не ділиться з надрукованих: 0.0294 ÷ 0.0005 дає 58.8, а не 55.2. Обидва розкиди тут округлені до чотирьох знаків, а відношення пораховане до округлення — так само, як і решта відношень цієї теми. Дивись на порядок величини, а не на другий знак множника.
Мережа зі скіпами дає практично одне й те саме з будь-якого початкового наближення: розкид від 0.0005 до 0.0025, тобто третій знак після коми. Без скіпів розкид у 4-55 разів більший. Усі вісім чисел зняті на тих самих перевірних сценах 64 × 64 у двох класах «предмет / фон» — це той самий замір, що й у таблиці розділу 4, по три навчання з різних початкових ваг на кожну точку.
- розкид без скіпів від глибини майже не залежить: 0.0112, 0.0294, 0.0125, 0.0129. Три числа з чотирьох лежать поруч, і лише глибина 2 випадає вгору;
- розкид зі скіпами увесь тулиться до нуля: 0.0025, 0.0005, 0.0013, 0.0013. Це вже не величина, а її остача — числа такого порядку самі гуляють у рази.
І ще одне, чого не варто забувати: розкид із трьох зерен — це нижня оцінка розкиду, а не сам розкид. Три точки не бачать четвертої, якій не пощастило; додай зерен — і найвужчі числа в цій таблиці, найімовірніше, поповзуть угору. Ось чому висновок формулюється як «зі скіпами навчання передбачуване, без них — ні», а не як «рівно в 55 разів».
Причина та сама, що й у залишкових звʼязків теми 14, тільки з іншого боку. Скіп дає градієнту короткий шлях від виходу до ранніх шарів: щоб виправити край предмета, сигналу помилки не треба протискатись крізь усе дно мережі. Без скіпа цей шлях один і довгий, і від того, як лягли початкові ваги, залежить, чи мережа взагалі знайде хороше рішення.
Практичний висновок: скіпи економлять не лише якість, а й ваш час. З ними досить одного навчання, щоб оцінити ідею. Без них одне навчання нічого не каже — треба три, і навіть тоді доведеться писати «±0.03».
ЗшиванняКонкатенація проти додавання
Тема 14 уже давала нам скіп — але інший.
Залишковий блок ResNet рахує x + F(x): вхід блоку додається до
його виходу поелементно. U-Net вхід і вихід зшиває. Різниця здається
дрібною, тож розберімо, у чому вона насправді.
Обидві карти мають бути однакового розміру й однакової кількості каналів. Результат — карта тієї самої форми, у якій на кожній позиції кожного каналу стоїть сума двох чисел.
Скільки каналів було, стільки й лишилось. Але два джерела тепер злиті: із суми 0.7 не дізнатись, чи це 0.5 + 0.2, чи 0.2 + 0.5.
Карти складають у один стос уздовж осі каналів. Кількість каналів додається; жодне число не змінюється.
Наступна згортка бачить обидва джерела окремо й може дати їм різні ваги — наприклад, узяти форму зі скіпа, а клас із того, що знизу.
Блок декодера після конкатенації має вдвічі більше вхідних каналів, отже вдвічі більше ваг у першій згортці. У нашій мережі глибини 3 це 68 510 параметрів проти 61 706 — на 11.0 % більше.
Що з цього виходить на практиці? Ми навчили обидва варіанти в однакових умовах, по три зерна.
| спосіб | параметрів | mIoU | mIoU на межі | час навчання |
|---|---|---|---|---|
| конкатенація | 68 510 | 0.9986 ±0.001 | 0.9956 | 10.7 с |
| додавання | 61 706 | 0.9973 ±0.001 | 0.9918 | 9.8 с |
| без скіпа | 61 706 | 0.8869 ±0.013 | 0.6742 | 9.2 с |
Результат несподіваний і вартий того, щоб його назвати прямо: спосіб зшивання майже не важить. Конкатенація виграє 0.0012 при розкиді 0.001 — тобто рівно стільки, скільки шум. На смузі межі перевага трохи виразніша, 0.0038, але й вона мала. А от сам факт скіпа коштує 0.1117 — у сто разів більше.
Зшити, додати чи не давати нічого
Три способи зʼєднати карту знизу з картою скіпа. Схема показує, що відбувається з каналами; табло — що з цього виходить у числах.
Чому ж усі пишуть U-Net саме через конкатенацію? Три причини, і жодна з них не про якість на іграшкових даних. По-перше, додавання вимагає однакової кількості каналів; в U-Net енкодер і декодер можуть мати різну ширину, і тоді доводиться вставляти згортку 1 × 1 лише заради узгодження. По-друге, конкатенація нічого не втрачає за побудовою — вона не може бути гіршою, бо додавання є її окремим випадком (згортка може навчитись просто скласти). По-третє, на справжніх задачах із десятками каналів і складнішими сценами запас потужності зазвичай окупається. Але на своїх даних це варто перевірити, а не припустити: якщо різниці немає, додавання економить 11 % ваг.
ЯкийЯкі саме скіпи важать
У мережі глибини 3 скіпів три: з рівня 0 (карта 64 × 64), з рівня 1 (32 × 32) і з рівня 2 (16 × 16). Прибираймо їх по одному й дивімось, чого бракує найбільше.
Здорова інтуїція каже: найважливіший — найдрібніший, той, що з рівня 0. Він єдиний несе край предмета в повному розмірі, піксель у піксель. Але інтуїція — не доказ, тож поміряймо.
| що прибрали | mIoU | mIoU на межі | втрата |
|---|---|---|---|
| нічого | 0.9986 ±0.001 | 0.9956 ±0.004 | — |
| скіп рівня 0 (64×64) | 0.9597 ±0.033 | 0.8781 ±0.101 | −0.0388 |
| скіп рівня 2 (16×16) | 0.9979 ±0.001 | 0.9935 ±0.004 | −0.0007 |
| усі три | 0.8869 ±0.013 | 0.6742 ±0.026 | −0.1117 |
Інтуїція підтвердилась, і з великим запасом. Прибрати найглибший скіп коштує 0.0007 — це менше за розкид, тобто його там могло б і не бути. Прибрати найдрібніший коштує 0.0388, у пʼятдесят пʼять разів більше, а на смузі межі — 0.1175 проти 0.0021.
Пояснення просте, і воно вже було в таблиці стелі. Скіп із рівня 2 несе карту 16 × 16 — а декодер і так приходить на цей рівень із карти 8 × 8, тобто різниця в роздільності всього вдвічі. Скіп із рівня 0 несе 64 × 64 проти 8 × 8 знизу — різниця у вісім разів. Чим вища роздільність скіпа, тим більше в ньому того, чого немає ніде більше.
Прибрати один скіп
Схема показує, який скіп перерізано; стовпчики — що з цього виходить. Кожен стовпчик — три навчання.
ВмістЩо несе скіп
Досі ми міряли, що буває, коли скіпа немає. Тепер подивімось усередину
навченої мережі й порівняймо дві карти, які зустрічаються в кожному блоці декодера:
ту, що прийшла збоку скіпом, і ту, що прийшла знизу після
ConvTranspose2d. Мережа для цього розбору дала mIoU
0.9995, тобто вона повністю навчена, і дивимось ми на робочі активації.
Чотири числа на кожну карту. Частка ненульових — скільки клітинок узагалі щось кажуть після ReLU. Дисперсія — наскільки карта контрастна. Кореляція з межею — наскільки середня карта активацій збігається з еталонною смугою межі; від −1 до +1. Висока частота — наскільки сильно карта міняється після згладжування 3 × 3, віднесено до величини самої карти; це міра дрібних деталей. Це відносний показник, а не відсоток: одиницю він переступати може й у таблиці нижче переступає (1.028). Читай його як «у скільки разів карта зерниста», порівнюючи рядки між собою, а не як «скільки сигналу зникло».
| карта | розмір | ненульових | дисперсія | кореляція з межею | висока частота |
|---|---|---|---|---|---|
| скіп, рівень 0 | 64×64 | 0.592 | 0.191 | +0.351 | 0.194 |
| скіп, рівень 1 | 32×32 | 0.352 | 0.322 | +0.433 | 0.146 |
| скіп, рівень 2 | 16×16 | 0.367 | 0.375 | +0.506 | 0.191 |
| знизу, на рівень 2 | 16×16 | 0.502 | 0.213 | +0.143 | 1.028 |
| знизу, на рівень 1 | 32×32 | 0.505 | 0.166 | +0.296 | 0.853 |
| знизу, на рівень 0 | 64×64 | 0.482 | 0.092 | −0.066 | 0.964 |
Порівняй два виділені рядки — це саме та пара карт, яку зшиває останній блок декодера. Скіп із рівня 0 має кореляцію з межею +0.351: він спалахує там, де в масці кордон. Карта, що прийшла знизу на той самий рівень, має −0.066 — тобто про положення межі вона не знає нічого. Дисперсія в неї теж удвічі менша (0.092 проти 0.191): після дворазового розтягування карта стала гладкою й невиразною.
ConvTranspose2d: із кроком 2 і ядром 2 кожен піксель карти
розписується у власний квадратик 2 × 2 виходу, і всі чотири позиції в ньому
множаться на різні ваги ядра. Виходить регулярний візерунок із періодом 2 —
дрібний, але з межею предмета жодним чином не повʼязаний. Кореляція це й ловить.
Одного числа для висновку замало; дивись на два.
⚠️ І не сплутай це з артефактом шахівниці з теми 29. Там візерунок виникав від нерівного покриття, коли
kernel_size не ділиться
на stride; ядро 2 при кроці 2 ділиться, і покриття в нього якраз рівне —
кожна вихідна клітинка дістає рівно один внесок. Причина візерунка тут інша: не
скільки разів клітинку накрито, а якою вагою. Цю мережа при бажанні здатна
вирівняти навчанням, нерівне покриття — ні.Два числа впорядковують ті самі карти навпаки
Шість карт із таблиці вище, двічі впорядковані: ліворуч — за тим,
наскільки карта знає, де межа, праворуч — за тим, наскільки вона зерниста.
Бірюзові — карти зі скіпів, рожеві — те, що приходить знизу після
ConvTranspose2d.
І ще одна закономірність у стовпці кореляції: у скіпів вона росте з
глибиною (0.351 → 0.433 → 0.506). Це не суперечить розділу 7. Глибша карта
корелює з межею сильніше, бо в неї грубіша сітка: широка смуга в 16 × 16 накриває
край упевненіше, ніж тонка лінія в 64 × 64. Але накриває вона його
приблизно — з точністю до чотирьох пікселів. Для середнього mIoU
цього досить, для точної межі — ні. Тому найкорисніший скіп усе одно найдрібніший.
МежаМежа — там, де все вирішується
Усі числа вище ми наводили парами: mIoU по всіх пікселях і
mIoU на смузі межі. Час пояснити, чому друге число завжди більше
за перше й навіщо його взагалі рахувати.
Смуга межі — це пікселі, в околі яких зустрічаються різні класи. Ми рахуємо її самі, у три рядки: беремо максимум і мінімум номера класу у квадратному околі 5 × 5 і залишаємо ті пікселі, де вони різні.
Мінімум околу тут дістається тим самим пулінгом: мінімум набору чисел дорівнює мінус максимуму їхніх протилежних значень. Така смуга накриває 12.05 % полотна — приблизно восьму частину.
Решта — сім восьмих, 87.95 % — це нутрощі предметів і чистий фон. Там не помиляється ніхто: навіть груба мережа без скіпів упевнено каже «це фон» посеред порожнього кута й «це предмет» посеред кола. Ці пікселі й розчиняють помилку: коли середнє береться по всьому полотну, сім восьмих легких пікселів тягнуть його вгору.
| глибина | розрив за загальним mIoU | розрив на смузі межі | у скільки разів більший |
|---|---|---|---|
| 1 рівень | +0.0191 | +0.0579 | 3.04 × |
| 2 рівні | +0.0523 | +0.1576 | 3.02 × |
| 3 рівні | +0.1117 | +0.3215 | 2.88 × |
| 4 рівні | +0.2535 | +0.5511 | 2.17 × |
На смузі межі розрив більший у два-три рази: 3.04, 3.02, 2.88 і 2.17. Це не інша задача й не інша модель — це ті самі мережі, поміряні на тих самих сценах, просто без розчинення. Зверни увагу, що множник не сталий: на трьох перших глибинах він тримається біля трьох, а на четвертій падає до 2.17. Найпростіше прочитання — на глибині 4 мережа без скіпів помиляється вже не тільки на межі, тож «легкі» пікселі перестають бути легкими й розчиняють помилку слабше. Але перевірити це можна лише окремим заміром по зонах, якого ми не робили, тож лишаємо як здогад: надійне тут одне — міряти на межі варто завжди, і що краща мережа, то більше це важить.
Та сама пара мереж, три різні метрики
Перемикач міняє лише метрику. Моделі й дані ті самі: зліва направо — чотири глибини стискання.
Практичний висновок ширший за цю тему. Коли метрика усереднюється по великій однорідній масі, вона вимірює масу, а не задачу. Якщо тебе цікавить край — міряй край. Смуга межі коштує три рядки коду, а рятує від висновку «різниці майже немає» там, де різниця вдвічі-втричі більша.
ТонкеДрібні структури
U-Net народилась не в задачі «знайти кота на фото». Вона народилась у біомедичних знімках, де корисні структури тонкі: мембрана клітини, стінка судини, контур зрізу. Для таких структур усе, про що ми говорили, множиться на десять — бо в них немає нутрощів, вони самі суцільна межа.
Наш аналог такої структури — кільце: коло з вирізаною серединою. Замінимо ним трикутник і зробимо стінку завтовшки 1, 2 або 3 пікселі. Кільця всіх трьох товщин лежать в одному наборі, тож одна навчена мережа міряється відразу на всіх трьох.
Спершу подивись, скільки місця вони займають. Кільця всіх товщин разом — це 1.30 % пікселів; окремо стінка в 1 піксель — 0.30 %. Для порівняння, суцільні фігури займали 10.07 % полотна — тобто корисного сигналу тут майже увосьмеро менше, а фону навколо стільки ж.
| товщина стінки | частка пікселів | IoU зі скіпами | IoU без скіпів | розрив |
|---|---|---|---|---|
| 1 піксель | 0.30 % | 0.7052 ±0.002 | 0.1775 ±0.009 | +0.5277 |
| 2 пікселі | 0.47 % | 0.8656 ±0.001 | 0.3439 ±0.024 | +0.5217 |
| 3 пікселі | 0.54 % | 0.8385 ±0.001 | 0.4599 ±0.022 | +0.3786 |
Порівняй ці розриви з розділом 4. На суцільних фігурах тієї самої глибини розрив був 0.1117. На кільці зі стінкою в 2 пікселі він 0.5217 — майже впʼятеро більший. Мережа без скіпів на найтоншому кільці дає 0.1775: вона його практично не бачить.
Арифметика цього провалу проста, і її можна порахувати на пальцях. Мережа глибини 3 стискає полотно у вісім разів: одна клітинка карти дна відповідає квадрату 8 × 8 вхідних пікселів, тобто 64 пікселям. Скільки з них належить стінці завтовшки 2 пікселі? Смуга завширшки 2 через квадрат 8 × 8 — це близько 16 пікселів, чверть площі. Клітинка, у якій чверть — предмет і три чверті — фон, після взяття переважного класу стає фоном. Кільце зникає ще до того, як декодер узагалі почав працювати.
Кільце: товщина стінки вирішує
Повзунок міняє товщину стінки. Ліворуч — як це виглядає на полотні 64 × 64, праворуч — IoU кільця цієї товщини у двох мереж глибини 3.
Тепер про втрату. Тема 29
міряла втрати на суцільних фігурах; на тонкій структурі картина інша, бо
крос-ентропія дивиться на кожен піксель окремо й легко змиряється з тим, щоб
загубити 0.3 % полотна. Dice так не вміє: він рахує перекриття
цілої фігури, тож утрата тонкої структури бʼє по ньому одразу.
| глибина | втрата | IoU предмета | стінка 1 px | стінка 3 px |
|---|---|---|---|---|
| 2 рівні | крос-ентропія | 0.9929 ±0.004 | 0.6536 | 0.8326 |
| 2 рівні | + Dice | 0.9973 ±0.002 | 0.6887 | 0.8375 |
| 3 рівні | крос-ентропія | 0.9973 ±0.001 | 0.6891 | 0.8365 |
| 3 рівні | + Dice | 0.9993 ±0.000 | 0.7052 | 0.8385 |
Ефект є, але скромний, і його варто назвати чесно. Додавання Dice
дає +0.0351 на найтоншій стінці при глибині 2 і +0.0161 при глибині
3. На товстій стінці (3 пікселі) виграш падає до 0.005-0.002, тобто зникає в
розкиді. Тобто Dice допомагає рівно там, де структура найтонша, — і
тим менше, чим вона товща. Це логічно: чим більше в предмета нутрощів, тим менше
крос-ентропія має шансів його проґавити.
І окремо помітно, що глибина 3 краща за глибину 2 на кільці (0.7052 проти 0.6887 на найтоншій стінці). Це вже не про скіпи: глибша мережа має ширше поле зору й краще розуміє, що перед нею кільце, а не дві дуги. Тобто стискання — не тільки шкода. Воно потрібне; шкода лише в тому, щоб не повернути втрачене.
ОригіналДеталі оригіналу
Стаття 2015 року описувала мережу з двома особливостями, які майже ніхто вже не повторює. Перевірмо обидві — раптом їх викинули даремно.
Симетрія енкодера й декодера
В оригіналі декодер дзеркальний енкодеру: скільки каналів на спуску, стільки й на підйомі. Це виглядає красиво, але коштує: більша частина ваг мережі сидить саме в декодері, бо його блоки отримують подвоєні входи після конкатенації. Зробімо декодер удвічі тоншим.
| декодер | параметрів | mIoU | mIoU на межі | час |
|---|---|---|---|---|
| симетричний | 68 510 | 0.9986 ±0.001 | 0.9956 ±0.004 | 10.7 с |
| удвічі тонший | 51 578 | 0.9968 ±0.002 | 0.9901 ±0.007 | 8.8 с |
Параметрів менше на 24.7 %, а mIoU змінився на
−0.0018 при розкиді 0.0023. Різниця, менша за розкид, різницею не є:
симетрія не обовʼязкова. Це не дрібниця — на справжніх задачах чверть ваг
означає чверть памʼяті й помітно швидший прохід. Сучасні реалізації U-Net так і
роблять: тонкий декодер, товстий енкодер.
Дзеркальне доповнення на краях
Друга особливість тонша. Оригінальна U-Net працює без доповнення взагалі: кожна згортка 3 × 3 зʼїдає по пікселю з кожного боку, карта меншає, і вихідна маска виходить меншою за вхід (у статті — 388 × 388 із 572 × 572). Щоб дістати маску аж до краю зображення, автори доповнювали вхід дзеркально: відбивали смугу пікселів назовні, як у дзеркалі.
Сучасні реалізації беруть padding='same' із нулями — простіше й
маска одразу потрібного розміру. Але нуль на краю означає «тут чорне», а це
неправда: там просто нічого не видно. Порівняймо, поглянувши окремо на смугу
завширшки 3 пікселі вздовж краю зображення — вона накриває 17.87 % полотна.
| доповнення | mIoU | mIoU на межі | точність на краю зображення |
|---|---|---|---|
нулі (same) | 0.9986 ±0.001 | 0.9956 | 0.9999 ±0.0001 |
| дзеркальне | 0.9990 ±0.001 | 0.9968 | 0.9996 ±0.0001 |
Щоб зробити цей замір чесно, потрібні дані, де предмети зрізані краєм — такі й бувають на справжніх знімках, коли клітина не вміщається в кадр. Це хороше завдання: зміни генератор так, щоб фігури виходили за межі полотна, і переміряй. Ми навмисно лишаємо це відкритим, а не робимо вигляд, що відповідь отримано.
Що ж лишилось від оригіналу в сучасних U-Net? Форма U, скіпи через конкатенацію й ідея навчання на шматках зображення — усе це на місці, і всі наші мережі теж училися на випадкових шматках 32 × 32, а мірялися на цілих сценах 64 × 64. Пішли: відсутність доповнення (незручно), сувора симетрія (дорого) і зважена втрата з розділенням дотичних клітин — задачу «два предмети поруч» тепер розвʼязують інакше, і про це тема 31.
ДаліДе U-Net сьогодні
Стаття про U-Net вийшла 2015 року й описувала сегментацію клітин на знімках електронного мікроскопа. Архітектура пережила свою задачу з великим запасом, і сьогодні її зустрічають далеко за межами сегментації. Коротко, без розгортання — кожен із цих напрямів заслуговує на власну тему.
- Медичні знімки — рідна ділянка. Судини, пухлини, зрізи томографа: структури тонкі, розмітки мало, і скіпи там дають найбільше.
- Дифузійні моделі. Мережа, яка на кожному кроці прибирає трохи шуму із зображення, майже завжди має форму U: вхід і вихід однакового розміру, посередині стискання, збоку скіпи. Про це — тема 39 у блоці 8.
- Реставрація й прибирання шуму. Вхід — зіпсоване зображення, вихід — чисте того самого розміру. Задача формою збігається із сегментацією, тільки замість класів на виході яскравості.
- Суперроздільність. Те саме, але вихід більший за вхід; скіпи переносять дрібні деталі, які не можна вигадати з нуля.
- Голови сегментації в детекторах. Тема 31 покаже, що маска окремого предмета теж рахується маленькою мережею такої самої форми.
Спільне в усіх випадках одне: вихід має розмір входу, і в ньому важливі дрібні деталі. Щойно задача виглядає так — форма U напрошується сама.
ПідсумокЩо з цього забрати
Коротко, по пунктах.
- Скіп — це третій спосіб повернути роздільність. Не «не стискати» і не «розтягнути назад», а «взяти деталі там, де вони ще цілі».
- Скіпи потрібні тоді, коли є що втрачати. Порогова глибина — вимірювана величина, і на своїх даних її треба міряти, а не вгадувати.
- Скіпи зшивають, а не додають. Конкатенація лишає обидва сигнали окремими; додавання з теми 14 їх змішує.
- Середня метрика приховує ефект. Міряй окремо на смузі межі — там живе вся різниця.
- Скіпи роблять навчання передбачуванішим. Це окремий виграш, який видно тільки при кількох зернах.
І тепер про те, чого ми не вміємо. Наша мережа фарбує кожен піксель
класом. Постав поруч два кола, які торкаються, — і на виході буде одна суцільна
пляма класу «коло». Пікселі всі до одного правильні, mIoU чудовий,
а на питання «скільки тут кіл?» відповіді немає. Семантична сегментація за
означенням не рахує предмети: вона не має поняття «окремий екземпляр».
Детектор із блоку 5 це вміє — він видає рамку на кожен предмет, — але рамка не каже, які саме пікселі предметові належать. Виходить, у нас є дві половини відповіді, і жодна з них не повна. Тема 31 зшиває їх докупи: маска для кожного предмета окремо.