🩺 Класифікатор Медичних Знімків — Як CNN Читає Зображення
Спостерігайте, як згортковий фільтр сканує синтетичний медичний знімок, виділяє ознаки та видає ймовірність діагнозу — з живою ROC-кривою, що показує компроміс між чутливістю та специфічністю.
Про Класифікатор Медичних Знімків
Ця симуляція показує крок за кроком, як згорткова нейронна мережа перетворює сітку інтенсивностей пікселів на ймовірність діагнозу. Синтетичний «знімок» 24×24 генерується на основі одного з трьох пресетів — Норма (чистий шум), Раннє ураження (слабка пляма підвищеної інтенсивності) або Просунуте ураження (сильна пляма) — а фіксоване ядро 3×3 ковзає по ньому, створюючи карту ознак. Карта ознак проходить max-pooling до єдиної активації та передається через сигмоїду, щоб отримати P(ураження) — саме ту механіку прямого проходу, яку використовують реальні CNN (без навчання).
Запустіть пакет випадково згенерованих випадків, щоб побудувати матрицю помилок і ROC-криву (робочу характеристику приймача), і перетягніть поріг діагнозу, щоб побачити компроміс чутливості/специфічності, з яким доводиться рахуватися кожному реальному інструменту скринінгу.
Часті питання
Що саме робить ядро згортки в цій симуляції?
Ядро-детектор плям — це невелике зважене середнє 3×3 (ваги приблизно [[1,2,1],[2,4,2],[1,2,1]]/16, дискретний Гаусів фільтр), яке по черзі центрується на кожному пікселі. У кожній позиції воно множить 9 пікселів під собою на відповідні ваги ядра та підсумовує результат, отримуючи одне вихідне значення карти ознак. Оскільки всі ваги додатні й найбільші в центрі, це ядро сильно реагує там, де ділянка знімка рівномірно яскрава — саме така сигнатура плями ураження — водночас майже повністю гасячи ізольований однопіксельний шум.
Чому карта ознак проходить через max-pooling, а не average-pooling?
Глобальний average-pooling розмив би невелику, але інтенсивну пляму ураження по всіх 576 клітинках карти ознак, адже більша частина знімка — це фоновий шум. Глобальний max-pooling натомість запитує: «яка найсильніша активація будь-де на зображенні?» — а це правильне питання для виявлення локалізованої аномалії, яка може бути будь-де в полі зору. Це пояснює, чому реальні CNN-класифікатори для локалізованої патології часто надають перевагу max- або attention-пулінгу перед простим усередненням.
Чому пересування повзунка порогу змінює чутливість і специфічність у протилежних напрямках?
Чутливість (частка істинно позитивних) — це частка реальних випадків ураження, які модель позначає як позитивні; специфічність (частка істинно негативних) — це частка реальних нормальних випадків, які вона правильно залишає негативними. Зниження порогу змушує модель позначати більше випадків як позитивні загалом — виявляючи більше справжніх уражень (вища чутливість), але й помилково класифікуючи більше нормальних знімків як позитивні (нижча специфічність). Підвищення порогу дає зворотний ефект. Цей компроміс фундаментальний для будь-якого бінарного класифікатора з перекривними розподілами оцінок; неможливо покращити обидва показники, лише рухаючи поріг.
Що саме показує ROC-крива і що таке AUC?
ROC-крива (робоча характеристика приймача) відображає частку істинно позитивних (чутливість) відносно частки хибнопозитивних (1 − специфічність) у міру того, як поріг рішення проходить від 1 до 0. Кожна точка кривої відповідає одному можливому порогу. Випадкове вгадування прокреслює діагональну лінію; ідеальний класифікатор притискається до верхнього лівого кута. Площа під кривою (AUC) підсумовує ефективність за всіма порогами одразу — AUC 0.5 означає не краще за випадковість, 1.0 означає ідеальне розділення. Оскільки ця симуляція додає випадковий шум для кожного випадку та рандомізує амплітуду й позицію плями, крива, яку ви бачите, реалістично недосконала, а не тривіальна ступінчаста функція.
Чи це насправді навчена нейронна мережа?
Ні — і це навмисно. Використані тут ядра — це фіксовані, вручну обрані ваги, а не результат градієнтного спуску на розмічених навчальних даних. Реальна діагностична CNN навчала б свої ваги згортки (часто на десятках шарів і сотнях каналів), поширюючи назад похибку, обчислену на тисячах експертно розмічених знімків. Що ця симуляція дійсно точно відтворює — це прямий прохід: згортка → карта ознак → пулінг → сигмоїда → ймовірність, тобто той самий обчислювальний конвеєр, який навчена мережа виконує під час висновування, лише з вагами, обраними вручну, а не навченими.
Чому пресет «Норма» не є просто рівним чи нульовим?
Реальні сенсори зображення завжди мають фоновий шум, а реальна анатомія має природну текстуру навіть у здоровому стані. Моделювання «Норми» як чистого шуму навколо низької базової інтенсивності (а не порожньої сітки) змушує класифікатор відрізняти справжню структуру підвищеної інтенсивності від звичайної варіації піксель-до-пікселя — саме це є реальним викликом для класифікаторів медичних зображень, і саме тому наївний поріг яскравості на сирих пікселях працює значно гірше за детектор ознак на основі згортки.
Чому матриця помилок змінюється, навіть якщо я не запускав новий пакет?
Матриця помилок і показники чутливості/специфічності/точності перераховуються миттєво щоразу, коли ви рухаєте повзунок порогу, використовуючи ймовірність діагнозу, вже збережену для кожного випадку, запущеного досі. Лише самі ймовірності потребують запуску пакета (або одного випадку) для генерації; класифікація їх як позитивних чи негативних відносно заданого порогу — це просто порівняння, тому воно може перераховуватися наживо без повторної генерації знімків.
Чому випадки «Раннього» та «Просунутого» ураження іноді отримують різні оцінки, навіть коли пресет однаковий?
Кожен випадок наново обирає амплітуду, позицію та ширину своєї плями з випадкового розподілу навколо типових значень пресету та додає свіжий піксельний шум. Це відображає реальну біологічну й знімкову варіативність — жодні два реальні знімки однієї патології не виглядають ідентично. Це також те, що робить ROC-криву змістовною: якби кожен випадок «Раннього» ураження отримував однакову оцінку, чутливість і специфічність стрибали б дискретними кроками, а не прокреслювали плавну криву.
Фіксоване ядро 3×3 згортає синтетичний знімок 24×24, створюючи карту ознак, яка проходить max-pooling і стискається через сигмоїду в ймовірність діагнозу — з живою ROC-кривою та матрицею помилок, що будуються з кожного запущеного пакета.
3D · рушій Three.js / WebGL · ціль 60 FPS · працює повністю на клієнті, без встановлення