3-D сегментация опухоли головного мозга Используя глубокое обучение

В этом примере показано, как обучить 3-D нейронную сеть U-Net и выполнить семантическую сегментацию опухолей головного мозга от 3-D медицинских изображений.

Семантическая сегментация вовлекает маркировку каждого пикселя в изображение или воксель 3-D объема с классом. Этот пример иллюстрирует использование методов глубокого обучения, чтобы выполнить бинарную семантическую сегментацию опухолей головного мозга в сканах магнитно-резонансной томографии (MRI). В этой бинарной сегментации каждый пиксель помечен как опухоль или фон.

Этот пример выполняет сегментацию опухоли головного мозга с помощью 3-D архитектуры U-Net [1]. U-Net является быстрой, эффективной и простой сетью, которая стала популярной в области семантической сегментации.

Одна проблема медицинской сегментации изображений является объемом памяти, должен был сохранить и процесс 3-D объемы. Обучение сети на полном входном объеме непрактично из-за ограничений ресурсов графического процессора. Этот пример решает задачу путем обучения сети на закрашенных фигурах изображений. Пример использует стратегию мозаики перекрытия сшить тестовые закрашенные фигуры в полный сегментированный тестовый объем. Пример избегает артефактов границы при помощи допустимой части свертки в нейронной сети [5].

Вторая проблема медицинской сегментации изображений является неустойчивостью класса в данных, которые препятствуют обучению при использовании обычной потери перекрестной энтропии. Этот пример решает задачу при помощи взвешенного мультикласса функция Dice Loss [4]. Взвешивание классов помогает противостоять влиянию более крупных областей на счете Dice, облегчающем для сети изучить, как сегментировать меньшие области.

Загрузите обучение, валидацию и тестовые данные

Этот пример использует набор данных BraTS [2]. Набор данных BraTS содержит сканы MRI опухолей головного мозга, а именно, глиом, которые являются наиболее распространенной первичной мозговой зловредностью. Размер файла данных составляет ~7 Гбайт. Если вы не хотите загружать набор данных BraTS, то перейдите непосредственно к разделу Download Pretrained Network и Sample Test Set в этом примере.

Создайте директорию, чтобы сохранить набор данных BraTS.

imageDir = fullfile(tempdir,'BraTS');
if ~exist(imageDir,'dir')
    mkdir(imageDir);
end

Чтобы загрузить данные BraTS, перейдите к Медицинскому веб-сайту Десятиборья Сегментации и щелкните по ссылке "Download Data". Загрузите файл [3] "Task01_BrainTumour.tar". Разархивируйте файл TAR в директорию, заданную imageDir переменная. Когда разархивировано успешно, imageDir будет содержать директорию под названием Task01_BrainTumour это имеет три подкаталога: imagesTr, imagesTs, и labelsTr.

Набор данных содержит 750 4-D объемов, каждый представляющий стек 3-D изображений. Каждый 4-D объем имеет размер 240 240 155 4, где первые три измерения соответствуют высоте, ширине и глубине 3-D объемного изображения. Четвертая размерность соответствует различной модальности скана. Набор данных разделен на 484 учебных объема с метками вокселя и 266 тестовых объемов, тестовые объемы не имеют меток, таким образом, этот пример не использует тестовые данные. Вместо этого пример разделяет 484 учебных объема в три независимых набора, которые используются для обучения, валидации и тестирования.

Предварительно обработайте данные об обучении и валидации

Чтобы обучить 3-D сеть U-Net более эффективно, предварительно обработайте данные MRI с помощью функции помощника preprocessBraTSdatasetЭта функция присоединена к примеру как вспомогательный файл.

Функция помощника выполняет эти операции:

  • Обрежьте данные в область, содержащую, в основном, мозг и опухоль. Обрезка данных уменьшает размер данных при сохранении самой критической части каждого объема MRI и его соответствующих меток.

  • Нормируйте каждую модальность каждого объема независимо путем вычитания среднего значения и деления на стандартное отклонение обрезанного отдела головного мозга.

  • Разделите 484 учебных объема в 400 обучения, 29 валидаций и 55 наборов тестов.

Предварительная обработка данных может занять приблизительно 30 минут, чтобы завершиться.

sourceDataLoc = [imageDir filesep 'Task01_BrainTumour'];
preprocessDataLoc = fullfile(tempdir,'BraTS','preprocessedDataset');
preprocessBraTSdataset(preprocessDataLoc,sourceDataLoc);

Создайте случайный Datastore экстракции закрашенной фигуры для обучения и валидации

Используйте случайный datastore экстракции закрашенной фигуры, чтобы накормить обучающими данными сеть и подтвердить процесс обучения. Этот datastore извлекает случайные закрашенные фигуры из изображений основной истины и соответствующих данных о пиксельных метках. Исправление является общим методом, чтобы предотвратить исчерпывание памяти когда обучение с произвольно большими объемами.

Создайте imageDatastore сохранить 3-D данные изображения. Поскольку формат MAT-файла является нестандартным форматом изображения, необходимо использовать читателя MAT-файла, чтобы позволить читать данные изображения. Можно использовать читателя MAT-файла помощника, matReadЭта функция присоединена к примеру как вспомогательный файл.

volReader = @(x) matRead(x);
volLoc = fullfile(preprocessDataLoc,'imagesTr');
volds = imageDatastore(volLoc, ...
    'FileExtensions','.mat','ReadFcn',volReader);

Создайте pixelLabelDatastore сохранить метки.

lblLoc = fullfile(preprocessDataLoc,'labelsTr');
classNames = ["background","tumor"];
pixelLabelID = [0 1];
pxds = pixelLabelDatastore(lblLoc,classNames,pixelLabelID, ...
    'FileExtensions','.mat','ReadFcn',volReader);

Предварительно просмотрите один объем изображений и метку. Отобразите помеченный объем с помощью labelvolshow функция. Сделайте фон полностью прозрачным путем установки видимости фоновой метки (1) к 0.

volume = preview(volds);
label = preview(pxds);

viewPnl = uipanel(figure,'Title','Labeled Training Volume');
hPred = labelvolshow(label,volume(:,:,:,1),'Parent',viewPnl, ...
    'LabelColor',[0 0 0;1 0 0]);
hPred.LabelVisibility(1) = 0;

Создайте randomPatchExtractionDatastore это содержит учебное изображение и данные о пиксельных метках. Задайте размер закрашенной фигуры 132 132 132 вокселями. Задайте 'PatchesPerImage' извлекать 16 случайным образом расположенных закрашенных фигур из каждой пары объемов и меток во время обучения. Задайте мини-пакет размером 8.

patchSize = [132 132 132];
patchPerImage = 16;
miniBatchSize = 8;
patchds = randomPatchExtractionDatastore(volds,pxds,patchSize, ...
    'PatchesPerImage',patchPerImage);
patchds.MiniBatchSize = miniBatchSize;

Выполните те же шаги, чтобы создать randomPatchExtractionDatastore это содержит изображение валидации и данные о пиксельных метках. Можно использовать данные о валидации, чтобы оценить, учится ли сеть постоянно, underfitting, или сверхсоответствует, в то время как время прогрессирует.

volLocVal = fullfile(preprocessDataLoc,'imagesVal');
voldsVal = imageDatastore(volLocVal, ...
    'FileExtensions','.mat','ReadFcn',volReader);

lblLocVal = fullfile(preprocessDataLoc,'labelsVal');
pxdsVal = pixelLabelDatastore(lblLocVal,classNames,pixelLabelID, ...
    'FileExtensions','.mat','ReadFcn',volReader);

dsVal = randomPatchExtractionDatastore(voldsVal,pxdsVal,patchSize, ...
    'PatchesPerImage',patchPerImage);
dsVal.MiniBatchSize = miniBatchSize;

Настройте 3-D слои U-Net

Этот пример использует 3-D сеть U-Net [1]. В U-Net начальные серии сверточных слоев вкраплены макс. слоями объединения, последовательно уменьшив разрешение входного изображения. Эти слои сопровождаются серией сверточных слоев, вкрапленных повышающей дискретизацией операторов, последовательно увеличивая разрешение входного изображения. Слой нормализации партии. введен перед каждым слоем ReLU. U-Net имени прибывает из того, что сеть может чертиться с симметричной формой как буква U.

Создайте 3-D сеть U-Net по умолчанию при помощи unetLayers функция. Задайте две сегментации класса. Также задайте допустимое дополнение свертки, чтобы избежать артефактов границы при использовании стратегии мозаики перекрытия предсказания тестовых объемов.

numChannels = 4;
inputPatchSize = [patchSize numChannels];
numClasses = 2;
[lgraph,outPatchSize] = unet3dLayers(inputPatchSize,numClasses,'ConvolutionPadding','valid');

Увеличьте данные об обучении и валидации при помощи transform функция с пользовательскими операциями предварительной обработки, заданными помощником, функционирует augmentAndCrop3dPatchЭта функция присоединена к примеру как вспомогательный файл.

augmentAndCrop3dPatch функция выполняет эти операции:

  1. Случайным образом вращайте и отразите обучающие данные, чтобы сделать обучение более устойчивым. Функция не вращает или отражает данные о валидации.

  2. Обрежьте закрашенные фигуры ответа к выходному размеру сети, 44 44 44 вокселями.

dataSource = 'Training';
dsTrain = transform(patchds,@(patchIn)augmentAndCrop3dPatch(patchIn,outPatchSize,dataSource));

dataSource = 'Validation';
dsVal = transform(dsVal,@(patchIn)augmentAndCrop3dPatch(patchIn,outPatchSize,dataSource));

Чтобы лучше сегментировать меньшие области опухоли и уменьшать влияние больших фоновых областей памяти, этот пример использует dicePixelClassificationLayer. Замените слой классификации пикселей на слой классификации пикселей Dice.

outputLayer = dicePixelClassificationLayer('Name','Output');
lgraph = replaceLayer(lgraph,'Segmentation-Layer',outputLayer);

Данные были уже нормированы в разделе Preprocess Training и Validation Data этого примера. Нормализация данных в image3dInputLayer (Deep Learning Toolbox) является ненужным, так замените входной слой на входной слой, который не имеет нормализации данных.

inputLayer = image3dInputLayer(inputPatchSize,'Normalization','none','Name','ImageInputLayer');
lgraph = replaceLayer(lgraph,'ImageInputLayer',inputLayer);

В качестве альтернативы можно изменить 3-D сеть U-Net при помощи Приложения Deep Network Designer от Deep Learning Toolbox™.

Постройте график обновленной 3-D сети U-Net.

analyzeNetwork(lgraph)

Задайте опции обучения

Обучите сеть с помощью adam решатель оптимизации. Задайте установки гиперпараметров с помощью trainingOptions (Deep Learning Toolbox) функция. Начальная скорость обучения установлена в 5e-4 и постепенно уменьшается по промежутку обучения. Можно экспериментировать с MiniBatchSize свойство на основе вашей памяти графического процессора. Чтобы максимизировать использование памяти графического процессора, одобрите большие входные закрашенные фигуры свыше большого пакетного размера. Обратите внимание на то, что слои нормализации партии. являются менее эффективными для меньших значений MiniBatchSize. Настройте начальную скорость обучения на основе MiniBatchSize.

options = trainingOptions('adam', ...
    'MaxEpochs',50, ...
    'InitialLearnRate',5e-4, ...
    'LearnRateSchedule','piecewise', ...
    'LearnRateDropPeriod',5, ...
    'LearnRateDropFactor',0.95, ...
    'ValidationData',dsVal, ...
    'ValidationFrequency',400, ...
    'Plots','training-progress', ...
    'Verbose',false, ...
    'MiniBatchSize',miniBatchSize);

Загрузите предварительно обученную сеть и демонстрационный набор тестов

Загрузите предварительно обученную версию 3-D U-Net и пяти демонстрационных тестовых объемов и их соответствующих меток от набора данных BraTS [3]. Предварительно обученная модель и выборочные данные позволяют вам выполнить сегментацию на тестовых данных, не загружая полный набор данных или ожидая сети, чтобы обучаться.

trained3DUnet_url = 'https://www.mathworks.com/supportfiles/vision/data/brainTumor3DUNetValid.mat';
sampleData_url = 'https://www.mathworks.com/supportfiles/vision/data/sampleBraTSTestSetValid.tar.gz';

imageDir = fullfile(tempdir,'BraTS');
if ~exist(imageDir,'dir')
    mkdir(imageDir);
end

downloadTrained3DUnetSampleData(trained3DUnet_url,sampleData_url,imageDir);

Обучение сети

По умолчанию пример загружает предварительно обученную 3-D сеть U-Net. Предварительно обученная сеть позволяет вам запустить целый пример, не ожидая обучения завершиться.

Чтобы обучить сеть, установите doTraining переменная в следующем коде к true. Обучите модель с помощью trainNetwork (Deep Learning Toolbox) функция.

Обучайтесь на графическом процессоре, если вы доступны. Используя графический процессор требует Parallel Computing Toolbox™, и CUDA® включил NVIDIA® графический процессор. Для получения дополнительной информации смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox). Обучение занимает приблизительно 30 часов в системе мультиграфического процессора с 4 Титанами NVIDIA™ Xp графические процессоры и может взять еще дольше в зависимости от вашего оборудования графического процессора.

doTraining = false;
if doTraining
    modelDateTime = string(datetime('now','Format',"yyyy-MM-dd-HH-mm-ss"));
    [net,info] = trainNetwork(dsTrain,lgraph,options);
    save(strcat("trained3DUNet-",modelDateTime,"-Epoch-",num2str(options.MaxEpochs),".mat"),'net');
else
    inputPatchSize = [132 132 132 4];
    outPatchSize = [44 44 44 2];
    load(fullfile(imageDir,'trained3DUNet','brainTumor3DUNetValid.mat'));
end

Выполните сегментацию тестовых данных

Графический процессор настоятельно рекомендован для выполнения семантической сегментации объемов изображений (требует Parallel Computing Toolbox™).

Выберите источник тестовых данных, который содержит объемы основной истины и метки для тестирования. Если вы сохраняете useFullTestSet переменная в следующем коде как false, затем пример использует пять объемов для тестирования. Если вы устанавливаете useFullTestSet переменная к true, затем пример использует 55 тестовых изображений, выбранных от полного набора данных.

useFullTestSet = false;
if useFullTestSet
    volLocTest = fullfile(preprocessDataLoc,'imagesTest');
    lblLocTest = fullfile(preprocessDataLoc,'labelsTest');
else
    volLocTest = fullfile(imageDir,'sampleBraTSTestSetValid','imagesTest');
    lblLocTest = fullfile(imageDir,'sampleBraTSTestSetValid','labelsTest');
    classNames = ["background","tumor"];
    pixelLabelID = [0 1];
end

voldsTest переменная хранит тестовые изображения основной истины. pxdsTest переменная хранит метки основной истины.

volReader = @(x) matRead(x);
voldsTest = imageDatastore(volLocTest, ...
    'FileExtensions','.mat','ReadFcn',volReader);
pxdsTest = pixelLabelDatastore(lblLocTest,classNames,pixelLabelID, ...
    'FileExtensions','.mat','ReadFcn',volReader);

Используйте стратегию мозаики перекрытия предсказать метки для каждого тестового объема. Каждый тестовый объем дополнен, чтобы сделать входное кратное размера выходному размеру сети и компенсирует эффекты допустимой свертки. Алгоритм мозаики перекрытия выбирает перекрывающиеся закрашенные фигуры, предсказывает метки для каждой закрашенной фигуры при помощи semanticseg функция, и затем повторно комбинирует закрашенные фигуры.

id = 1;
while hasdata(voldsTest)
    disp(['Processing test volume ' num2str(id)]);
    
    tempGroundTruth = read(pxdsTest);
    groundTruthLabels{id} = tempGroundTruth{1};
    vol{id} = read(voldsTest);
    
    % Use reflection padding for the test image. 
    % Avoid padding of different modalities.
    volSize = size(vol{id},(1:3));
    padSizePre  = (inputPatchSize(1:3)-outPatchSize(1:3))/2;
    padSizePost = (inputPatchSize(1:3)-outPatchSize(1:3))/2 + (outPatchSize(1:3)-mod(volSize,outPatchSize(1:3)));
    volPaddedPre = padarray(vol{id},padSizePre,'symmetric','pre');
    volPadded = padarray(volPaddedPre,padSizePost,'symmetric','post');
    [heightPad,widthPad,depthPad,~] = size(volPadded);
    [height,width,depth,~] = size(vol{id});
    
    tempSeg = categorical(zeros([height,width,depth],'uint8'),[0;1],classNames);
    
    % Overlap-tile strategy for segmentation of volumes.
    for k = 1:outPatchSize(3):depthPad-inputPatchSize(3)+1
        for j = 1:outPatchSize(2):widthPad-inputPatchSize(2)+1
            for i = 1:outPatchSize(1):heightPad-inputPatchSize(1)+1
                patch = volPadded( i:i+inputPatchSize(1)-1,...
                    j:j+inputPatchSize(2)-1,...
                    k:k+inputPatchSize(3)-1,:);
                patchSeg = semanticseg(patch,net);
                tempSeg(i:i+outPatchSize(1)-1, ...
                    j:j+outPatchSize(2)-1, ...
                    k:k+outPatchSize(3)-1) = patchSeg;
            end
        end
    end
    
    % Crop out the extra padded region.
    tempSeg = tempSeg(1:height,1:width,1:depth);

    % Save the predicted volume result.
    predictedLabels{id} = tempSeg;
    id=id+1;
end

Сравните основную истину с сетевым предсказанием

Выберите одно из тестовых изображений, чтобы оценить точность семантической сегментации. Извлеките первую модальность из 4-D объемных данных и сохраните этот 3-D объем в переменной vol3d.

volId = 1;
vol3d = vol{volId}(:,:,:,1);

Отобразите в монтаже центральный срез основной истины и предсказанных меток вдоль направления глубины.

zID = size(vol3d,3)/2;
zSliceGT = labeloverlay(vol3d(:,:,zID),groundTruthLabels{volId}(:,:,zID));
zSlicePred = labeloverlay(vol3d(:,:,zID),predictedLabels{volId}(:,:,zID));

figure
montage({zSliceGT,zSlicePred},'Size',[1 2],'BorderSize',5) 
title('Labeled Ground Truth (Left) vs. Network Prediction (Right)')

Отобразите основную истину помеченный объем с помощью labelvolshow функция. Сделайте фон полностью прозрачным путем установки видимости фоновой метки (1) к 0. Поскольку опухоль в мозговой ткани, сделайте некоторые мозговые воксели прозрачными, так, чтобы опухоль отобразилась. Чтобы сделать некоторые мозговые воксели прозрачными, задайте порог объема как номер в области значений [0, 1]. Вся нормированная интенсивность объема ниже этого порогового значения полностью прозрачна. Этот пример устанавливает порог объема как меньше чем 1 так, чтобы некоторые мозговые пиксели остались видимыми, чтобы дать контекст пространственному местоположению опухоли в мозгу.

viewPnlTruth = uipanel(figure,'Title','Ground-Truth Labeled Volume');
hTruth = labelvolshow(groundTruthLabels{volId},vol3d,'Parent',viewPnlTruth, ...
    'LabelColor',[0 0 0;1 0 0],'VolumeThreshold',0.68);
hTruth.LabelVisibility(1) = 0;

Для того же объема отобразите предсказанные метки.

viewPnlPred = uipanel(figure,'Title','Predicted Labeled Volume');
hPred = labelvolshow(predictedLabels{volId},vol3d,'Parent',viewPnlPred, ...
    'LabelColor',[0 0 0;1 0 0],'VolumeThreshold',0.68);
hPred.LabelVisibility(1) = 0;

Это изображение показывает результат отображающихся срезов последовательно через тот объема. Помеченная основная истина слева, и сетевое предсказание справа.

Определите количество точности сегментации

Измерьте точность сегментации с помощью dice функция. Эта функция вычисляет коэффициент подобия Dice между сегментациями основной истины и предсказанным.

diceResult = zeros(length(voldsTest.Files),2);

for j = 1:length(vol)
    diceResult(j,:) = dice(groundTruthLabels{j},predictedLabels{j});
end

Вычислите средний счет Dice через набор тестовых объемов.

meanDiceBackground = mean(diceResult(:,1));
disp(['Average Dice score of background across ',num2str(j), ...
    ' test volumes = ',num2str(meanDiceBackground)])
meanDiceTumor = mean(diceResult(:,2));
disp(['Average Dice score of tumor across ',num2str(j), ...
    ' test volumes = ',num2str(meanDiceTumor)])

Рисунок показывает boxplot (Statistics and Machine Learning Toolbox), который визуализирует статистику о баллах Dice через набор пяти демонстрационных тестовых объемов. Красные линии в графике показывают среднее значение Dice для классов. Верхние и нижние границы синего поля указывают на 25-е и 75-е процентили, соответственно. Черные контактные усики расширяют к самым экстремальным точкам данных, не рассмотренным выбросами.

Если у вас есть Statistics and Machine Learning Toolbox™, то можно использовать boxplot функция, чтобы визуализировать статистику о баллах Dice через все ваши тестовые объемы. Создать boxplot, установите createBoxplot переменная в следующем коде к true.

createBoxplot = false;
if createBoxplot
    figure
    boxplot(diceResult)
    title('Test Set Dice Accuracy')
    xticklabels(classNames)
    ylabel('Dice Coefficient')
end

Ссылки

[1] Çiçek, Ö., А. Абдулкадир, С. С. Линкамп, Т. Брокс и О. Роннебергер. "3D U-Net: Изучение Плотной Объемной Сегментации из Разреженной Аннотации". В Продолжениях Международной конференции по вопросам Медицинского Вычисления Изображений и Машинного Вмешательства - MICCAI 2016. Афины, Греция, октябрь 2016, стр 424-432.

[2] Isensee, F., П. Кикинджередер, W. Фитиль, М. Бендсзус и К. Х. Майер-Хейн. "Сегментация Опухоли головного мозга и Предсказание Выживания Radiomics: Вклад в проблему BRATS 2017". В Продолжениях BrainLes: Международный Семинар MICCAI Brainlesion. Квебек-Сити, Канада, сентябрь 2017, стр 287-297.

[3] "Мозговые Опухоли". Медицинское Десятиборье Сегментации. http://medicaldecathlon.com/

Набор данных BraTS обеспечивается Медицинским Десятиборьем Сегментации в соответствии с лицензией CC-BY-SA 4.0. От всех гарантий и представлений отказываются; см. лицензию на детали. MathWorks® изменил набор данных, соединенный в разделе Download Pretrained Network и Sample Test Set этого примера. Модифицированный демонстрационный набор данных был обрезан в область, содержащую, в основном, мозг и опухоль, и каждый канал был нормирован независимо путем вычитания среднего значения и деления на стандартное отклонение обрезанного отдела головного мозга.

[4] Sudre, C. H. В. Ли, Т. Веркотерен, С. Аурселин и М. Х. Кардозу. "Обобщенное Перекрытие Dice как Функция потерь Глубокого обучения для Очень Несбалансированных Сегментаций". Глубокое обучение в Медицинском Анализе изображения и Многомодальном Изучении для Клинической Поддержки принятия решений: Семинар Третьего Интернационала. Квебек-Сити, Канада, сентябрь 2017, стр 240-248.

[5] Ronneberger, O., П. Фишер и Т. Брокс. "Сети U-Net:Convolutional для Биомедицинской Сегментации Изображений". В Продолжениях Международной конференции по вопросам Медицинского Вычисления Изображений и Машинного Вмешательства - MICCAI 2015. Мюнхен, Германия, октябрь 2015, стр 234-241. Доступный в arXiv:1505.04597.

Смотрите также

| (Deep Learning Toolbox) | (Deep Learning Toolbox) | | | | |

Похожие темы