Блок закінчується не новою архітектурою. Тема 27 прибрала з детектора останню рукотворну деталь, і на цьому історія конструкцій вичерпалась: далі йдуть варіації. Тепер уяви, що тобі треба зробити детектор для реальної задачі — порахувати ящики на складі, знайти дефекти на платі, помітити людей на камері. Ти обираєш архітектуру за пів години, а потім три місяці займаєшся чимось геть іншим. Ця тема про ті три місяці. І головне її число таке: помилка в розмітці коштувала нам 0.1749 mAP, а найкращий архітектурний винахід усього блоку — 0.1061. Обидва числа зміряні на одній задачі, на одному й тому самому детекторі.
ПостановкаПроєкт, а не модель
У попередніх пʼяти темах задача була вже поставлена: є сцени 64×64, у них кола, квадрати й трикутники, рамки рахуються з масок. Це зручно для навчання й безчесно щодо реальності. У реальній задачі рамок немає ніде. Їх треба спершу придумати, потім намалювати, і обидва кроки коштують дорожче за всю решту.
Тема 02 вже називала ціну другого кроку: близько 15 секунд на одну рамку при уважній роботі. Десять тисяч зображень по три предмети — це 125 годин чистого часу розмітника, тобто місяць роботи однієї людини. Але дорожчий не цей крок, а перший, бо помилки в ньому не видно.
Перше рішення — що вважати предметом. Питання звучить безглуздо, поки не візьмеш конкретну задачу. Рахуємо ящики на складі: ящик, який видно на чверть із-за іншого ящика, — це предмет? А намальований ящик на плакаті? А ящик у дзеркалі? А відкритий ящик без кришки — це той самий клас чи інший? Кожна відповідь має бути записана до того, як перша людина почне розмічати. Інакше відповідей буде стільки, скільки розмітників.
Друге рішення — що робити з частково видимими. Тут теж немає правильної відповіді, є вибір із наслідками. Розмічаєш усе, що видно хоч трохи, — детектор навчиться реагувати на маленькі шматки й даватиме багато хибних спрацювань. Розмічаєш лише те, що видно повністю, — детектор мовчатиме на половині реальних кадрів, бо в житті предмети постійно перекриваються.
Третє — що робити з групами. Двадцять яблук у ящику: двадцять рамок чи одна? Тема 25 показувала, що сітка 7×7 при двадцяти предметах у кадрі втрачає 98.9 % сцен через конфлікт клітинок — тобто відповідь «двадцять рамок» дорого коштує самій моделі, а не лише розмітникові.
Ці три питання не про машинне навчання. Вони про домовленість між тобою, замовником і розмітниками. І кожне з них міняє те, що модель узагалі вважатиме правдою.
ПравилаРозмітка: правила важливіші за виконавців
Типова помилка — думати, що якість розмітки залежить від сумлінності розмітників. Насправді вона залежить від того, чи є в них однозначна інструкція. Двоє однаково сумлінних людей без інструкції розмітять один кадр по-різному, і різниця буде більшою, ніж різниця між двома архітектурами.
Подивись на одну картинку й покрути правила.
Та сама картинка, різні правила — різна істина
Три складні випадки в одній сцені: два предмети, з яких один перекрито; предмет, що наполовину вийшов за кадр; купка дрібних предметів. Перемикачі задають правила розмітки. Праворуч — скільки рамок вийде в еталонній розмітці.
Мінімальна інструкція для детекції — це пʼять відповідей, і всі вони мають бути однозначними до початку роботи.
Перевірка інструкції теж проста й коштує пів дня: дай двом людям розмітити ті самі
50 зображень і порахуй, у скількох рамках вони збіглися за IoU вище 0.7.
Ця частка — стеля твоєї моделі. Модель не може бути точнішою за розмітку, на
якій її вчили: у темі 23 ми бачили, що
рамка зі стороною 40 пікселів утримує IoU 0.9 лише при зсуві до
2.1 пікселя — тобто розбіжність у два пікселі між двома розмітниками вже
зʼїдає весь запас між mAP@0.5 і mAP@0.5:0.95.
ЦінаСкільки коштує помилка розмітки
Досі це були міркування. Тепер замір, і це головний замір теми.
Беремо наш звичний набір — 240 навчальних сцен, 501 істинна рамка — і псуємо тільки навчальну розмітку. Перевірна лишається ідеальною: ми хочемо знати, як зіпсована розмітка впливає на модель, а не як зіпсована метрика впливає на число. Три способи псування, кожен відповідає реальній помилці людини:
- зсув рамок на 2 і 4 пікселі у випадковому напрямку — рамку вели поспіхом;
- пропущені рамки (5, 15 і 30 %) — предмет на картинці є, підпису немає;
- неправильний клас (15 і 30 %) — рамка правильна, підпис ні.
Кожна настройка навчається три рази з різними зернами. Це не формальність:
на чистій розмітці три зерна дали mAP 0.8427, 0.8445 і 0.8749, тобто
розкид 0.0321 без жодної зміни в даних. (Відняти надруковані краї й дістати
0.0322 — правильно: усі різниці тут пораховані до округлення до чотирьох знаків, тому
подекуди розходяться з надрукованим на одиницю в останньому знаку.) Це наша одиниця
виміру. Різниця, менша за 0.0321, нічого не доводить — про це докладно
тема 18.
| що зіпсували | mAP@0.5 | втрата | у розкидах |
|---|---|---|---|
| нічого | 0.8540 | — | — |
| зсув 2 px | 0.8294 | −0.0246 | 0.8× |
| зсув 4 px | 0.6791 | −0.1749 | 5.4× |
| пропуск 5 % | 0.8441 | −0.0099 | 0.3× |
| пропуск 15 % | 0.8314 | −0.0227 | 0.7× |
| пропуск 30 % | 0.8076 | −0.0464 | 1.4× |
| клас 15 % | 0.8364 | −0.0176 | 0.5× |
| клас 30 % | 0.7445 | −0.1095 | 3.4× |
Два числа тут головні, і обидва — у виділених рядках.
Зсув на 4 пікселі коштує 0.1749. Чотири пікселі — це менше за товщину
пальця на екрані. Наші фігури мають рамку близько 17 пікселів завширшки, тож зсунута
рамка перекривається з істинною на IoU 0.6111 — вона все ще
«приблизно там», але вже не там. Для порівняння, при зсуві на 2 пікселі
IoU дорівнює 0.7841, і втрата всемеро менша.
Неправильний клас у 30 % рамок коштує 0.1095. Цікаво, що при 15 % втрата лише 0.0176 — утричі менша, ніж вийшло б за простою пропорцією. Мережа певною мірою терпить рідкісний шум у мітках — доти, доки правильних більше. Але після якоїсь межі терпіння закінчується різко.
Найбільший виграш від зміни архітектури в усьому блоці 5 — focal loss проти звичайної крос-ентропії, +0.1061 (тема 26). Другий за величиною — anchor-free голова замість якірної, +0.0577. Зсув рамок на чотири пікселі коштує 0.1749, тобто більше за обидва разом. Один недбалий розмітник зʼїдає результат двох винаходів, на які пішли роки.
Розмітка проти архітектури
Перемикач обирає вид помилки розмітки, повзунок — її силу. Червона смуга — втрата від цієї помилки. Бірюзові — виграші від двох архітектурних винаходів блоку. Сіра — розкид від зерна, тобто межа значущості.
ПропускПропущена рамка проти відсутнього зображення
Серед трьох помилок розмітки пропущена рамка стоїть окремо, і механізм тут інший. Згадай, як улаштоване навчання детектора з теми 26: кожен якір або відповідає за якийсь предмет, або є фоном. Якщо предмет на картинці є, а рамки в файлі немає, то всі якорі на ньому оголошуються фоном. Мережу штрафують саме за те, що вона правильно побачила предмет.
Просто менша вибірка так не робить. Вона забирає приклади, але нічого не стверджує неправильно. Порівняймо це прямо: «видалили 15 % рамок» проти «видалили 15 % зображень», і те саме на 30 %. Кількість рамок, що лишилась, у цих парах близька, тож порівняння чесне.
| що видалили | mAP@0.5 | впевненість на істині | знайдено при 0.30 |
|---|---|---|---|
| нічого | 0.8540 | 0.5702 | 0.8596 |
| 15 % рамок | 0.8314 | 0.4587 | 0.8030 |
| 15 % сцен | 0.8499 | 0.5272 | 0.8394 |
| 30 % рамок | 0.8076 | 0.3649 | 0.6775 |
| 30 % сцен | 0.8068 | 0.4753 | 0.8057 |
Подивись на другий стовпчик і здивуйся разом зі мною. При 30 % mAP
однаковий: 0.8076 проти 0.8068, різниця в четвертому знаку. Якби ми дивились лише на
mAP, довелося б сказати «різниці немає» — і це була б неправда.
Різниця є, просто mAP її не бачить. Дивись на передостанній
стовпчик: середня впевненість, яку модель дає справжньому предмету, впала з 0.4753 до
0.3649. І це не гра середніх — тут виконується найсильніша умова, яку взагалі
можна перевірити на трьох прогонах: усі три зерна «видалили рамки» (0.2840,
0.4042, 0.4064) лежать нижче за всі три зерна «видалили сцени» (0.4308, 0.4910,
0.5040). Купи не перетинаються — так само, як у
темі 26 для focal loss.
В останньому стовпчику різниця виглядає велетенською: 0.6775 проти 0.8057, тобто 12.8 пункту. Але розкид усередині «видалили рамки» дорівнює 0.3198 — одне зерно з трьох просто розвалилось (0.4656 проти 0.7854 і 0.7814). Середнє тягне вниз саме воно. Тож напрямок ми показали, а ціну в пунктах повноти на 240 сценах не встановили: для цього потрібно більше зерен або більший набір.
З 501 рамки прибрали приблизно 150. Предмети на картинках лишились — зникли тільки їхні підписи.
150 разів вона бачила чітку фігуру й отримувала вказівку «тут фон». Це не відсутність сигналу, а сигнал протилежного знаку.
Знижувати впевненість скрізь, де бачить фігуру. Не «не бачити» — саме стишувати: рамка досі на місці, оцінка нижча. Це й видно в замірі впевненості, де всі три зерна впорядковані однаково.
mAP — площа під кривою точність-повнота, а крива будується
перебором усіх порогів. Якщо всі оцінки впали приблизно однаково, порядок
передбачень майже не змінився, і площа лишилась тією самою. Впаде тільки той, хто
працює з фіксованим порогом. Тобто ти, у продуктиві.
Це, до речі, найкраща ілюстрація до розділу 9 цієї теми: mAP — чесна
метрика для порівняння моделей і погана для передбачення того, що відчує користувач.
І водночас урок про самі заміри: одна метрика тут нічого не показала, а друга
показала занадто багато. Довіряти можна тій, у якої купи зерен не перетинаються.
Пропущена рамка проти відсутнього зображення
Дві криві: скільки коштує видалити частку рамок і скільки —
видалити стільки ж зображень. Перемикач міняє метрику. За mAP
криві майже збігаються, за впевненістю на істинних предметах — розходяться,
і саме там висновок витримує перевірку зернами.
mAP на 30 % різниця дорівнює 0.0008 — усередині будь-якого шуму.
За впевненістю на істинних предметах — 0.1104, і там купи зерен не перетинаються.
Крива повноти показує той самий напрямок, але з розкидом 0.3198 усередині однієї
настройки, тож за нею робити висновок не можна. Метрика вирішує, чи побачиш ти
проблему — і чи не побачиш зайвого.ОбсягСкільки даних треба
Найчастіше запитання й найгірша відповідь на нього — число. «Тисяча зображень на клас» гуляє форумами років десять і не означає нічого, бо кількість — не та величина, від якої залежить результат. Залежить від різноманіття.
Тисяча кадрів з однієї камери, знятих за одну годину при одному освітленні, — це приблизно одне зображення, повторене тисячу разів. Сто кадрів із десяти різних камер у різну погоду навчать більшого. Правило, яке справді працює, звучить так: додавай не кількість, а різновид. Нова камера, нове освітлення, новий ракурс, новий фон, нова відстань до предмета.
Перевірити, чи вистачає даних, можна без здогадів — кривою навчання. Навчи
модель на чверті даних, на половині, на трьох чвертях і на всіх, по три зерна на
кожну точку, і подивись на приріст. Якщо остання чверть даних дала приріст, менший за
розкид від зерна, — нові дані того самого типу вже нічого не додадуть. Техніку
побудови таких кривих ми розбирали в темі
11; тут вона застосовується без змін, просто по осі стоїть mAP.
Практичні орієнтири, з якими не соромно починати: сотні зображень достатньо, щоб побачити, чи задача взагалі розвʼязна; тисячі — щоб отримати робочу якість на вузькій задачі з одного джерела; десятки тисяч потрібні там, де багато класів або дуже різні умови зйомки. Але жоден із цих орієнтирів не замінює криву навчання на твоїх даних, бо між «ящики на одному складі» й «ящики взагалі» різниця в кілька порядків.
І ще одне, що добре видно з розділу 3: менше й акуратніше краще, ніж більше й
недбало. Скорочення набору на 30 % опустило mAP з 0.8540 до
0.8068, а зсув рамок на чотири пікселі — аж до 0.6791. Якщо вибір стоїть між «розмітити вдвічі більше сяк-так» і
«розмітити стільки ж уважно», числа однозначно за друге.
АугментаціяАугментація з рамками
Аугментацію ми проходили в темі 10, але там задачею була класифікація, і мітка при перетворенні не мінялась: перевернув картинку — це все ще кіт. У детекції мітка геометрична, і її треба перетворювати разом із зображенням. Помилитись тут легко, а помітити помилку майже неможливо: код не падає, картинки виглядають нормально, модель просто гірша.
Тому кожне перетворення пишеться парою «зображення + рамки» і звіряється з маскою. Ідея звірки проста. У синтетичних даних ми знаємо маску фігури; отже, можна перетворити саму маску тим самим перетворенням і порахувати рамку з неї заново. Якщо формула правильна, два числа збігаються точно. Для горизонтального дзеркала формула така:
Тут W — ширина зображення, а x₁, y₁, x₂, y₂ — ліва,
верхня, права й нижня координати рамки. Зверни увагу, що x₁ і
x₂ міняються місцями: після дзеркала лівий край стає правим. Це і є
та помилка, яку роблять найчастіше — переставити координати забувають, і рамка стає
«вивернутою», з відʼємною шириною. Тому формулу перевіряють assert-ом
проти рамки, порахованої з дзеркальної маски, — і так само для зсуву й масштабу.
Рамка їде разом із предметом — або не їде
Ліворуч оригінал, праворуч перетворена сцена. Перемикач обирає перетворення, другий — чи перетворили рамки. Пунктир показує, де рамка мала б бути насправді.
Найпідступніше тут те, що варіант із забутими рамками усе одно кращий за відсутність аугментації: 0.6580 проти 0.3589. Метрика виросла, ти зрадів і пішов далі. Помилка, яка робить гірше, знаходиться за годину; помилка, яка робить краще, ніж було, живе в проєкті роками.
Що безпечно, а що ні
Перетворення діляться на три купи, і критерій простий: чи буває таке в реальних даних.
| перетворення | коли безпечно |
|---|---|
| Горизонтальне дзеркало | майже завжди: у світі немає «правильного» боку. Виняток — текст, дорожні знаки, цифри |
| Зсув і обрізання | завжди, але потребує рішення про рамки на межі — див. нижче |
| Масштаб | завжди; найкорисніше, бо предмети в житті бувають на різній відстані |
| Яскравість і контраст | завжди, якщо клас не визначається кольором |
| Поворот на малий кут | обережно: рамка після повороту перестає бути тісною, бо вона завжди по осях |
| Вертикальне дзеркало | рідко: у більшості задач є низ і верх |
Останній рядок вартий окремого слова, бо його регулярно вмикають «за компанію» з горизонтальним. У нашому наборі є трикутник, і він завжди стоїть вістрям угору. Перевернувши сцену вертикально, ми отримуємо фігуру, якої в перевірній вибірці не буває ніколи, і витрачаємо на неї третину навчального часу. У реальних задачах те саме: перевернута машина, перевернута людина, перевернутий дорожній знак — усе це або не трапляється, або означає щось інше. Правило просте: вмикай перетворення тільки тоді, коли можеш назвати кадр із реального життя, який на нього схожий.
Рамка на межі кадру
Обрізання ставить питання, у якого немає очевидної відповіді: що робити з рамкою, яка після обрізання наполовину вийшла за кадр? Є три відповіді, і всі три використовуються.
Три політики для рамки на межі
Повзунок рухає вікно обрізання, перемикач обирає політику. Ліворуч — повна сцена з вікном, праворуч — те, що потрапить у навчання.
Читай ці числа обережно. Різниця між «викинути» й «обрізати» — 0.0070, тобто вчетверо з половиною менша за розкид від зерна: ці дві політики нерозрізненні на наших даних. А от «лишити» гірше за «викинути» на 0.0321 — рівно на один розкид, тобто на самій межі значущості. Причина зрозуміла: політика «лишити» вчить регресор передбачати координати, яких на картинці не видно, і це єдина з трьох, яка вимагає від мережі неможливого.
Зверни увагу й на інше: політика «викинути» робить те саме, що пропущена рамка з розділу 4 — предмет видно, підпису немає. На наших даних вона від цього не постраждала, бо викидає лише рамки з обрізаної половини набору. Але якщо обрізати всі кадри, ця політика перетворюється на фабрику пропущених рамок, і розділ 4 пояснює, чим це закінчиться.
ПоділПоділ вибірки
Найтихіша помилка з усіх. Якщо кадри одного відео потрапили і в навчання, і в перевірку, модель на перевірці впізнає майже ті самі картинки, які бачила під час навчання. Метрика виходить завищеною, і ти дізнаєшся про це вже на реальних даних — тобто найдорожчим можливим способом.
Змоделюймо це чесно. Робимо 60 серій по 4 схожі кадри: та сама компоновка предметів, центри дрижать на ±1 піксель, шум щоразу новий. Це модель кадрів з одного відео, знятих підряд. Ділимо 240 кадрів на 180 навчальних і 60 перевірних двома способами — випадково й за серіями. При випадковому поділі 42 серії з 60 опиняються по обидва боки.
А потім міряємо кожну модель двічі: на своїй перевірці й на цілком незалежному наборі, згенерованому іншим зерном.
| поділ | своя перевірка | незалежний набір | ілюзія |
|---|---|---|---|
| випадковий | 0.8173 | 0.7279 | +0.0893 |
| за серіями | 0.7527 | 0.7237 | +0.0291 |
Дивись на другий стовпчик — він тут головний. Обидві моделі однаково добрі насправді: 0.7279 і 0.7237, різниця усемеро менша за розкид від зерна. Уся різниця першого стовпчика — 0.8173 проти 0.7527 — це не якість, а ілюзія. Випадковий поділ обіцяє 0.8173 там, де насправді 0.7279: він завищує оцінку на 0.0893, тобто майже на три розкиди.
Найнеприємніше в цій помилці — що вона не заважає. Модель із витоком навчається нормально, метрики ростуть, графіки красиві. Вона просто бреше про майбутнє.
Група — це все, що знято разом і схоже одне на одне: кадри одного відео, знімки однієї сесії, фотографії одного предмета з різних боків, зображення від одного клієнта. Ідентифікатор групи треба зберігати поруч з іменем файлу від самого початку: придумати його після того, як дані вже поділені, майже неможливо.
Той самий принцип стосується перевірної вибірки в іншому сенсі. Якщо ти вибирав пороги (розділ 8) за перевірною вибіркою, то ця вибірка вже перестала бути чесною оцінкою: ти підганяв під неї рішення. Для остаточного числа потрібен третій набір, якого не бачив ані оптимізатор, ані ти.
ПорогиПороги — це рішення, а не константи
У детектора є два пороги, і обидва зазвичай беруть із чужого коду не думаючи: поріг упевненості (нижче якої оцінки передбачення викидаємо) і поріг NMS (наскільки сильно рамки мають перекриватись, щоб вважатись дублікатами). Стандартні 0.5 і 0.5 — це не константи природи. Це два налаштування, які треба обрати під ціну помилки у твоїй задачі.
Помилки бувають двох видів, і вони коштують по-різному. Пропуск — предмет був, детектор промовчав. Хибне спрацювання — детектор показав те, чого немає. Пошук зброї в аеропорту: пропуск катастрофічний, хибне спрацювання — зайва перевірка валізи. Автоматичне блокування рахунку: хибне спрацювання бʼє по клієнту, пропуск означає ще один прохід ручної перевірки. Ті самі дві помилки, протилежні ціни.
Запишімо це формулою — вона тут проста настільки, що майже не є формулою:
FN — кількість пропусків (від false negative), FP —
кількість хибних спрацювань (false positive), c — ціна однієї такої
помилки в будь-яких одиницях: гривнях, хвилинах роботи оператора, чому завгодно.
Важливе тут не абсолютне значення, а відношення двох цін.
Далі — перебір. Беремо навчений детектор, будуємо сітку з девʼяти порогів
упевненості на шість порогів NMS, у кожній клітинці рахуємо TP,
FP і FN на 120 перевірних кадрах і шукаємо найдешевшу
клітинку.
Оптимум переїжджає разом із ціною помилки
Теплова карта: по вертикалі поріг упевненості, по горизонталі поріг NMS, колір — вартість на кадр (світліше дешевше). Перемикач міняє ціну помилки; бірюзова рамка показує оптимум.
Тепер найважливіше число цього розділу. Візьмімо пороги, оптимальні для «дорогого пропуску», і порахуймо, скільки вони коштують у світі, де дорогі хибні спрацювання: 10.533 проти 1.067, тобто в 9.9 раза дорожче. У зворотний бік трохи мʼякше, але теж боляче: 9.842 проти 3.033, у 3.2 раза.
А знамените «0.5 і 0.5» з чужого коду? Найближча до нього клітинка сітки — 0.55 і 0.50 — дає 7.025 там, де оптимум 3.033 (у 2.3 раза дорожче), і 3.425 там, де оптимум 1.067 (у 3.2 раза дорожче). Тобто замовчування програє в обох світах, і це природно: воно не було обране ні під один із них.
Перебравши 54 клітинки й обравши найкращу, ти підігнав два числа під перевірний набір. Оцінка, отримана на тому самому наборі, вже завищена — рівно з тієї самої причини, що й у розділі 7. Пороги добирай на одній частині даних, а остаточну цифру називай на іншій.
ОцінкаОцінка, зрозуміла замовникові
mAP — правильна метрика для порівняння моделей і погана для
розмови з людиною, яка не інженер. І це не питання простоти пояснення. Проблема
глибша: mAP усереднює по класах і по всіх порогах упевненості,
тобто описує модель у всіх режимах одразу, включно з тими, у яких її ніхто ніколи не
запустить. Розділ 4 показав це на живому прикладі: дві моделі з однаковим
mAP (0.8076 і 0.8068) і різною впевненістю на істинних предметах
(0.3649 і 0.4753) — тобто з різною поведінкою на будь-якому фіксованому порозі.
Замовникові потрібні числа, які описують той режим, у якому система працює. Два таких числа рахуються за пʼять рядків коду:
- частка кадрів, де знайдено всі предмети — «на скількох знімках зі ста нічого не загубилось». Це число люди розуміють без пояснень;
- середня кількість хибних спрацювань на кадр — «скільки зайвого доведеться відкидати руками».
Порахуймо їх для шести моделей із цієї теми — при одному робочому порозі 0.30.
Одна метрика — один переможець
Шість моделей із цієї теми — по одному прогону кожної (зерно 0), а не середнє з трьох, тому числа тут не збігаються з таблицею розділу 3. Перемикач міняє метрику, і порядок перебудовується. Найкраща за одним числом опиняється останньою за іншим.
mAP
(0.6231) і найнижчу повноту (0.377) — і рівно тому дає найменше хибних спрацювань
(0.33 на кадр). Вона просто мовчить. І окремо про перший рядок: на цьому одному
зерні «пропуск 15 %» стоїть вище за чисту розмітку (0.8572 проти 0.8427),
хоча в розділі 3, де середнє з трьох зерен, усе навпаки (0.8314 проти 0.8540).
Різниця 0.0145 менша за розкид від зерна 0.0321 — ось як виглядає «різниця,
менша за шум», коли дивишся на один прогін.Звідси головне правило розмови із замовником: одне число не буває чесним. Мінімальний чесний набір — пара: скільки знаходимо і скільки вигадуємо. Один показник без другого завжди можна виграти, зіпсувавши систему в потрібний бік.
І ще: обидва числа мають бути порахованими на тому порозі, який стоятиме в продуктиві. Оцінка «в середньому по всіх порогах» описує модель, якої не існує.
ПасткиТипові пастки
Шість помилок, кожна з яких коштувала комусь тижня. Усі мовчазні: код не падає, повідомлень немає.
| пастка | як виглядає й що робити |
|---|---|
| Формат координат | Рамку записують трьома способами: xyxy, xywh (кут і розмір), cxcywh (центр і розмір) — усі три розібрані в темі 23. Переплутав — IoU виходить майже нулем, а помилки немає. Ліки: torchvision.ops.box_convert і надрукувати одну рамку очима перед першим розрахунком |
| Пікселі проти часток | Одні формати зберігають координати в пікселях, інші — нормованими від 0 до 1. Рамка [0.1, 0.2, 0.3, 0.4] на зображенні 640×480 — це або крихітний квадратик у кутку, або чверть кадру |
model.eval() | Забув перемкнути режим — батчнорм рахує статистики по перевірній партії, і результат залежить від того, що лежало поруч у батчі. Механізм і ціна — у темі 11 |
| Клас фону | Одні бібліотеки віддають нульовий індекс фону й нумерують класи з одиниці, інші — ні. Зсув на одиницю дає модель, яка стабільно називає кола квадратами |
| Порядок класів | Список імен класів при навчанні береться з тек, а при виведенні — з конфігу. Достатньо, щоб хтось відсортував його інакше. Ліки: зберігати відповідність «індекс → імʼя» поруч із вагами й читати звідти |
| Рамка нульової площі | Після обрізання рамка може стати смужкою в один піксель. log(ширина) у кодуванні зсувів дає −inf, і навчання розвалюється. Ліки: викидати рамки, тонші за два пікселі |
Спільна риса всіх шести — жодну не ловить ані компілятор, ані тест «код запустився».
Ловить тільки одне: надрукувати проміжний результат і подивитись на нього очима.
Одна намальована сцена з рамками, узятими з реального завантажувача даних, знаходить
пʼять із шести цих помилок за хвилину — усі, крім model.eval(): режим
мережі в картинці з даними не видно взагалі.
ВибірЩо обирати
Тепер, коли весь блок позаду, можна відповісти на питання «яку архітектуру брати» — і зробити це числами, а не смаком.
| беремо | коли й чому |
|---|---|
| Одноетапний (RetinaNet, FCOS, YOLO) | Замовчування. Одноетапна постановка дала прискорення у 18 разів при однаковій ємності (тема 25), а focal loss закрив розрив у точності: +0.1061 над звичайною крос-ентропією, причому купи зерен не перетинаються (тема 26). Anchor-free голова додає ще +0.0577 і втричі легша |
| Двоетапний (Faster R-CNN) | Коли потрібні найточніші рамки й багато дрібних предметів, а час є. RPN дає повноту 0.997 усього на десяти кандидат-областях (тема 24) — другий етап уточнює рамки на вже відібраних місцях |
| DETR і його нащадки | Коли предмети стоять щільно і NMS стає вузьким місцем. Числа з теми 27 красномовні: щільна голова знаходить усі предмети (повнота 1.000), а NMS із порогом 0.5 зрізає її до 0.500 — половину предметів знищує фільтр, а не мережа. Ціна — повільна збіжність |
А тепер поверни це в масштаб. Найбільша різниця між архітектурами в таблиці — 0.1061. Зсув рамок на чотири пікселі коштує 0.1749. Витік через поділ вибірки завищує оцінку на 0.0893. Чужі пороги множать вартість помилок до 9.9 раза.
Отже, порядок дій у реальному проєкті зворотний до порядку тем у цьому блоці. Спершу правила розмітки, поділ за групами, аугментація з перевіреними рамками й пороги під ціну помилки. Архітектуру бери з першого рядка таблиці й не думай про неї, поки все інше не зроблено чесно.
БлокПідсумок блоку 5
Шість тем тому ми не вміли навіть сформулювати задачу. Ось що змінилось.
| тема | головне число |
|---|---|
| 23 · Постановка | Відповідь стає списком, а метрика — окремою наукою: mAP@0.5 = 0.9393 і mAP@0.5:0.95 = 0.4900 на тій самій моделі. І NMS назавжди губить один із двох справжніх предметів, що стоять поруч із IoU 0.714 |
| 24 · Двоетапні | Кандидат-області замість перебору: R-CNN потребував 176 годин на 5000 зображень, Fast R-CNN пришвидшив це у 74 рази. Якорі — заготовка, яка не підходить: 0.079 % позитивних і 28.3 % істинних рамок без жодного якоря |
| 25 · YOLO | Інша постановка, а не швидший конвеєр: 18× прискорення. Ціна — конфлікт сітки: 8.95 % втрачених предметів на звичайних сценах і 98.9 % при двадцяти предметах на сітці 7×7 |
| 26 · Focal loss | Хвороба була у втраті, а не в архітектурі. Множник (1−p)γ дає +0.1061, і всі три зерна кращі за всі три зерна крос-ентропії. Ініціалізація одного зсуву міняє втрату першого кроку з 72.190 на 2.255. Anchor-free — ще +0.0577 при втричі легшій голові |
| 27 · DETR | Детекція як передбачення множини: угорське зіставлення прибирає NMS. Повнота щільної голови 1.000 без NMS проти 0.500 з ним — доказ, що дублікати краще не породжувати, ніж фільтрувати |
| 28 · Практика | І все це важить менше, ніж розмітка: зсув рамок на 4 пікселі — −0.1749, тобто більше за будь-який архітектурний виграш блоку. А витік через поділ вибірки додає до оцінки +0.0893, яких немає |
Дуга блоку виглядає так. Спершу ми навчились питати: де саме предмет і як виміряти відповідь. Потім три теми поспіль прибирали з детектора рукотворні деталі — перебір вікон, потім якорі, потім NMS. Кожен крок замінював людське припущення на щось, що вчиться з даних.
А остання тема показала, куди ці припущення насправді переїхали. Вони не зникли — вони вийшли з моделі назовні, у правила розмітки, у поділ вибірки, у пороги, у вибір метрики. Там їх не видно в коді архітектури й не описано в жодній статті, і саме тому вони тепер вирішують більше.
ДаліМісток далі
Рамка — груба відповідь. Вона каже, де предмет, і навіть це каже приблизно: прямокутник по осях описує людину, що йде, чи автомобіль на повороті з величезним запасом порожнечі всередині. У розділі про аугментацію ми вже наткнулись на наслідок — після повороту рамка перестає бути тісною, бо вона завжди по осях.
Але є питання, на яке рамка не відповідає в принципі: які саме пікселі належать предмету, а які — фону за ним. Порахувати площу листка на знімку, відділити пухлину від здорової тканини, замінити фон на відеозвʼязку, зрозуміти, де закінчується дорога й починається тротуар — усе це потребує відповіді для кожного пікселя, а не для прямокутника.
Саме це й робить наступний блок — сегментація. Він міняє форму відповіді востаннє: замість списку прямокутників мережа видає карту, у якій кожен піксель підписаний. Усе, що ми навчились сьогодні про правила розмітки, поділ вибірки й пороги, лишається чинним — тільки розмічати стане ще дорожче, бо обвести предмет контуром довше, ніж накрити рамкою.