Loading repository data…
Loading repository data…
amirassov / repository
Данный репозиторий содержит мое решение конкурса Data-Science-Bowl-2018
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
Первый этап конкурса закончился. Сейчас готовлю предсказания для данных второго этапа (3016 изображений).
Данный репозиторий содержит мое решение конкурса Data-Science-Bowl-2018.
Задача конкурса заключается в обнаружении ядер в гистологических изображениях. Организаторы утверждают, что обнаружение ядер клеток позволит исследователям идентифицировать каждую отдельную клетку и измерить ее реакцию на различные методы лечения.
Обучающая выборка содержит 664 изображений, а тестовая 67. Ниже представлены примеры изображений из обучающей выборки:
Видно, что изображения имеют разные оттенки цвета. Поэтому изображения, у которых цвет фона розовый или белый, были инвертированы. Для этого я использовал простое эвристическое правило:
if np.mean(image[..., 0]) > 100:
image = 255 - image
Все изображения были масштабированы так,
чтобы медиана площадей (количество пикселей) клеток на изображении была равна 250.
Для изображений из обучающей выборки известны площади клеток, а для тестовой выборки нет. Поэтому я использовал следующий алгоритм:
Для решения задач данного типа популярны две архитектуры нейронной сети:
Из соображений простоты и работоспособности в данной задаче была выбрана архитектура UNet, которая решает задачу бинарной сегментации.
В работе TernausNet: U-Net with VGG11 Encoder Pre-Trained on ImageNet for Image Segmentation
было показано, что использование предобученной нейронной сети в качестве энкодера для UNet улучшает качество алгоритма. Поэтому будем использовать UNet с предобученным энкодером на наборе данных ImageNet.
В качестве энкодеров будем использовать Resnet34 и VGG11.
В качестве функции ошибок использовались следующие функции:
BceLogDice = bce - log(dice)BceDice = bce - diceНейронная сеть обучалась на случайных кропах размера 256 X 256. Изображения меньшего размера были дополнены до нужного размера зеркальным отражением границ.
В качестве преобразований были выбраны следующие операции: VerticalFlip, HorizontalFlip, Transpose, ShiftScaleRotate, Distort, RandomBrightness, RandomContrast.
Мы имеем изображения разных оттенков.
Поэтому выборка была разбита на две части в пропорции 597/67 на обучающую и валидационную выборку так,
чтобы изображения разных оттенков присутствовали примерно в такой же пропорции, как в размеченной и тестовой выборке.
На валидационной выборке подбирались параметры нейронной сети и алгоритма постобработки. После того, как были выбраны подходящие параметры, я обучал модели на всех изображениях.
Все модели обучались по следующему принципу:
learning_rate (примерно 0.0003) до выхода на плато (примерно 90 эпох)cyclic learning rate, то есть начиная с какого-то большого learning_rate спускаемся внизlearning_rate и верхнюю границу cyclic learning rate700), то возвращаемся к шагу 1.Ниже представлен график зависимости learning_rate от номера эпохи для одной из моделей:
Тестовые изображения дополнялись до нужного размера (высота и широта кратно 64) зеркальным отражением границ и пропускались через нейронную сеть батчами размера 1.
Для предсказания масок использовался метод Test Time Augmentation (TTA), суть которого заключается в применении аугментаций к тестовым изображениям при формировании предсказаний.
Дальше усреднением обратных преобразований предсказанных масок получаем итоговый ответ.
UNet выдает вероятность маски, которую нужно сегментировать на отдельные ядра. В качестве алгоритма сегментации использовался watershed.
Алгоритм на вход принимает инвертированную вероятность маски, как функцию интенсивности, и маркеры, которые указывают, какие области должны быть объединены, а какие нет. Поэтому UNet-ом предсказывалась не только маска, но и центры каждого ядра.
Дальше центры были использованы, как маркеры для watershed.
Центры масок вычислялись с помощью алгоритма distance transform. Для каждого ядра:
threshold, то точка является центром.В итоге я обучил 9 моделей с архитектурой UNet с разными энкодерами, функциями ошибок и ответами (в скобках указан threshold):
| Энкодер | Ответы | Функция ошибок | Количество эпох | Размер батча | Заморозка энкодера | Качество на Public Leaderboard |
|---|---|---|---|---|---|---|
| Resnet34 | маска+центр (0.5)+граница (0.5) | BceLogDice | 589 | 16 | Да | 0.536 |
| Resnet34 | маска+центр (0.5)+центр (0.5) | BceLogDice | 689 | 16 | Да | 0.537 |
| VGG11 | маска+центр (0.5)+граница (0.5) | BceLogDice | 589 | 16 | Да | 0.535 |
| Resnet34 | маска+центр (0.5)+граница (0.5) | BceLogDice | 589 | 16 | Нет | 0.533 |
| Resnet34 | маска+центр (0.5)+граница (0.5) | BceDice | 589 | 32 | Да | 0.540 |
| VGG11 | маска+центр (0.5)+центр (0.5) | BceDice | 689 | 32 | Да | 0.535 |
| VGG11 | маска+центр (0.5)+граница (0.5) | BceDice | 689 | 32 | Да | 0.534 |
| Resnet34 | маска+центр (0.5)+граница (0.5)+центр (0.3) | BceDice | 789 | 32 | Да | 0.500 |
| VGG11 | маска+центр (0.5)+граница (0.5)+центр (0.3) | BceDice | 789 | 32 | Да | 0.529 |
Итоговый ансамбль является взвешенной суммой данных моделей с весами [0.10, 0.13, 0.13, 0.08, 0.13, 0.13, 0.12, 0.09, 0.09]. Качество ансамбля на Public Leaderboard: 0.553:
Примеры работы алгоритма на тестовых изображениях:
data_1_extra_data.ipynbthreshold=0.5) и граница: data_1_without_scale_05.ipynbthreshold=0.5) и граница: data_2_with_scale_05.ipynbthreshold = 0.5 и 0.3) : data_3_with_scale_05_03_only_centers.ipynbthreshold = 0.5 и 0.3) : data_5_with_scale_05_centers_contour.ipynbpredict_1_without_scale_predict.ipynbpredict_2_with_scale_test.ipynbpredict_3_ensemble.ipynb