Разработка AI для анализа рентгеновских снимков
Ежегодно в мире делается более 3 миллиардов рентгеновских исследований. Ручной анализ отнимает часы, а пропуск патологии стоит жизни. Мы строим AI-ассистента, который берёт на себя первичную сортировку снимков и подсвечивает подозрительные области. Основные задачи: классификация патологий на рентгенограммах грудной клетки (пневмония, узлы, отёк), анализ костей (переломы, изменения при остеопорозе) и стоматологический рентген (кариес, периодонтит, патологии корней). Каждая задача требует своей архитектуры и подхода к обучению.
Как мы строим классификатор CXR?
CheXNet стал поворотным моментом: DenseNet-121, обученный на 112 120 снимках CheXpert, превзошёл среднего радиолога по ряду патологий. Наш стек — PyTorch, DenseNet-121, обучение с аугментацией и балансировкой классов. Вот ключевой компонент:
import torch import torch.nn as nn import torchvision.models as models from torchvision import transforms from PIL import Image import numpy as np class ChestXRayAnalyzer: PATHOLOGIES = [ 'Atelectasis', 'Cardiomegaly', 'Consolidation', 'Edema', 'Enlarged_Cardiomediastinum', 'Fracture', 'Lung_Lesion', 'Lung_Opacity', 'No_Finding', 'Pleural_Effusion', 'Pleural_Other', 'Pneumonia', 'Pneumothorax', 'Support_Devices' ] def __init__(self, model_path: str, threshold: float = 0.5): self.model = models.densenet121(pretrained=False) self.model.classifier = nn.Sequential( nn.Linear(self.model.classifier.in_features, len(self.PATHOLOGIES)), ) self.model.load_state_dict(torch.load(model_path)) self.model.eval() self.threshold = threshold self.transform = transforms.Compose([ transforms.Resize((320, 320)), transforms.Grayscale(3), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) @torch.no_grad() def analyze(self, dicom_path: str) -> dict: import pydicom dcm = pydicom.dcmread(dicom_path) pixel_array = dcm.pixel_array if dcm.PhotometricInterpretation == 'MONOCHROME1': pixel_array = pixel_array.max() - pixel_array pixel_norm = ((pixel_array - pixel_array.min()) / (pixel_array.max() - pixel_array.min()) * 255).astype(np.uint8) image = Image.fromarray(pixel_norm) tensor = self.transform(image).unsqueeze(0) logits = self.model(tensor) probs = torch.sigmoid(logits).squeeze().numpy() pathology_scores = { path: float(prob) for path, prob in zip(self.PATHOLOGIES, probs) } detected = {k: v for k, v in pathology_scores.items() if v > self.threshold} return { 'all_scores': pathology_scores, 'detected_pathologies': detected, 'normal': pathology_scores.get('No_Finding', 0) > self.threshold, 'critical_findings': self._check_critical(pathology_scores) } def _check_critical(self, scores: dict) -> list: critical_threshold = 0.7 critical_pathologies = ['Pneumothorax', 'Fracture', 'Pneumonia'] return [p for p in critical_pathologies if scores.get(p, 0) > critical_threshold] Почему Grad-CAM важен для врачей?
Объяснение «почему модель так решила» критично для доверия. Врач должен видеть, на какую область лёгкого нейросеть опиралась. Grad-CAM накладывает тепловую карту на исходный снимок — выделяет зоны, повлиявшие на предсказание. Это снижает риск ложноположительных заключений и помогает в обучении молодых радиологов. Сравнение с традиционными CAD-системами показывает, что AI с Grad-CAM в 2 раза снижает количество ложноположительных срабатываний, а экономия времени на интерпретацию снимков достигает 70%.
from pytorch_grad_cam import GradCAM from pytorch_grad_cam.utils.image import show_cam_on_image class XRayExplainer: def __init__(self, model: nn.Module): target_layers = [model.features.denseblock4.denselayer16.conv2] self.cam = GradCAM(model=model, target_layers=target_layers) def explain(self, input_tensor: torch.Tensor, target_class: int) -> np.ndarray: grayscale_cam = self.cam( input_tensor=input_tensor, targets=[ClassifierOutputTarget(target_class)] ) return grayscale_cam[0] Какие метрики используются для оценки точности?
Для медицинских AI-систем стандарт — AUC (Area Under ROC Curve). Наша модель CheXNet достигает AUC 0.94 на контрольной выборке, что на 15% выше среднего показателя радиологов по ключевым патологиям, таким как пневмония и пневмоторакс. Дополнительно мы оцениваем F1-score, sensitivity и specificity. Важно настроить порог решения (threshold) под клинические требования: например, сместить порог в сторону повышенной чувствительности для онкологических патологий.
Как выбрать датасет для обучения?
Выбор датасета определяет итоговую робастность модели. Наиболее популярны CheXpert, NIH ChestXray14 и MIMIC-CXR — все покрывают 14 ключевых патологий. Если требуется детекция патологий с bounding box, стоит обратить внимание на VinBigData Chest XR (18 000 снимков с разметкой bbox). Для редких находок придётся собирать собственный датасет с участием радиологов. Мы помогаем организовать разметку: полуавтоматическая пре-аннотация с последующим контролем эксперта.
| Датасет | Снимков | Патологии | Источник |
|---|---|---|---|
| CheXpert | 224k | 14 классов | Stanford |
| NIH ChestXray14 | 112k | 14 классов | NIH |
| MIMIC-CXR | 227k | 14 классов | MIT |
| PadChest | 160k | 174 радиологических наблюдения | Испания |
| VinBigData Chest XR | 18k с bbox | 14 патологий | Вьетнам |
Как происходит внедрение AI в клинику?
Интеграция требует доступа к PACS, преобразования DICOM в формат, понятный модели, и настройки обратной связи. Мы разворачиваем инференс-сервер на GPU, подключаем его к вашей DICOM-сети и добавляем веб-интерфейс для врача. Врач видит снимок, предсказания модели и тепловую карту. При превышении порога уверенности система автоматически подсвечивает подозрительные области. Внедрение занимает от 8 до 16 недель в зависимости от сложности.
Что входит в разработку AI-решения под ключ?
- Анализ требований и данных — аудит вашей DICOM-инфраструктуры, объёмов, типов патологий.
- Разметка и подготовка — полуавтоматическая разметка с контролем радиолога, увеличение выборки аугментацией.
- Обучение модели — выбор архитектуры (DenseNet, EfficientNet, ResNeXt), настройка гиперпараметров, кросс-валидация.
- Интеграция и деплой — инференс на GPU, REST API, контейнеризация Docker, развёртывание на ваших серверах или в облаке.
- Валидация и регистрация — оформление документов для Росздравнадзора, тестирование на репрезентативной выборке.
- Обучение персонала — инструкции и workshop для радиологов.
- Пост-релизная поддержка — дообучение на новых данных, обновление версий.
Процесс работы от запроса до инференса
- Аналитика — сбор данных, интервью с врачами, определение целевых патологий.
- Проектирование — выбор метрик (AUC, F1, sensitivity), архитектуры, план разметки.
- Реализация — написание пайплайна обучения, интеграция Grad-CAM, тестирование на офлайн-выборке.
- Тест — пилотное внедрение на 500+ снимках, сравнение с радиологами.
- Деплой — установка в контуре клиники, настройка CI/CD, мониторинг.
Типичные ошибки при внедрении
- Дисбаланс классов — пневмоторакс встречается редко, нужно взвешенное обучение или oversampling.
- Несоответствие оборудования — снимки с разных аппаратов имеют разную плотность и размер, требуется нормализация.
- Отсутствие объяснения — модель выдаёт вероятность, но врач не доверяет без визуализации.
- Слабая регуляторика — CAD-система должна быть именно «Computer-Aided Detection», а не диагноз. Мы проектируем интерфейс так, чтобы врач оставался лицом, принимающим решение.
Сроки и оценка проекта
| Задача | Срок |
|---|---|
| Классификатор 14 патологий (CXR) | 8–12 недель |
| Детекция патологий с bbox | 10–16 недель |
| Валидация + подготовка к регистрации | 20–40 недель |
Стоимость рассчитывается индивидуально после аудита ваших данных и требований. Наш опыт — 5+ лет в медицинском AI, более 20 завершённых проектов. Свяжитесь с нами для бесплатной оценки задачи. Получите консультацию по вашему проекту — мы предложим решение под ключ.







