# 🦴 DXA Quality Assessment БСрвис Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ контроля качСства дСнситомСтричСских исслСдований (DXA): ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ DICOM, опрСдСляСт Π°Π½Π°Ρ‚ΠΎΠΌΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ, ΠΎΡ†Π΅Π½ΠΈΠ²Π°Π΅Ρ‚, ΠΏΡ€ΠΈΠ³ΠΎΠ΄Π½ΠΎ Π»ΠΈ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ для клиничСской ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΠΈ, ΠΈ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ структурированный ΠΎΡ‚Ρ‡Ρ‘Ρ‚.
Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π² Π²Π΅Π±-интСрфСйсС: полоса состояния, статистика ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†Π° снимков
## Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ | Π¨Π°Π³ | РСализация | |---|---| | ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ анатомичСской области | Π¨ΠΈΡ€ΠΈΠ½Π° ΠΊΠ°Π΄Ρ€Π° (ΠΏΠΎΠ·Π²ΠΎΠ½ΠΎΡ‡Π½ΠΈΠΊ / Π±Π΅Π΄Ρ€ΠΎ) + Π³ΠΎΠ»ΠΎΠ²Π° области + гСомСтрия яркой Π·ΠΎΠ½Ρ‹ | | Бинарная ΠΎΡ†Π΅Π½ΠΊΠ° качСства | ResNet18 (ImageNet) β†’ линСйная Π³ΠΎΠ»ΠΎΠ²Π°; ΠΏΠΎΡ€ΠΎΠ³ ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Π½ ΠΏΠΎ F1 Π½Π° Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ | | Π’ΠΈΠΏ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ | ΠžΠ±Ρ‰Π°Ρ катСгория для снимков с Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ΠΌ; Π΄Π΅Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠΈ Ρ‚ΠΈΠΏΠΎΠ² Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ снимка | | ΠžΡ‚Ρ‡Ρ‘Ρ‚ | XLSX/CSV со столбцами ΠΈΠ· Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ; ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ zip с Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ Π·ΠΎΠ½Ρ‹ интСрСса | | API | FastAPI: Π°Π½Π°Π»ΠΈΠ·, Π΄Π΅Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΉ Π°Π½Π°Π»ΠΈΠ·, пакСтная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°, экспорт, DICOM SR (тСкст) | | Π’Π΅Π±-интСрфСйс | Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° DICOM, Ρ‚Π°Π±Π»ΠΈΡ†Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ², панСль Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ с Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ, панСль «О ΠΌΠΎΠ΄Π΅Π»ΠΈΒ» | ## Установка ΠΈ запуск ```bash python3 -m venv venv && source venv/bin/activate pip install -r requirements.txt ./run.sh label # Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ датасСт ΠΏΠΎ Excel ./run.sh rename # ΠΏΠ»Π°Π½ привСдСния ΠΈΠΌΡ‘Π½ Ρ„Π°ΠΉΠ»ΠΎΠ² ./run.sh train # ΠΎΠ±ΡƒΡ‡ΠΈΡ‚ΡŒ модСль качСства ./run.sh infer "dataset_hack/Для тСста" results.xlsx # пакСтная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ./run.sh serve # API ΠΈ Π²Π΅Π±-интСрфСйс Π½Π° :8000 ./run.sh split && ./run.sh compare # ΡΡ€Π°Π²Π½ΠΈΡ‚ΡŒ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠΈ ./run.sh test # тСсты ``` Для инфСрСнса Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° CPU (ΠΎΠ±Ρ€Π°Π· мСньшС, Π±Π΅Π· CUDA-колёс): ```bash pip install -r requirements.txt --extra-index-url https://download.pytorch.org/whl/cpu ``` ΠžΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΈ инфСрСнс ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ: ```bash python -m src.dxa.train --epochs 100 --output-dir models python -m src.dxa.inference --input-path dataset_hack --output-path results.xlsx --zip-out masks.zip ``` ПослС запуска сСрвСра: - Π’Π΅Π±-интСрфСйс: http://localhost:8000 - Swagger UI: http://localhost:8000/docs ## Docker ```bash docker build -t dxa-quality . docker run -v /path/to/data:/data -v /path/to/models:/app/models -p 8000:8000 dxa-quality ``` Π§Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚ Π² ΠΎΠ±Ρ€Π°Π· Π½Π΅ копируСтся: ΠΎΠ½ монтируСтся Π² `/app/models`, ΠΏΡƒΡ‚ΡŒ задаётся ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ `DXA_MODEL_PATH` (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ `/app/models/dxa_model.pth`). Π‘Π΅Π· Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚Π° сСрвис всё Ρ€Π°Π²Π½ΠΎ поднимаСтся β€” `/api/v1/health` сообщаСт `model_loaded: false`, Π° Π°Π½Π°Π»ΠΈΠ· ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ ошибкой `Model not loaded` вмСсто Ρ‚ΠΈΡ…ΠΎΠΉ Π½Π΅Π²Π΅Ρ€Π½ΠΎΠΉ ΠΎΡ†Π΅Π½ΠΊΠΈ. Из сСти Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ скачиваСтся. Π‘Π±ΠΎΡ€ΠΊΠ° провСряСт, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ импортируСтся ΠΈ Ρ‡Ρ‚ΠΎ ΠΎΡ„Π»Π°ΠΉΠ½-ассСты Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄Π° Π½Π° мСстС. --- ## АрхитСктура
Пайплайн ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ DXA: Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° DICOM, Ρ€Π°Π·Π±ΠΎΡ€ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΡ€Π΅Π΄ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°, инфСрСнс, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ области, ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ качСства, ΠΎΡ‚Ρ‡Ρ‘Ρ‚
Π‘Ρ…Π΅ΠΌΠ° Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΏΡƒΡ‚ΠΈ Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Ρ… Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ: ``` DICOM ──▢ ΠΏΡ€Π΅Π΄ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ──▢ ResNet18 (Π·Π°ΠΌΠΎΡ€ΠΎΠΆΠ΅Π½) ──▢ линСйная Π³ΠΎΠ»ΠΎΠ²Π° ──▢ Π»ΠΎΠ³ΠΈΡ‚ β”‚ β”‚ β”‚ └──▢ Π³ΠΎΠ»ΠΎΠ²Π° области (Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Π°Ρ) β”‚ β”œβ”€β”€β–Ά гСомСтрия яркой Π·ΠΎΠ½Ρ‹: ΠΎΠ±Π»Π°ΡΡ‚ΡŒ, ROI, гСомСтрия ΠΊΠ°Π΄Ρ€Π° └──▢ эвристики: Ρ€Π΅Π·ΠΊΠΎΡΡ‚ΡŒ, Β«ΠΏΠ»ΠΎΡ‚Π½Ρ‹Π΅Β» Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ``` ΠšΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΈ ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΎΠ½ΠΈ Ρ‚Π°ΠΊΠΈΠ΅: 1. **Π›ΠΈΠ½Π΅ΠΉΠ½Ρ‹ΠΉ Π·ΠΎΠ½Π΄ вмСсто ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ fine-tune.** Π£Π½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… снимков Π² Π½Π°Π±ΠΎΡ€Π΅ ~250. ΠŸΠΎΠ»Π½Ρ‹ΠΉ fine-tune ResNet18 пСрСобучаСтся Π·Π° нСсколько эпох (train F1 β†’ 1.0 ΠΏΡ€ΠΈ val AUC β‰ˆ 0.5). Π—Π°ΠΌΠΎΡ€ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ backbone + линСйная Π³ΠΎΠ»ΠΎΠ²Π° ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ val AUC β‰ˆ 0.7–0.85. Π Π΅ΠΆΠΈΠΌ `--head mlp --freeze-epochs 0` оставлСн для экспСримСнтов Π½Π° большСм ΠΎΠ±ΡŠΡ‘ΠΌΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…. 2. **ΠœΠ΅Ρ‚ΠΊΠΈ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ снимка.** Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ β€” `labels/labels_images.csv`, построСнный ΠΈΠ· экспСртной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ `./run.sh label` (Ρ€Π°Π·Π±ΠΎΡ€ β€” Π² `assets/labeling.md`): Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΎΡ‚ΠΌΠ΅Ρ‡Π΅Π½Ρ‹ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΠΈ качСства ΠΏΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ исслСдованию, Π° каТдая ΠΎΠ±Π»Π°ΡΡ‚ΡŒ встрСчаСтся Π² Π½Ρ‘ΠΌ Ρ€ΠΎΠ²Π½ΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·, поэтому Π²Π΅Ρ€Π΄ΠΈΠΊΡ‚ пСрСносится Π½Π° снимок ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ. Π’Π°ΠΊΠΎΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠΈ β€” 77 Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ ΠΈΠ· 252 (30.6 %). ΠŸΡ€Π°Π²ΠΈΠ»ΠΎ Π²Ρ‹Π±Ρ€Π°Π½ΠΎ ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠ΅ΠΌ: ΡƒΡ‡Ρ‘Ρ‚ Ρ€ΡƒΡ‡Π½Ρ‹Ρ… ΠΏΠΎΠΌΠ΅Ρ‚ΠΎΠΊ ΠΈΠ· ΠΈΠΌΡ‘Π½ Ρ„Π°ΠΉΠ»ΠΎΠ² Π΄Π°Π» Ρ…ΡƒΠ΄ΡˆΠΈΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π½Π° held-out Π½Π°Π±ΠΎΡ€Π΅, поэтому Π² ΠΌΠ΅Ρ‚ΠΊΠ°Ρ… ΠΎΠ½ΠΈ Π½Π΅ ΡƒΡ‡Π°ΡΡ‚Π²ΡƒΡŽΡ‚. Π Π΅Π·Π΅Ρ€Π²Π½Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ `--labels-csv ""` Π±Π΅Ρ€Ρ‘Ρ‚ ΠΌΠ΅Ρ‚ΠΊΡƒ ΠΈΠ· суффикса `_good`/`_bad` ΠΈ оставлСн для совмСстимости. 3. **Π‘ΠΊΠ»Π΅ΠΉΠΊΠ° ΠΏΠΎΠ±Π°ΠΉΡ‚Π½Ρ‹Ρ… Π΄ΡƒΠ±Π»Π΅ΠΉ.** Π’ датасСтС 544 Ρ„Π°ΠΉΠ»Π°, Π½ΠΎ 252 ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… снимка: ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΊΠ°Π΄Ρ€ сохранён ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ ΠΏΠΎΠ΄ Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ (Ρ‡Π°ΡΡ‚ΡŒ β€” с ΠΌΠ΅Ρ‚ΠΊΠΎΠΉ, Ρ‡Π°ΡΡ‚ΡŒ β€” Π±Π΅Π·). Π‘Π΅Π· склСйки ΠΎΠ΄Π½ΠΎ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠΏΠ°Π΄Π°Π»ΠΎ Π±Ρ‹ Π² ΠΎΠ±Π° класса. 4. **Π Π°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ ΠΏΠΎ исслСдованиям.** Π‘Π½ΠΈΠΌΠΊΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ исслСдования Π½Π΅ ΠΏΠΎΠΏΠ°Π΄Π°ΡŽΡ‚ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π² train ΠΈ val β€” ΠΈΠ½Π°Ρ‡Π΅ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π·Π°Π²Ρ‹ΡˆΠ°ΡŽΡ‚ΡΡ Π·Π° счёт ΡƒΡ‚Π΅Ρ‡ΠΊΠΈ. 5. **АугмСнтация ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½Π°.** ΠŸΡ€ΠΎΠ²Π΅Ρ€Π΅Π½ΠΎ ΡΠΊΡΠΏΠ΅Ρ€ΠΈΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½ΠΎ: яркостный разброс ΠΈ сдвиг ΠΊΠ°Π΄Ρ€Π° ΡΠ½ΠΈΠΆΠ°ΡŽΡ‚ AUC с 0.87 Π΄ΠΎ 0.56, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ распрСдСлСниС яркости ΠΈ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ области сами ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΏΡ€ΠΈΠ·Π½Π°ΠΊΠ°ΠΌΠΈ качСства. Π€Π»Π°Π³ `--augment` Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π΅Ρ‘ для экспСримСнтов. 6. **ΠŸΠΎΡ€ΠΎΠ³ ΠΏΠΎ Π»ΠΎΠ³ΠΈΡ‚Ρƒ.** ΠŸΡ€ΠΈ Π΄ΠΎΠ»Π΅ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ ~15 % ΠΏΠΎΡ€ΠΎΠ³ 0.5 Π΄Π°Ρ‘Ρ‚ Π½ΡƒΠ»Π΅Π²ΠΎΠΉ recall. ΠŸΠΎΡ€ΠΎΠ³ подбираСтся ΠΏΠΎ F1 Π½Π° Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ ΠΈ сохраняСтся Π² Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚; Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ принимаСтся ΠΏΠΎ Π»ΠΎΠ³ΠΈΡ‚Ρƒ (числСнно устойчиво ΠΏΡ€ΠΈ насыщСнии вСроятностСй). ### Π‘Ρ…Π΅ΠΌΡ‹ систСмы | ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ | ΠŸΠΎΡ‚ΠΎΠΊ Π΄Π°Π½Π½Ρ‹Ρ… | |---|---| | Π”ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΠ° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²: Π²Π΅Π±-ΠΊΠ»ΠΈΠ΅Π½Ρ‚, FastAPI, ΠΌΠΎΠ΄Π΅Π»ΠΈ DXA, ΠΎΡ†Π΅Π½ΠΊΠ° качСства, файловая систСма | ΠŸΠΎΡ‚ΠΎΠΊ Π΄Π°Π½Π½Ρ‹Ρ…: Π²Ρ…ΠΎΠ΄, ΠΏΡ€Π΅Π΄ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°, ΠΌΠΎΠ΄Π΅Π»ΠΈ, Π°Π½Π°Π»ΠΈΠ· качСства, Π²Ρ‹Ρ…ΠΎΠ΄ | | ΠŸΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π°Π½Π°Π»ΠΈΠ·Π° | Π Π°Π·Π²Ρ‘Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅ | |---|---| | Π”ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ: запрос /analyze/detailed, ΠΏΡ€Π΅Π΄ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°, инфСрСнс, Ρ€Π΅Π³ΠΈΠΎΠ½, сСгмСнтация, ΠΎΡ‚Ρ‡Ρ‘Ρ‚ | Π”ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΠ° развёртывания: ΠΊΠ»ΠΈΠ΅Π½Ρ‚, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ML-ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½, инфраструктура | | ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ анатомичСской области | ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ сущности | |---|---| | Алгоритм опрСдСлСния области: ΠΏΠΎΡ€ΠΎΠ³ ΠΏΠΎ ΠΏΠ΅Ρ€Ρ†Π΅Π½Ρ‚ΠΈΠ»ΡŽ яркости, bounding box, ΡΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ сторон, сторона Π±Π΅Π΄Ρ€Π° | Π”ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΠ° классов: классификатор, модСль, Π΄Π΅Ρ‚Π°Π»ΡŒΠ½Π°Ρ ΠΎΡ†Π΅Π½ΠΊΠ°, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ области | Π‘Ρ…Π΅ΠΌΡ‹ взяты ΠΈΠ· ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° ΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ Ρ†Π΅Π»Π΅Π²ΡƒΡŽ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρƒ: Π±Π»ΠΎΠΊΠΈ `Orchestrator`, UNet-сСгмСнтации ΠΈ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… Π²Π΅Ρ€Π΄ΠΈΠΊΡ‚ΠΎΠ² качСства Π² Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΈ Π½Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹. Π Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ ΠΏΡƒΡ‚ΡŒ описан Π²Ρ‹ΡˆΠ΅. --- ## Π€ΠΎΡ€ΠΌΠ°Ρ‚ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ столбцы ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ трСбованиям задания: | Π‘Ρ‚ΠΎΠ»Π±Π΅Ρ† | ОписаниС | |---|---| | `path_to_study` | ΠŸΡƒΡ‚ΡŒ ΠΊ исслСдованию (для HTTP-Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ β€” `upload://<имя>`) | | `study_uid` | StudyInstanceUID | | `image_uid` | SOPInstanceUID | | `anatomical_region` | `spine` / `hip_left` / `hip_right` / `hip` | | `quality_class` | 0 β€” качСствСнноС, 1 β€” Π΅ΡΡ‚ΡŒ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ | | `violation_type` | Π’ΠΈΠΏ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ ΠΈΠ»ΠΈ пустая строка | | `processing_status` | `Success` ΠΈΠ»ΠΈ `Failure: <ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°>` | | `time_of_processing` | ВрСмя ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ, сСкунды | Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ `confidence`, `violation_reason`, `region_confidence` β€” ΠΎΠ½ΠΈ Π½Π΅ ΠΌΠ΅ΡˆΠ°ΡŽΡ‚ автоматичСскому Ρ€Π°Π·Π±ΠΎΡ€Ρƒ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… столбцов. ## API | ΠœΠ΅Ρ‚ΠΎΠ΄ | ΠŸΡƒΡ‚ΡŒ | НазначСниС | |---|---|---| | GET | `/` | Π’Π΅Π±-интСрфСйс | | 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 | ```bash curl -X POST http://localhost:8000/api/v1/analyze -F "file=@study/spine.dcm" ``` ```json { "study_uid": "1.2.643...", "image_uid": "1.2.643...", "anatomical_region": "spine", "quality_class": 1, "quality_label": "Π•ΡΡ‚ΡŒ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ качСства", "violation_type": "artifact", "violation_type_label": "АртСфакты ΠΈ ΠΈΠΌΠΏΠ»Π°Π½Ρ‚Ρ‹", "violation_type_is_heuristic": true, "violation_type_note": "Π’ΠΈΠΏ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½ эвристикой ΠΏΠΎ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠ°ΠΌ снимка, Π° Π½Π΅ модСлью...", "reason": "ΠŸΠΎΡΡ‚ΠΎΡ€ΠΎΠ½Π½ΠΈΠ΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈΠ»ΠΈ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Ρ‹ Π² Π·ΠΎΠ½Π΅ интСрСса", "confidence": 0.72, "threshold_probability": 0.5103, "processing_status": "Success" } ``` ΠšΠΎΠ΄Ρ‹ `violation_type` бСрутся ΠΈΠ· Π΅Π΄ΠΈΠ½ΠΎΠ³ΠΎ словаря `src/dxa/violations.py` (`positioning`, `axis_deviation`, `artifact`, `rotation`, `roi_incorrect`, `motion`, `incomplete_anatomy`, `labeling_error`, `unspecified`) β€” ΠΏΠ΅Ρ€Π²Ρ‹Π΅ ΠΏΡΡ‚ΡŒ ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅Ρ‚ экспСртная Ρ‚Π°Π±Π»ΠΈΡ†Π°, ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ приходят ΠΈΠ· ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΠ΅Π² пригодности. ПолС `violation_type_is_heuristic` ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½ эвристикой, Π° Π½Π΅ модСлью: модСль Ρ€Π΅ΡˆΠ°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π±ΠΈΠ½Π°Ρ€Π½ΡƒΡŽ Π·Π°Π΄Π°Ρ‡Ρƒ. Подписи для интСрфСйса ΠΎΡ‚Π΄Π°Ρ‘Ρ‚ сСрвСр, своСй ΠΊΠΎΠΏΠΈΠΈ словаря Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄ Π½Π΅ Π΄Π΅Ρ€ΠΆΠΈΡ‚. --- ## Π’Π΅Π±-интСрфСйс Полоса состояния Π² шапкС ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, **какая** модСль сСйчас Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚: имя Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚Π°, источник Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠΈ, эпоху ΠΈ ΠΏΠΎΡ€ΠΎΠ³. По интСрфСйсу сразу Π²ΠΈΠ΄Π½ΠΎ, какая вСрсия Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚, β€” Π±Π΅Π· обращСния ΠΊ Π»ΠΎΠ³Π°ΠΌ.
Полоса состояния: загруТСнная модСль, Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ°, эпоха, ΠΏΠΎΡ€ΠΎΠ³
Π‘Ρ‚Ρ€ΠΎΠΊΠΈ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΊΠ»ΠΈΠΊΠ°Π±Π΅Π»ΡŒΠ½Ρ‹, Π½ΠΎ ΠΎΠ± этом Π½Π°Π΄ΠΎ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ прямо β€” ΠΈΠ½Π°Ρ‡Π΅ Π½Π΅ Π΄ΠΎΠ³Π°Π΄Ρ‹Π²Π°ΡŽΡ‚ΡΡ. Над Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ висит подсказка «НаТмитС Π½Π° Π»ΡŽΠ±ΡƒΡŽ строку», Π² ΠΊΠΎΠ½Ρ†Π΅ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строки Π΅ΡΡ‚ΡŒ ΠΊΠ½ΠΎΠΏΠΊΠ° Β«ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒΒ», Π° ΠΊΠ»ΠΈΠΊ ΠΏΠΎ строкС ΠΏΡ€ΠΎΠΊΡ€ΡƒΡ‡ΠΈΠ²Π°Π΅Ρ‚ страницу ΠΊ ΠΏΠ°Π½Π΅Π»ΠΈ Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ. Подсказка скрываСтся, ΠΊΠΎΠ³Π΄Π° Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ Π½Π΅ оставил Π½ΠΈ ΠΎΠ΄Π½ΠΎΠΉ строки. Кнопка Β«ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒΒ» β€” настоящая ΠΊΠ½ΠΎΠΏΠΊΠ°, поэтому панСль доступна ΠΈ с ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Ρ‹ (Tab + Enter), Π° Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΡ‹ΡˆΡŒΡŽ. Π‘Π°ΠΌΠ° Ρ‚Π°Π±Π»ΠΈΡ†Π° со статистикой ΠΈ подсказкой β€” Π½Π° ΠΏΠ΅Ρ€Π²ΠΎΠΌ ΡΠΊΡ€ΠΈΠ½ΡˆΠΎΡ‚Π΅. ПанСль Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ открываСтся ΠΏΠΎ ΠΊΠ»ΠΈΠΊΡƒ Π½Π° строку: Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, измСрСния ΠΈ визуализация снимка. Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ ΠΎΠ±Π΅ Π²Π΅Ρ‚ΠΊΠΈ β€” Β«Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅Β» ΠΈ Β«Π½ΠΎΡ€ΠΌΠ°Β»:
ПанСль Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ для снимка с Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ΠΌ: красный Π±Π΅ΠΉΠ΄ΠΆ, ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ HIGH, Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ с Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈ ΠΏΠΎΡ€ΠΎΠ³ΠΎΠΌ, визуализация ПанСль Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ для качСствСнного снимка: Π·Π΅Π»Ρ‘Π½Ρ‹ΠΉ Π±Π΅ΠΉΠ΄ΠΆ, справочныС измСрСния
ΠΠ°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅. Π‘Π΅ΠΉΠ΄ΠΆ Β«ΠΠ°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅Β», ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ HIGH, Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ с Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈ ΠΏΠΎΡ€ΠΎΠ³ΠΎΠΌ, Ρ‚ΠΈΠΏ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ с ΠΏΠΎΠΌΠ΅Ρ‚ΠΊΠΎΠΉ «эвристика». Норма. Π—Π΅Π»Ρ‘Π½Ρ‹ΠΉ Π±Π΅ΠΉΠ΄ΠΆ. Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ΠΈΡ (Ρ€Π΅Π·ΠΊΠΎΡΡ‚ΡŒ, Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ области) подписаны ΠΊΠ°ΠΊ справочныС β€” ΠΈΡ… ΠΏΠΎΡ€ΠΎΠ³ΠΈ Π½Π΅ ΠΊΠ°Π»ΠΈΠ±Ρ€ΠΎΠ²Π°Π½Ρ‹.
ПанСль **«О ΠΌΠΎΠ΄Π΅Π»ΠΈΒ»** (ΠΊΠ½ΠΎΠΏΠΊΠ° Π² шапкС): Ρ‡Ρ‚ΠΎ Π·Π° Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, Π½Π° ΠΊΠ°ΠΊΠΎΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ΅ ΠΎΠ½ ΠΎΠ±ΡƒΡ‡Π΅Π½, с ΠΊΠ°ΠΊΠΈΠΌ ΠΏΠΎΡ€ΠΎΠ³ΠΎΠΌ Ρ€Π΅ΡˆΠ°Π΅Ρ‚, ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ сравнСния с 95 % ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»Π°ΠΌΠΈ, состав Π΄Π°Π½Π½Ρ‹Ρ…, ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Ρ‚ΠΈΠΏΠΎΠ² Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ ΠΈ список ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ.
ПанСль «О ΠΌΠΎΠ΄Π΅Π»ΠΈΒ»: свСдСния ΠΎ Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚Π΅, ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ с ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»Π°ΠΌΠΈ, состав Π΄Π°Π½Π½Ρ‹Ρ…, ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ
Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ всСх этих Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ β€” сСрвСр (`/api/v1/health`, `/api/v1/model`). Π€Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄ Π½Π°ΠΌΠ΅Ρ€Π΅Π½Π½ΠΎ Π½Π΅ Π΄Π΅Ρ€ΠΆΠΈΡ‚ собствСнных ΠΊΠΎΠΏΠΈΠΉ: Ρ€Π°Π½ΡŒΡˆΠ΅ подписи Ρ‚ΠΈΠΏΠΎΠ² Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ Π±Ρ‹Π»ΠΈ ΠΏΡ€ΠΎΠ΄ΡƒΠ±Π»ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π² `dxa-app.js` ΠΈ Ρ€Π°Π·ΠΎΡˆΠ»ΠΈΡΡŒ с сСрвСрными, ΠΈΠ·-Π·Π° Ρ‡Π΅Π³ΠΎ ΠΊΠΎΠ΄Ρ‹ экспСртной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π»ΠΈΡΡŒ ΠΊΠ°ΠΊ Π΅ΡΡ‚ΡŒ. Π§Ρ‚ΠΎ интСрфСйс Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π½Π΅ ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚: - **Ρ‚ΠΈΠΏ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½ ΠΊΠ°ΠΊ «эвристика»** с пояснСниСм β€” модСль Ρ€Π΅ΡˆΠ°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π±ΠΈΠ½Π°Ρ€Π½ΡƒΡŽ Π·Π°Π΄Π°Ρ‡Ρƒ ΠΈ Ρ‚ΠΈΠΏ Π½Π΅ прСдсказываСт; - **ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠ° Ρ€Π°Π±ΠΎΡ‡Π΅Π³ΠΎ Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚Π° ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Π° ΠΊΠ°ΠΊ Π·Π°Π²Ρ‹ΡˆΠ΅Π½Π½Π°Ρ** прямо Π² Π±Π°Π½Π½Π΅Ρ€Π΅ состояния ΠΈ Π² ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡ΠΊΠ΅: Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚ Π²Ρ‹Π±Ρ€Π°Π½ Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΈΠ· пяти seed'ΠΎΠ², чСстная ΠΎΡ†Π΅Π½ΠΊΠ° Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° β€” срСднСС ΠΏΠΎ seed'Π°ΠΌ; - **ΠΏΠ»ΠΈΡ‚ΠΊΠ° Β«Π‘Ρ€. ΡƒΠ²Π΅Ρ€Π΅Π½Π½ΠΎΡΡ‚ΡŒ ΠΌΠΎΠ΄Π΅Π»ΠΈΒ»** большС Π½Π΅ называСтся Ρ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒΡŽ: Ρ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ эталонных ΠΌΠ΅Ρ‚ΠΎΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… для ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° Π½Π΅Ρ‚; - числовыС ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π² ΠΏΠ°Π½Π΅Π»ΠΈ Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ ΠΈΠ΄ΡƒΡ‚ ΠΏΠΎΠ΄ дисклСймСром ΠΎ нСкалиброванности ΠΏΠΎΡ€ΠΎΠ³ΠΎΠ². --- ## ΠœΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ ΠœΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ зависят ΠΎΡ‚ Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ разбиСния ΠΏΠΎ исслСдованиям, поэтому приводятся с разбросом. Основная ΠΎΡ†Π΅Π½ΠΊΠ° β€” Π½Π° **фиксированном** Ρ€Π°Π·Π±ΠΈΠ΅Π½ΠΈΠΈ ΠΏΠΎ исслСдованиям (ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ 199 снимков / 81 исслСдованиС, валидация 53 снимка / 19 исслСдований, 16 Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ), ΠΏΡΡ‚ΡŒ seed'ΠΎΠ² обучСния, эталон β€” Π²Π΅Ρ€Π΄ΠΈΠΊΡ‚ экспСрта: | Π§Ρ‚ΠΎ ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΎ | Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ | Как ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΎ | |---|---|---| | ROC-AUC | **0.6764** [0.6309, 0.7218] | 5 seed'ΠΎΠ² Π½Π° фиксированном Ρ€Π°Π·Π±ΠΈΠ΅Π½ΠΈΠΈ | | PR-AUC | 0.4759 [0.4141, 0.5377] | Ρ‚Π°ΠΌ ΠΆΠ΅; Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ ΠΏΡ€ΠΈ 30 % Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ β€” 0.30 | | F1 | 0.5676 [0.5270, 0.6082] | Ρ‚Π°ΠΌ ΠΆΠ΅; ΠΏΠΎΡ€ΠΎΠ³ ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Π½ Π½Π° Ρ‚ΠΎΠΉ ΠΆΠ΅ Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ β€” смСщСно Π²Π²Π΅Ρ€Ρ… | | ROC-AUC ΠΏΠΎ областям | ΠΏΠΎΠ·Π²ΠΎΠ½ΠΎΡ‡Π½ΠΈΠΊ 0.943, Π±Π΅Π΄Ρ€ΠΎ R 0.576, Π±Π΅Π΄Ρ€ΠΎ L 0.550 | Ρ€Π°Π±ΠΎΡ‡ΠΈΠΉ Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚, собствСнная валидация | | ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Π°Ρ Π·Π°Π΄Π°Ρ‡Π° Β«ΠΏΠΎΠ·Π²ΠΎΠ½ΠΎΡ‡Π½ΠΈΠΊ / Π±Π΅Π΄Ρ€ΠΎΒ» | AUC 1.00 | ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° работоспособности ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½Π° | | МодСль ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ снимок, Π° Π½Π΅ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ | AUC 0.854 ΠΏΡ€ΠΎΡ‚ΠΈΠ² 0.529 Ρƒ ΠΏΡ€Π°Π²ΠΈΠ»Π° области | `discriminator` Π½Π° всём Π½Π°Π±ΠΎΡ€Π΅, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ ΠΎΠ±ΡƒΡ‡Π°ΡŽΡ‰ΠΈΠ΅ снимки | ΠœΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ ΠΏΠΎ областям β€” Π² `models/train_report.md`, ΠΎΠ½ создаётся ΠΏΡ€ΠΈ ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠΈ. Π Π°Π·Π±ΠΈΠ²ΠΊΠ° Π²Π°ΠΆΠ½Π°, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ распрСдСлСны Π½Π΅Ρ€Π°Π²Π½ΠΎΠΌΠ΅Ρ€Π½ΠΎ: Π² ΠΏΠΎΠ·Π²ΠΎΠ½ΠΎΡ‡Π½ΠΈΠΊΠ΅ 33 ΠΈΠ· 99, Ρƒ Π±Ρ‘Π΄Π΅Ρ€ 21–22 ΠΈΠ· 73–79, Π° ΠΎΠ±Π»Π°ΡΡ‚ΡŒ ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ опрСдСляСтся ΠΏΠΎ ΡˆΠΈΡ€ΠΈΠ½Π΅ ΠΊΠ°Π΄Ρ€Π°. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΎΠ±Ρ‰ΠΈΠΉ AUC частично ΠΎΡ‚Ρ€Π°ΠΆΠ°Π΅Ρ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ области, Π° Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ распознаваниС Π΄Π΅Ρ„Π΅ΠΊΡ‚Π°. ### Π’Ρ‹Π±ΠΎΡ€ ΠΏΡ€Π°Π²ΠΈΠ»Π° Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠΈ ΠœΠ΅Ρ‚ΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ· экспСртной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΈΠ»ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΏΠΎΠΌΠ΅Ρ‚ΠΊΠΈ, проставлСнныС Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ Π² ΠΈΠΌΠ΅Π½Π°Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ² (суффикс `_bad`). ΠŸΠΎΠΌΠ΅Ρ‚ΠΊΠΈ Ρ€Π°ΡΡ…ΠΎΠ΄ΠΈΠ»ΠΈΡΡŒ с ΠΎΡ†Π΅Π½ΠΊΠΎΠΉ экспСрта Π² 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 | ΠŸΠ°Ρ€Π½Π°Ρ Ρ€Π°Π·Π½ΠΈΡ†Π° (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π°Π±Π»ΠΈΡ†Π° βˆ’ с суффиксами): ROC-AUC **+0.0564** [+0.0403, +0.0725], PR-AUC **+0.0713** [+0.0398, +0.1028] β€” Π·Π½Π°ΠΊΠΈ `+++++`, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ прСимущСство Π½Π° всСх пяти seed'Π°Ρ…. **ΠŸΡ€ΠΈΠ½ΡΡ‚ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ Β«Ρ‚ΠΎΠ»ΡŒΠΊΠΎ экспСртная Ρ‚Π°Π±Π»ΠΈΡ†Π°Β».** ΠŸΠΎΠΌΠ΅Ρ‚ΠΊΠΈ Π² ΠΈΠΌΠ΅Π½Π°Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΏΡ€ΠΎΡΡ‚Π°Π²Π»ΡΠ»ΠΈΡΡŒ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ ΠΈ оказались Π½Π΅Π½Π°Π΄Ρ‘ΠΆΠ½Ρ‹ΠΌΠΈ: ΠΎΠ½ΠΈ ΡƒΡ…ΡƒΠ΄ΡˆΠ°Π»ΠΈ согласиС ΠΌΠΎΠ΄Π΅Π»ΠΈ с экспСртом Π½Π° Π½Π΅Π²ΠΈΠ΄Π°Π½Π½Ρ‹Ρ… исслСдованиях. ΠžΠ³ΠΎΠ²ΠΎΡ€ΠΊΠ°: эталон β€” Ρ‚Π° ΠΆΠ΅ Ρ‚Π°Π±Π»ΠΈΡ†Π°, поэтому Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, ΠΎΠ±ΡƒΡ‡Π°Π²ΡˆΠΈΠΉΡΡ Π½Π° Π½Π΅ΠΉ, Π² Π²Ρ‹ΠΈΠ³Ρ€Ρ‹ΡˆΠ½ΠΎΠΌ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ; Π·Π½Π°Ρ‡ΠΈΠΌΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π΅Π½Π°Π΄Ρ‘ΠΆΠ½Ρ‹Ρ… ΠΏΠΎΠΌΠ΅Ρ‚ΠΎΠΊ согласиС **сниТаСт**. ΠžΡ‚Ρ‡Ρ‘Ρ‚ с ΠΏΠΎΠ»Π½Ρ‹ΠΌΠΈ числами ΠΈ Ρ€Π°Π·Π±ΠΎΡ€ΠΎΠΌ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ β€” `assets/labeling.md`; ΠΎΡ‚Ρ‡Ρ‘Ρ‚ обучСния Ρ€Π°Π±ΠΎΡ‡Π΅Π³ΠΎ Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚Π° β€” `models/train_report.json`. Π‘Π°ΠΌΠΎ сравнСниС ΠΏΡ€Π°Π²ΠΈΠ» хранится Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Π²ΠΈΠ΄Π΅ чисСл Π² этих Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ…: Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚Ρ‹ ΠΏΡ€ΠΎΠ³ΠΎΠ½ΠΎΠ² ΡƒΠ΄Π°Π»Π΅Π½Ρ‹, Π° ΠΏΠ΅Ρ€Π΅ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ `./run.sh split && ./run.sh compare`. ВрСмя ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ снимка β€” порядка 0.02–0.05 с Π½Π° CPU (ResNet18 с Π·Π°ΠΌΠΎΡ€ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌ backbone), Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠ΅ Β«Π½Π΅ Π±ΠΎΠ»Π΅Π΅ 3 ΠΌΠΈΠ½ΡƒΡ‚ Π½Π° исслСдованиС» выполняСтся с большим запасом. --- ## ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΡ (Π²Π°ΠΆΠ½ΠΎ для ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΠΈ) 1. **Π Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ° Π²Ρ‹Π²Π΅Π΄Π΅Π½Π° ΠΈΠ· ΠΎΡ†Π΅Π½ΠΊΠΈ исслСдования.** ЭкспСртная Ρ‚Π°Π±Π»ΠΈΡ†Π° описываСт исслСдованиС, Π° Π½Π΅ снимок; пСрСнос ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π΅Π½ (ΠΎΠ±Π»Π°ΡΡ‚ΡŒ встрСчаСтся ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·), Π½ΠΎ ΠΏΠΎΡˆΡ‚ΡƒΡ‡Π½ΠΎΠΉ экспСртной ΠΎΡ†Π΅Π½ΠΊΠΈ снимков Π² Π½Π°Π±ΠΎΡ€Π΅ Π½Π΅Ρ‚. ΠŸΡ€ΠΎΠΈΡΡ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строки зафиксировано Π² `labels/labels_images.csv`. Π Π°Π·Π±ΠΎΡ€ β€” Π² `assets/labeling.md`. 2. **Мало Π΄Π°Π½Π½Ρ‹Ρ….** 252 ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… снимка, 77 Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ. Π”ΠΎΠ²Π΅Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»Ρ‹ ΡˆΠΈΡ€ΠΎΠΊΠΈΠ΅; ΠΎΡ†Π΅Π½ΠΊΠ° Π½Π° Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΎΠΌ Π½Π°Π±ΠΎΡ€Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒΡΡ. 3. **Π’ΠΈΠΏ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ опрСдСляСтся эвристиками, Π° Π½Π΅ ΠΎΠ±ΡƒΡ‡Π΅Π½Π½ΠΎΠΉ модСлью.** Для чСстного ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΊΠ»Π°ΡΡΠ° Π½ΡƒΠΆΠ½Π° Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ° Ρ‚ΠΈΠΏΠΎΠ² Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ снимка. 4. **ΠžΠ±Π»Π°ΡΡ‚ΡŒ опрСдСляСтся ΠΏΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρƒ ΠΊΠ°Π΄Ρ€Π°.** ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ Π±Π΅Π·ΠΎΡˆΠΈΠ±ΠΎΡ‡Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π° этом ΠΎΠ±ΠΎΡ€ΡƒΠ΄ΠΎΠ²Π°Π½ΠΈΠΈ (99/99 для ΠΏΠΎΠ·Π²ΠΎΠ½ΠΎΡ‡Π½ΠΈΠΊΠ°), Π½ΠΎ ΠΏΡ€ΠΈ смСнС Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π° ΠΏΠΎΡ€ΠΎΠ³ `SPINE_MIN_WIDTH` ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΊΠ°Π»ΠΈΠ±Ρ€ΠΎΠ²ΠΊΠΈ. 5. **Π’ DICOM Π½Π΅Ρ‚ Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠΈ ROI.** Ни overlay, Π½ΠΈ graphic annotation Π² Ρ„Π°ΠΉΠ»Π°Ρ… Π½Π΅Ρ‚, поэтому ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ нанСсённых областСй измСрСния нСльзя ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ прямым сравнСниСм β€” оцСниваСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ гСомСтрия Π²ΠΈΠ΄ΠΈΠΌΠΎΠΉ Π·ΠΎΠ½Ρ‹. 6. **Эвристики ΠΈΠ· `src/quality/detailed_assessment.py` Π½Π΅ ΠΊΠ°Π»ΠΈΠ±Ρ€ΠΎΠ²Π°Π½Ρ‹.** ΠŸΠΎΡ€ΠΎΠ³ΠΈ для «двиТСния», Β«Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ²Β» ΠΈ отступов ROI рассчитаны Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΌΠ°ΡΡˆΡ‚Π°Π± интСнсивностСй: Π½Π° этом Π½Π°Π±ΠΎΡ€Π΅ ΠΎΠ½ΠΈ ΡΡ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ ΠΏΠΎΡ‡Ρ‚ΠΈ для любого снимка, Π° ΠΏΡ€ΠΈΠ·Π½Π°ΠΊ рСзкости Π²Π΅Π΄Ρ‘Ρ‚ сСбя ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½ΠΎ Π² ΠΏΠΎΠ·Π²ΠΎΠ½ΠΎΡ‡Π½ΠΈΠΊΠ΅ ΠΈ Π±Ρ‘Π΄Ρ€Π°Ρ…. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π² ΠΏΠ°Π½Π΅Π»ΠΈ Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ **числовыС измСрСния** с ΠΏΠΎΠΌΠ΅Ρ‚ΠΊΠΎΠΉ «справ.Β», Π° Π½Π΅ Π²Π΅Ρ€Π΄ΠΈΠΊΡ‚Ρ‹ Β«Π”Π°/НСт». ΠšΠ»Π°ΡΡΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ выполняСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ модСль. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π΅Ρ‘ Π²ΠΊΠ»Π°Π΄ ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ: ```bash python -m src.dxa.discriminator --model-path models/dxa_model.pth ``` ## Π§Ρ‚ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Π½ΠΎ ΠΈ ΠΊΠ°ΠΊ | ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° | Команда | Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ | |---|---|---| | МодСль ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ снимок, Π° Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ | `python -m src.dxa.discriminator` | AUC 0.854 ΠΏΡ€ΠΎΡ‚ΠΈΠ² 0.529 Ρƒ ΠΏΡ€Π°Π²ΠΈΠ»Π° Β«ΠΏΠΎΠ·Π²ΠΎΠ½ΠΎΡ‡Π½ΠΈΠΊ = Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅Β»; Π²Π½ΡƒΡ‚Ρ€ΠΈ областСй Ρƒ ΠΌΠΎΠ΄Π΅Π»ΠΈ 0.85–0.93, Ρƒ ΠΏΡ€Π°Π²ΠΈΠ»Π° 0.50 | | ΠšΠΎΠ½Ρ‚Ρ€Π°ΠΊΡ‚ API для Π²Π΅Π±-интСрфСйса | `python -m pytest tests/test_api_contract.py` | поля ΠΏΠ°Π½Π΅Π»ΠΈ Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ, Ρ€Π°Π·Π»ΠΈΡ‡ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊ, PNG-Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, отсутствиС Π½Π΅ΠΊΠ°Π»ΠΈΠ±Ρ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π²Π΅Ρ€Π΄ΠΈΠΊΡ‚ΠΎΠ², каноничСскиС ΠΊΠΎΠ΄Ρ‹ Ρ‚ΠΈΠΏΠΎΠ² Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ, ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ | | Π•Π΄ΠΈΠ½Ρ‹ΠΉ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ | `python -m pytest tests/test_violations.py` | ΠΊΠΎΠ΄Ρ‹, подписи, ΠΊΠΎΠ΄Ρ‹ SR, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ с Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ | | Π Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ° ΠΈ Ρ€Π°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… | `python -m pytest tests/test_labels.py` | склСйка Π΄ΡƒΠ±Π»Π΅ΠΉ, Ρ€Π°Π·Π±ΠΎΡ€ ΠΈΠΌΡ‘Π½, фиксация разбиСния, отсутствиС ΡƒΡ‚Π΅Ρ‡ΠΊΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ train/val | | ИмСна DICOM-Ρ„Π°ΠΉΠ»ΠΎΠ² | `python -m pytest tests/test_rename_files.py` | Ρ€Π°Π·Π±ΠΎΡ€ ΠΈΠΌΡ‘Π½, поиск свободного Π½ΠΎΠΌΠ΅Ρ€Π° ΠΏΡ€ΠΈ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Π΅, ΠΎΡ‚ΠΊΠ°Π· ΠΎΡ‚ угадывания области, Ρ†ΠΈΠΊΠ» Β«ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ β†’ ΠΎΡ‚ΠΊΠ°Ρ‚ΠΈΡ‚ΡŒΒ» | | Π Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ° ΠΏΠΎ экспСртной Ρ‚Π°Π±Π»ΠΈΡ†Π΅ | `python -m pytest tests/test_excel_labels.py` | Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΠ΅Π², голосованиС ΠΏΠΎ области, пСрСнос Π½Π° СдинствСнноС Π±Π΅Π΄Ρ€ΠΎ, ΠΏΡ€Π°Π²ΠΈΠ»Π° `table`/`union`/`expert`, ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΡŽ | | Π’Ρ‹Π±ΠΎΡ€ ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΌΠ΅Ρ‚ΠΊΠΈ | `./run.sh split && ./run.sh compare` | ROC-AUC 0.6764 ΠΏΡ€ΠΎΡ‚ΠΈΠ² 0.6199 ΠΏΠΎ эталону, парная Ξ” +0.0564 [+0.0403, +0.0725], 5/5 seed'ΠΎΠ² Π² ΠΏΠΎΠ»ΡŒΠ·Ρƒ экспСртной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ | | ΠœΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ ΠΈ ΠΏΠΎΡ€ΠΎΠ³ | `python -m pytest tests/test_preprocess_and_model.py` | ΠΏΠΎΠ΄Π±ΠΎΡ€ ΠΏΠΎΡ€ΠΎΠ³Π° ΠΏΡ€ΠΈ дисбалансС, roundtrip Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚Π°, BatchNorm | | Π’Π΅Π±-интСрфСйс Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ | `node tests/browser/ui_check.js` | подсказка ΠΎ ΠΊΠ»ΠΈΠΊΠ°Π±Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ строк Π²ΠΈΠ΄Π½Π° ΠΈ скрываСтся Π½Π° пустом Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π΅; ΠΊΠ½ΠΎΠΏΠΊΠ° Β«ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒΒ» ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ панСль; значСния ΠΏΠ°Π½Π΅Π»ΠΈ ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ строк; панСль «О ΠΌΠΎΠ΄Π΅Π»ΠΈΒ» наполняСтся ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠ°ΠΌΠΈ ΠΈ словарём | | Π Π°Π±ΠΎΡ‚Π° Π±Π΅Π· сСти | `node tests/browser/ui_offline.js` | ноль Π²Π½Π΅ΡˆΠ½ΠΈΡ… запросов, стили ΠΈ ΠΈΠΊΠΎΠ½ΠΊΠΈ Π½Π° мСстС | Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€Π½Ρ‹Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ Π·Π°ΠΏΡƒΡ‰Π΅Π½Π½ΠΎΠ³ΠΎ сСрвСра: ```bash python -m uvicorn src.main:app --port 8123 node tests/browser/ui_check.js # панСль Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ обновляСтся ΠΏΠΎ ΠΊΠ»ΠΈΠΊΡƒ node tests/browser/ui_offline.js # Ρ€Π°Π±ΠΎΡ‚Π° Π±Π΅Π· доступа ΠΊ внСшним сСрвисам ``` ΠžΡ„Π»Π°ΠΉΠ½-Ρ€Π΅ΠΆΠΈΠΌ обСспСчСн Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ копиями Tailwind ΠΈ FontAwesome (`src/api/static/vendor`, `src/api/static/webfonts`); страница Π½Π΅ обращаСтся ΠΊ CDN. ## План Π΄ΠΎΡ€Π°Π±ΠΎΡ‚ΠΊΠΈ - Π Π°Π·ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ Ρ‚ΠΈΠΏΡ‹ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ снимка ΠΈ ΠΎΠ±ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠ»Π΅ΠΉΠ±Π»-классификатор. - Π‘ΠΎΠ±Ρ€Π°Ρ‚ΡŒ 500+ исслСдований для устойчивых ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊ ΠΈ чСстной Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ. - Π—Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΠΎΡ€ΠΎΠ³ ΠΏΠΎ ΡˆΠΈΡ€ΠΈΠ½Π΅ ΠΊΠ°Π΄Ρ€Π° Π½Π° ΠΊΠ°Π»ΠΈΠ±Ρ€ΠΎΠ²ΠΊΡƒ ΠΏΠΎ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹ΠΌ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π°. --- ## Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ``` bone_2026/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ main.py # FastAPI: ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ β”‚ β”œβ”€β”€ dxa/ # Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΎΡ†Π΅Π½ΠΊΠΈ качСства β”‚ β”‚ β”œβ”€β”€ labels.py # Ρ€Π°Π·Π±ΠΎΡ€ ΠΈΠΌΡ‘Π½, ΠΌΠ΅Ρ‚ΠΊΠΈ, склСйка Π΄ΡƒΠ±Π»Π΅ΠΉ, сплит β”‚ β”‚ β”œβ”€β”€ excel_labels.py # Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ° снимков ΠΏΠΎ экспСртной Ρ‚Π°Π±Π»ΠΈΡ†Π΅ β”‚ β”‚ β”œβ”€β”€ rename_files.py # ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΈΠΌΡ‘Π½ DICOM ΠΊ Π΅Π΄ΠΈΠ½ΠΎΠΌΡƒ Π²ΠΈΠ΄Ρƒ β”‚ β”‚ β”œβ”€β”€ violations.py # Π΅Π΄ΠΈΠ½Ρ‹ΠΉ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Ρ‚ΠΈΠΏΠΎΠ² Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΉ (ΠΊΠΎΠ΄Ρ‹, подписи) β”‚ β”‚ β”œβ”€β”€ model_card.py # ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡ΠΊΠ° Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ для /api/v1/model ΠΈ интСрфСйса β”‚ β”‚ β”œβ”€β”€ compare_labels.py # сравнСниС источников Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠΈ Π½Π° ΠΎΠ΄Π½ΠΎΠΌ Π½Π°Π±ΠΎΡ€Π΅ β”‚ β”‚ β”œβ”€β”€ discriminator.py # ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π²ΠΊΠ»Π°Π΄Π° содСрТимого снимка β”‚ β”‚ β”œβ”€β”€ render.py # Ρ€Π΅Π½Π΄Π΅Ρ€ снимков ΠΈ ΠΊΠΎΠ½Ρ‚Π°ΠΊΡ‚Π½Ρ‹Ρ… листов β”‚ β”‚ β”œβ”€β”€ preprocess.py # DICOM -> Ρ‚Π΅Π½Π·ΠΎΡ€ (ΠΎΠ±Ρ‰ΠΈΠΉ для обучСния ΠΈ API) β”‚ β”‚ β”œβ”€β”€ dataset.py # Dataset ΠΈ DataLoader β”‚ β”‚ β”œβ”€β”€ model.py # ΡΠ΅Ρ‚ΡŒ, ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ, ΠΏΠΎΠ΄Π±ΠΎΡ€ ΠΏΠΎΡ€ΠΎΠ³Π° β”‚ β”‚ β”œβ”€β”€ train.py # ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΡ‚Ρ‡Ρ‘Ρ‚ β”‚ β”‚ └── inference.py # ΠΏΠ°ΠΊΠ΅Ρ‚Π½Ρ‹ΠΉ инфСрСнс, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ области β”‚ β”œβ”€β”€ quality/ # эвристики качСства, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ API β”‚ └── api/static/ # Π²Π΅Π±-интСрфСйс β”œβ”€β”€ labels/labels_images.csv # Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ° снимков: ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ (+ .xlsx) β”œβ”€β”€ labels/labels_images_table.csv # Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Β«Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π°Π±Π»ΠΈΡ†Π°Β» (Ρ‚ΠΎ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ Π²Ρ‹ΡˆΠ΅) β”œβ”€β”€ labels/labels_images_union.csv # Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Β«Ρ‚Π°Π±Π»ΠΈΡ†Π° ΠΈΠ»ΠΈ суффикс ΠΈΠΌΠ΅Π½ΠΈΒ» β”œβ”€β”€ labels/labels_images_expert.csv # эталон для ΠΎΡ†Π΅Π½ΠΊΠΈ: Ρ‚ΠΎΠ»ΡŒΠΊΠΎ снимки с ΠΎΡ†Π΅Π½ΠΊΠΎΠΉ β”œβ”€β”€ labels/split_expert_seed42.json # зафиксированноС Ρ€Π°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ (19 исслСдований) β”œβ”€β”€ labels/rename_map.csv # ΠΊΠ°Ρ€Ρ‚Π° ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠΉ Ρ„Π°ΠΉΠ»ΠΎΠ² (для ΠΎΡ‚ΠΊΠ°Ρ‚Π°) β”œβ”€β”€ assets/img/ # схСмы Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ ΠΈ ΡΠΊΡ€ΠΈΠ½ΡˆΠΎΡ‚Ρ‹ интСрфСйса β”œβ”€β”€ assets/labeling.md # ΠΊΠ°ΠΊ построСна Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ° ΠΈ ΠΊΠ°ΠΊ ΡΡ€Π°Π²Π½ΠΈΠ²Π°Π»ΠΈΡΡŒ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ β”œβ”€β”€ models/dxa_model.pth # Ρ€Π°Π±ΠΎΡ‡ΠΈΠΉ Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚ (+ train_report.md/.json) β”œβ”€β”€ tests/ # pytest: ΠΌΠ΅Ρ‚ΠΊΠΈ, сплит, ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ, модСль, API β”œβ”€β”€ dataset_hack/ # Π΄Π°Π½Π½Ρ‹Π΅ (Π² git Π½Π΅ хранятся) β”œβ”€β”€ Dockerfile β”œβ”€β”€ requirements.txt └── run.sh ``` ## Запуск обучСния ```bash python -m src.dxa.train --epochs 100 --output-dir models ``` | ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ | По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ | ОписаниС | |---|---|---| | `--data-root` | `dataset_hack` | ΠšΠ°Ρ‚Π°Π»ΠΎΠ³ датасСта | | `--annotation-path` | `dataset_hack/НД_для_обучСния/Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ°.xlsx` | Excel с Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠΎΠΉ (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΡ‚Ρ‡Ρ‘Ρ‚ ΠΎ расхоТдСниях) | | `--labels-csv` | `labels/labels_images.csv` | Π Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ° снимков ΠΈΠ· `./run.sh label`; пустая строка β€” ΠΌΠ΅Ρ‚ΠΊΠΈ ΠΈΠ· ΠΈΠΌΡ‘Π½ Ρ„Π°ΠΉΠ»ΠΎΠ²; ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ„Π°ΠΉΠ» β€” ΠΎΡ‚ΠΊΠ°Ρ‚ ΠΊ ΠΈΠΌΠ΅Π½Π°ΠΌ с ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ | | `--split-file` | β€” | ЗафиксированноС Ρ€Π°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ ΠΈΠ· `./run.sh split`; ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΉ held-out Π½Π°Π±ΠΎΡ€ для сравнСния Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠΈ | | `--backbone` | `resnet18` | `resnet18` / `resnet34` | | `--head` | `linear` | `linear` (Π»ΠΈΠ½Π΅ΠΉΠ½Ρ‹ΠΉ Π·ΠΎΠ½Π΄) / `mlp` | | `--freeze-epochs` | `-1` | `-1` β€” backbone Π·Π°ΠΌΠΎΡ€ΠΎΠΆΠ΅Π½ всСгда; `0` β€” ΠΎΠ±ΡƒΡ‡Π°Ρ‚ΡŒ всю ΡΠ΅Ρ‚ΡŒ | | `--epochs`, `--batch-size`, `--learning-rate`, `--weight-decay` | 100 / 16 / 3e-4 / 5e-2 | ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ | | `--balance` | `none` | `loss` / `sampler` для компСнсации дисбаланса | | `--val-fraction`, `--seed` | 0.2 / 42 | Π Π°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ ΠΏΠΎ исслСдованиям | | `--augment` | Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ | Π’ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΡΡ€ΠΊΠΎΡΡ‚Π½ΡƒΡŽ Π°ΡƒΠ³ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ (ΡƒΡ…ΡƒΠ΄ΡˆΠ°Π΅Ρ‚ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ, см. ΠΏ. 5) | | `--output-dir` | `models` | ΠšΡƒΠ΄Π° ΡΠΎΡ…Ρ€Π°Π½ΡΡ‚ΡŒ Ρ‡Π΅ΠΊΠΏΠΎΠΈΠ½Ρ‚ ΠΈ ΠΎΡ‚Ρ‡Ρ‘Ρ‚Ρ‹ | | `--dry-run` | β€” | ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Ρ€Π°Π·Π±ΠΎΡ€ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ Ρ€Π°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ Π±Π΅Π· обучСния | ПослС обучСния Π² `--output-dir` ΠΏΠΎΡΠ²Π»ΡΡŽΡ‚ΡΡ `dxa_model.pth`, `train_report.md` ΠΈ `train_report.json`; ΠΎΡ‚Ρ‡Ρ‘Ρ‚ ΡƒΠ΄ΠΎΠ±Π½ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈΡ‚ΡŒ ΠΊ ΠΏΡ€Π΅Π·Π΅Π½Ρ‚Π°Ρ†ΠΈΠΈ. ## Команда - **Π“Ρ€Π°Ρ‡Π΅Π² ДСнис** β€” Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° - **Π“Ρ€Π°Ρ‡Π΅Π² Π’Π°Ρ‚ΡŒΡΠ½Π°** β€” ΠΊΠ°ΠΏΠΈΡ‚Π°Π½
Built for Bone Quality Assessment Hackathon 2026