AI-система цифровой патологии: WSI, MIL, heatmap внимания

Отметим: когда патологу нужно просмотреть 100 препаратов в день, каждый — гигапиксельный скан, глаза устают уже к обеду, а риск пропустить микроочаг рака растёт. Мы разрабатываем AI-системы цифровой патологии, которые берут на себя рутинный анализ: выделяют участки с подозрением на рак, классифициру

Направления AI-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1302
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    998
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1267
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    714
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1006

Отметим: когда патологу нужно просмотреть 100 препаратов в день, каждый — гигапиксельный скан, глаза устают уже к обеду, а риск пропустить микроочаг рака растёт. Мы разрабатываем AI-системы цифровой патологии, которые берут на себя рутинный анализ: выделяют участки с подозрением на рак, классифицируют ткани, строят heatmap внимания. Под ключ, с интеграцией в существующую LIS и обучением персонала. Наши модели достигают AUC ≥ 0.95 на валидации, что подтверждено независимыми тестами. Клиенты экономят существенную сумму на оплате работы патологов.

Какие проблемы решаем

Проблема 1: Гигапиксельные данные. Прямая подача WSI в ResNet-50 невозможна — не хватит памяти даже на A100. Решение — тайлинг: нарезка на фрагменты 256×256 с перекрытием, фильтрация фона (стекло, воздух) по HSV-маске. Только тайлы с >50% ткани попадают в анализ.

Проблема 2: Отсутствие попиксельных аннотаций. В клинической практике редки размеченные изображения на уровне клеток. MIL решает это: весь срез (bag) считается положительным, если хотя бы один тайл содержит опухоль. Нейросеть сама учится выделять значимые патчи через attention. Подробнее о MIL.

Проблема 3: Воспроизводимость и интерпретируемость. Врач должен понимать, почему AI поставил диагноз. Мы строим heatmap внимания: attention scores проецируются обратно на WSI, подсвечивая подозрительные области. Патолог проверяет именно их, а не просматривает весь срез.

Тайлинг и многомасштабный анализ WSI

Тайлинг — стандартный подход для обработки гигапиксельных изображений. Код ниже показывает обработку WSI через OpenSlide с фильтром тканевых тайлов. Многомасштабность обеспечивается за счёт уровней увеличения (level 0 = x40, level 1 = x20 и т.д.).

import openslide import numpy as np from PIL import Image from pathlib import Path import torch class WSIProcessor: """ Обработка Whole Slide Image через тайлинг. openslide поддерживает SVS, TIFF, NDPI, SCN форматы. """ def __init__(self, wsi_path: str): self.slide = openslide.OpenSlide(wsi_path) self.dimensions = self.slide.dimensions # (W, H) на level 0 self.level_count = self.slide.level_count # Обычно: level 0 = x40, level 1 = x20, level 2 = x10, level 3 = x4 mpp = float(self.slide.properties.get( openslide.PROPERTY_NAME_MPP_X, 0.25 )) # микрон/пиксель self.magnifications = { lvl: 0.25 / (mpp * self.slide.level_downsamples[lvl]) for lvl in range(self.level_count) } def extract_tiles( self, level: int, tile_size: int = 256, overlap: int = 0, tissue_threshold: float = 0.5 # минимум % ткани в тайле ) -> list[dict]: """ Нарезка WSI на тайлы заданного уровня. Пропускаем тайлы с преобладанием фона (стекло/воздух). """ level_w, level_h = self.slide.level_dimensions[level] downsample = self.slide.level_downsamples[level] stride = tile_size - overlap tiles = [] for y in range(0, level_h - tile_size + 1, stride): for x in range(0, level_w - tile_size + 1, stride): # Координаты в level 0 для openslide.read_region x0 = int(x * downsample) y0 = int(y * downsample) tile = self.slide.read_region( (x0, y0), level, (tile_size, tile_size) ).convert('RGB') # Фильтр по содержанию ткани tile_arr = np.array(tile) if self._tissue_ratio(tile_arr) >= tissue_threshold: tiles.append({ 'image': tile, 'level': level, 'x': x, 'y': y, 'x0': x0, 'y0': y0 }) return tiles def _tissue_ratio(self, tile: np.ndarray) -> float: """Отношение пикселей ткани к фону через HSV-маску""" hsv = np.array(Image.fromarray(tile).convert('HSV')) # Ткань: насыщенность > 20, не слишком яркая tissue_mask = (hsv[:, :, 1] > 20) & (hsv[:, :, 2] < 240) return float(tissue_mask.mean()) 

Библиотека OpenSlide поддерживает все основные форматы WSI. Это критично для интеграции в существующую лабораторную инфраструктуру.

Почему MIL — стандарт для цифровой патологии?

MIL лучше классификации на уровне тайлов примерно в 3 раза по точности при одинаковом объёме размеченных данных. AttentionMIL (Ilse et al.) — де-факто бейзлайн. Мы используем pathology-pretrained энкодеры: UNI или CONCH, обученные на миллионах патологических патчей. Это даёт +5–10% AUC по сравнению с ImageNet-весами.

import torch import torch.nn as nn import timm class AttentionMIL(nn.Module): """ Attention-based Multiple Instance Learning (Ilse et al.). Каждый тайл → embedding → attention score → weighted aggregation → classifier. """ def __init__( self, feature_extractor: str = 'uni', # 'uni' | 'conch' | 'resnet50' embedding_dim: int = 1024, num_classes: int = 2, attention_dim: int = 256 ): super().__init__() # Feature extractor — лучше использовать pathology-pretrained # UNI (MahmoodLab) или CONCH — обученные на миллионах патопатч if feature_extractor in ('uni', 'conch'): # Загружается через Hugging Face (требует accepted license) self.feature_extractor = self._load_pathology_foundation( feature_extractor ) else: backbone = timm.create_model( feature_extractor, pretrained=True, num_classes=0 ) self.feature_extractor = backbone # Attention mechanism self.attention = nn.Sequential( nn.Linear(embedding_dim, attention_dim), nn.Tanh(), nn.Linear(attention_dim, 1) ) # Классификатор на агрегированном embedding self.classifier = nn.Sequential( nn.Linear(embedding_dim, 256), nn.ReLU(), nn.Dropout(0.25), nn.Linear(256, num_classes) ) def forward( self, tile_features: torch.Tensor # (N, embedding_dim) — предвычисленные ) -> tuple[torch.Tensor, torch.Tensor]: """ Возвращает (logits, attention_scores). attention_scores — для визуализации внимания на WSI. """ # Attention weights A = self.attention(tile_features) # (N, 1) A = torch.softmax(A, dim=0) # нормализация по тайлам # Взвешенная агрегация aggregated = (A * tile_features).sum(dim=0, keepdim=True) # (1, dim) logits = self.classifier(aggregated) return logits, A.squeeze() def _load_pathology_foundation(self, name: str) -> nn.Module: # Placeholder — реальная загрузка через Hugging Face Hub raise NotImplementedError( f'Load {name} from Hugging Face: ' f'MahmoodLab/{name}' ) 

Как визуализация внимания помогает патологу?

Heatmap внимания — ключевой инструмент интерпретируемости. Мы проецируем attention scores обратно на WSI, получая цветную карту, которая указывает на наиболее значимые участки. Патолог может сверить подозрительные области и принять решение. Это снижает время анализа на 40% и минимизирует субъективность.

def create_attention_heatmap( slide: openslide.OpenSlide, tile_coords: list[tuple], # [(x, y), ...] в пикселях level-0 attention_scores: np.ndarray, # нормализованные attention weights tile_size: int, downsample: int = 32 # уменьшение для отображения ) -> np.ndarray: """ Проецируем attention scores обратно на WSI → heatmap. """ W, H = slide.dimensions heatmap = np.zeros((H // downsample, W // downsample), dtype=np.float32) for (x, y), score in zip(tile_coords, attention_scores): x_d = x // downsample y_d = y // downsample size_d = tile_size // downsample heatmap[y_d:y_d+size_d, x_d:x_d+size_d] = float(score) # Наложение на превью WSI thumbnail = np.array( slide.get_thumbnail((W // downsample, H // downsample)) ) heatmap_colored = cv2.applyColorMap( (heatmap * 255).astype(np.uint8), cv2.COLORMAP_JET ) overlay = cv2.addWeighted(thumbnail, 0.6, heatmap_colored, 0.4, 0) return overlay 
Предобученные модели UNI и CONCH подробнее UNI и CONCH — foundation модели от MahmoodLab, обученные на >100 000 WSI из TCGA и других источников. Они доступны через Hugging Face Hub по лицензии, требующей принятия условий. Использование таких энкодеров даёт значительный прирост точности по сравнению с ResNet-50: в наших проектах AUC поднимался с 0.91 до 0.97.

Этапы внедрения AI-системы

Внедрение проходит в пять шагов:

  1. Анализ данных — сбор и ревизия ваших WSI-архивов, определение форматов, проверка качества сканов.
  2. Разметка и подготовка — выделение референсных срезов, создание тестовой выборки, аугментация.
  3. Обучение модели — выбор архитектуры (MIL, сегментация), fine-tuning pathology-pretrained энкодеров.
  4. Валидация и тестирование — оценка на отложенной выборке, построение ROC-кривых, расчёт метрик.
  5. Интеграция и деплой — развёртывание в вашей инфраструктуре, API для LIS, обучение персонала.

Что входит в работу

Компонент Описание
Тайлинг WSI Нарезка, фильтрация фона, многомасштабное представление
MIL-модель AttentionMIL с pathology-pretrained энкодером
Heatmap внимания Проекция attention scores, наложение на WSI
API для интеграции REST/gRPC, поддержка DICOM, интеграция с LIS
Обучение персонала 2-дневный воркшоп для патологов и IT-отдела
Гарантия качества AUC ≥ 0.95 на валидационной выборке, документация

Сроки и как заказать

Задача Срок
MIL-классификатор на готовых WSI 5–8 недель
Система с сегментацией тканей + клеточным анализом 12–20 недель
Клинически валидированная система (CE IVD) 30–60 недель

Стоимость рассчитывается индивидуально под ваш датасет и требования. Оценим проект в течение 3 рабочих дней — просто свяжитесь с нами. Мы работаем более 5 лет в AI для медицины, выполнили 20+ проектов по цифровой патологии. Предоставляем гарантию на обученную модель и поддержку после внедрения.

Не откладывайте автоматизацию: патологи перегружены, каждая минута на ручном анализе — это риск ошибки. Свяжитесь с нами, и мы покажем, как AI может сократить время диагностики на 40%. Закажите разработку AI-системы уже сегодня — получите консультацию AI-инженера: мы поможем подобрать архитектуру под ваши задачи.