Материалы к презентации в трёх вариантах: краткий спич, словарь терминов к нему и полная техническая выкладка. Все числа проверяемы, источник указан рядом.
На слайд: колонки результата и требования — офлайн, контейнер, три минуты.
На слайд: 544 файла → 252 снимка → 100 исследований; одна область на исследование.
На слайд: три строки метрик с интервалами и одна оговорка про эталон.
| Вопрос | Ответ | Откуда |
|---|---|---|
| Сколько снимков? | 252 уникальных в 100 исследованиях (544 файла на диске) | склейка дублей по пикселям |
| Сколько нарушений? | 77 из 252 (30.6 %): 74 по экспертной таблице + 3 без экспертной оценки | labels/labels_images.csv |
| ROC-AUC | 0.6764 [0.6309, 0.7218], 5 seed'ов | models/compare_rules/rule_comparison.md |
| PR-AUC / F1 | 0.4759 [0.4141, 0.5377] / 0.5676 [0.5270, 0.6082] | там же |
| Почему такое правило разметки? | замер: +0.0564 ROC-AUC против варианта со служебными пометками, 5 из 5 seed'ов | там же |
| Вклад содержимого снимка | внутри областей AUC 0.85–0.93 против 0.50 у правила области | discriminator |
| Скорость | ≈15 мс на снимок на ускорителе, 20 мс на CPU | замер на 544 файлах |
| Размер модели | 42.8 МБ, 11.2 млн параметров, обучается только голова | models/dxa_model.pth |
| Тесты | 208 | ./run.sh test |
StudyInstanceUID идентифицирует исследование, SOPInstanceUID — конкретный снимок. Оба идут в выходной файл: study_uid и image_uid.
Подводный камень: имя каталога исследования в наборе не совпадает с этим тегом, а экспертная таблица ссылается на каталог. Склейка идёт по каталогу, в отчёт попадает тег.spine (поясничный отдел), hip_right и hip_left (проксимальный отдел бедра).
Область определяется по геометрии кадра, а не по метаданным: ширина кадра у позвоночника около 300 пикселей, у бедра около 280. Порог привязан к текущему оборудованию — это ограничение.разметка.xlsx: по каждому исследованию отмечены критерии — укладка, ось, артефакты для позвоночника; позиционирование и область интереса для каждого бедра; плюс итог по области и комментарий.
Значение 1 в критерии означает нарушение, хотя часть заголовков сформулирована положительно. Проверено: итог области равен логическому ИЛИ критериев (бёдра 72/72 и 78/78, позвоночник 96/99).table — только экспертная таблица (принято), union — таблица и служебные пометки, проставленные при подготовке набора.
Выбрано измерением: table дал ROC-AUC 0.6764 против 0.6199, преимущество на всех пяти seed'ах. Есть третье правило, expert: только снимки с экспертной оценкой — оно служит эталоном при оценке, а не для обучения.Success или Failure. Необработанных исключений быть не должно — любая ошибка фиксируется в строке результата.path_to_study, study_uid, image_uid, anatomical_region, quality_class, violation_type, processing_status, time_of_processing.| Показатель | Значение |
|---|---|
| Файлов DICOM на диске | 544 |
| Уникальных снимков (по пикселям) | 252 |
| Исследований | 100 |
| Снимков: позвоночник / бедро R / бедро L / неопределено | 99 / 79 / 73 / 1 |
| Нарушений по экспертной таблице | 74 (29.4 %) |
| Нарушений в обучающей разметке | 77 (30.6 %) |
| Снимков без экспертной оценки | 3 |
OverlayData, ни GraphicAnnotationSequence.Две строки заголовков, данные с третьей. Столбцы 2–4 — критерии позвоночника (укладка, ось, артефакты), 5–6 и 7–8 — позиционирование и область интереса для правого и левого бедра, 9–11 — итоги по областям, 12 — комментарий.
1 в критерии означает нарушение, хотя часть заголовков сформулирована положительно («корректная укладка»). Проверено на данных: итог области равен логическому ИЛИ критериев — для бёдер 72/72 и 78/78, для позвоночника 96/99. Три расхождения позвоночника трактуются как нарушение, что соответствует правилу «хотя бы один существенный пункт нарушен».
Заполненность: позвоночник 99 из 100 исследований, бедро R 72, бедро L 78; комментарий есть у 23 исследований.
laterality_mirrored.filename_fallback — иначе они остались бы без метки вообще.Результат: labels/labels_images.csv (и XLSX) — 252 строки, 175 качественных и 77 с нарушениями.
Правило «только таблица» против «таблица плюс служебные пометки при подготовке набора». Пометки расходились с оценкой эксперта в 15 случаях из 252, поэтому выбор делался измерением: одно фиксированное разбиение, пять seed'ов, один эталон (вердикт эксперта на снимках валидации).
| Метрика (эталон) | только таблица | со служебными пометками |
|---|---|---|
| ROC-AUC | 0.6764 [0.6309, 0.7218] | 0.6199 [0.5840, 0.6559] |
| PR-AUC | 0.4759 [0.4141, 0.5377] | 0.4046 [0.3702, 0.4391] |
| F1 | 0.5676 [0.5270, 0.6082] | 0.5426 [0.5073, 0.5778] |
| Recall / Precision | 0.700 / 0.486 | 0.863 / 0.404 |
| Парная разница (таблица − с пометками) | Δ, среднее [95 % ДИ] | Знаки по seed'ам |
|---|---|---|
| ROC-AUC | +0.0564 [+0.0403, +0.0725] | +++++ |
| PR-AUC | +0.0713 [+0.0398, +0.1028] | +++++ |
| F1 | +0.0251 [−0.0056, +0.0558] | +++-+ |
| Precision | +0.0815 [+0.0590, +0.1039] | +++++ |
./run.sh split # зафиксировать разбиение (стратификация по эталону)
./run.sh compare # 5 seed'ов × 2 варианта, отчёт models/compare_rules/rule_comparison.md
| Код | Подпись | Область | Источник |
|---|---|---|---|
positioning | Некорректная укладка | позвоночник | таблица |
axis_deviation | Отклонение оси | позвоночник | таблица |
artifact | Артефакты и импланты | любая | таблица |
rotation | Ротация, позиционирование | бедро | таблица |
roi_incorrect | Некорректная область интереса | любая | таблица |
motion | Движение, размытие | любая | методика |
incomplete_anatomy | Анатомия видна не полностью | любая | методика |
labeling_error | Ошибка разметки | позвоночник | методика |
unspecified | Нарушение без уточнения | любая | служебный |
Распределение в разметке: rotation 36, artifact 17, axis_deviation 10, roi_incorrect 7, positioning 6, unspecified 5.
src/dxa/violations.py), подписи отдаёт сервер, старые значения приводятся к канону.
Отдельный инструмент приводит имена файлов к единому виду: область, две цифры номера, при наличии — пометка качества. Приведено 344 файла из 548, карта отката сохранена, разметка и метрики при этом не менялись.
./run.sh rename # план правки, без изменений на диске
./run.sh rename --apply # выполнить; карта отката labels/rename_map.csv
./run.sh rename --rollback --apply # вернуть прежние имена
Правка сделана после того, как разметка и метрики были посчитаны, и проверено, что она на них не влияет: набор из 252 пиксельных групп идентичен до и после, разметка не изменилась ни в одной строке. Пометки качества в именах в метках не участвуют — только как диагностический столбец.
DICOM → pixel_array (RescaleSlope/Intercept, MONOCHROME1)
→ нормализация по перцентилям 0.5–99.5 → [0, 1]
→ ×255, uint8
→ повтор в 3 канала, билинейный resize 224×224
→ /255, нормировка по статистикам ImageNet
→ тензор (3, 224, 224) float32
Один и тот же путь используется при обучении и в API. Обучение и API вызывают общий код предсказания, поэтому порог и препроцессинг совпадают по построению.
| Компонент | Значение |
|---|---|
| Backbone | ResNet18, веса ImageNet, заморожен (заморозка на всё обучение) |
| Классификационная голова | линейный слой, 2 класса; обучаемых параметров — тысячи |
| Вспомогательная голова области | вес в функции потерь 0.3 |
| Вход | 224×224, 3 канала; BatchNorm в eval-режиме |
| Порог | −0.4930 по логиту (вероятность 0.379), подбор по F1 на валидации |
| Размер чекпоинта | 42.8 МБ, 11.2 млн параметров сети |
| Определение области | эвристика по ширине кадра (позвоночник ≈300 px, бедро ≈280 px) |
Фиксированное разбиение: обучение 199 снимков / 81 исследование, валидация 53 снимка / 19 исследований, 16 нарушений по эталону. Пять seed'ов.
| Метрика | Значение |
|---|---|
| ROC-AUC | 0.6764 [0.6309, 0.7218] |
| PR-AUC | 0.4759 [0.4141, 0.5377] |
| F1 | 0.5676 [0.5270, 0.6082] |
| Рабочий чекпоинт | Значение |
|---|---|
| Обучение / валидация | 199 снимков / 81 исследование — 53 снимка / 19 исследований, 16 нарушений |
| Эпоха / порог | 39 / логит −0.4930 (вероятность 0.379) |
| ROC-AUC / PR-AUC | 0.6706 / 0.4585 |
| F1 / recall / precision | 0.5600 / 0.875 / 0.412 |
| ROC-AUC по областям | позвоночник 0.943, бедро R 0.576, бедро L 0.550 |
В позвоночнике нарушений треть, у бёдер около трети, а область почти однозначно определяется шириной кадра. Отсюда вопрос: не выучила ли модель просто «область вместо качества». Проверка — сравнение с правилом «позвоночник значит нарушение».
| Предиктор | Общий AUC | spine | hip_right | hip_left |
|---|---|---|---|---|
| Модель | 0.854 | 0.928 | 0.861 | 0.853 |
| Правило «позвоночник = нарушение» | 0.529 | 0.500 | 0.500 | 0.500 |
Внутри областей правило не имеет подсказки и даёт ровно 0.5; модель — 0.85–0.93. Значит, она использует содержимое снимка. Оговорка: проверка считается на всём наборе, включая обучающие снимки, поэтому значения смещены вверх; она отвечает на вопрос «есть ли вклад содержимого», а не «каково качество на новых данных».
| Метод | Путь | Назначение |
|---|---|---|
| GET | /api/v1/health | статус и происхождение загруженной модели |
| GET | /api/v1/model | карточка решения: разметка, данные, метрики, словарь нарушений, ограничения |
| POST | /api/v1/analyze | анализ одного файла |
| POST | /api/v1/analyze/detailed | расширенный отчёт, при необходимости с маской |
| POST | /api/v1/analyze/sr | текстовое представление отчёта DICOM SR |
| POST | /api/v1/batch | пакетный анализ |
| POST | /api/v1/export | пакетный анализ и выгрузка XLSX |
Ответ анализа по одному файлу, сверх обязательных колонок: confidence, threshold_probability, region_confidence, violation_type_label, violation_type_is_heuristic, violation_type_note, reason, metrics, samples.
Ошибки не приводят к исключению: строка получает processing_status = Failure. Путь к чекпоинту задаётся переменной DXA_MODEL_PATH, чтобы контейнер не зависел от рабочего каталога.
| Показатель | Ускоритель (Apple MPS) | CPU, 8 потоков |
|---|---|---|
| Обработка одного снимка, медиана | 15 мс | 20 мс |
| Весь набор (544 файла) | 8 с | — |
| На одно исследование (до 3 снимков) | ≈0.05 с | ≈0.06 с |
| Запас к бюджету 3 минуты | >3000× | >2500× |
Основное время уходит на декодирование DICOM и препроцессинг, а не на сеть: разница между ускорителем и процессором в пределах 1.4×. Значит, ускоритель для этой задачи не является узким местом. Минимальная конфигурация — CPU; чекпоинт занимает 43 МБ, память ограничена накладными расходами среды исполнения. Образ содержит только код и фронтенд; веса монтируются при запуске.
tests/: разбор имён и склейка дублей, отсутствие утечки при разбиении, фиксация разбиения, разметка по таблице и три правила метки, единый словарь типов, приведение имён файлов с откатом, препроцессинг и метрики, контракт API для интерфейса../run.sh label | rename | split | compare | train | infer | serve | test.| Ограничение | Следствие | Что планируется |
|---|---|---|
| Разметка выведена из оценки исследования | поштучной экспертной оценки снимков нет | разметка отдельных снимков специалистом |
| Мало данных: 252 снимка, 77 нарушений | широкие интервалы, закрытый набор может дать другие цифры | 500+ исследований |
| Тип нарушения — эвристика | 5 снимков имеют только «нарушение без уточнения» | мультилейбл-модель по типам |
| Эталон — та же таблица | сравнение правил частично благоприятствует таблице | независимая экспертная оценка снимков |
| Область определяется по ширине кадра | порог привязан к текущему оборудованию | калибровка по метаданным аппарата |
| Теги латеральности пусты | сторона бедра в 7 исследованиях не проверяема | запрос тега у источника данных |
| Разметки ROI нет в DICOM | корректность областей наследуется из таблицы | проверка на данных с экспортной разметкой |
Планировалась визуальная разметка снимков локальной vision-моделью (9 млрд параметров, офлайн): это сняло бы зависимость от экспертной таблицы. На калибровке по 14 снимкам, из которых 8 заведомо с нарушениями, модель вынесла «непригоден» всем 14, включая все качественные, с шаблонными формулировками и выдуманными имплантами. Разделяющая способность — на уровне случайной.