В этом примере показано, как обучить 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 извлекает случайные закрашенные фигуры из изображений основной истины и соответствующих данных о пиксельных метках. Исправление является общим методом, чтобы предотвратить исчерпывание памяти когда обучение с произвольно большими объемами.
Создайте imageDatastore
сохранить 3-D данные изображения. Поскольку формат MAT-файла является нестандартным форматом изображения, необходимо использовать читателя MAT-файла, чтобы позволить читать данные изображения. Можно использовать читателя MAT-файла помощника, matRead
Эта функция присоединена к примеру как вспомогательный файл.
volReader = @(x) matRead(x); volLoc = fullfile(preprocessDataLoc,'imagesTr'); volds = imageDatastore(volLoc, ... 'FileExtensions','.mat','ReadFcn',volReader);
Создайте pixelLabelDatastore
(Computer Vision Toolbox), чтобы сохранить метки.
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;
Увеличьте данные об обучении и валидации при помощи transform
функция с пользовательскими операциями предварительной обработки, заданными помощником, функционирует augmentAndCrop3dPatch
Эта функция присоединена к примеру как вспомогательный файл.
augmentAndCrop3dPatch
функция выполняет эти операции:
Случайным образом вращайте и отразите обучающие данные, чтобы сделать обучение более устойчивым. Функция не вращает или отражает данные о валидации.
Обрежьте закрашенные фигуры ответа к выходному размеру сети, 44 44 44 вокселями.
dataSource = 'Training'; dsTrain = transform(patchds,@(patchIn)augmentAndCrop3dPatch(patchIn,dataSource)); dataSource = 'Validation'; dsVal = transform(dsVal,@(patchIn)augmentAndCrop3dPatch(patchIn,dataSource));
Этот пример использует 3-D сеть U-Net [1]. В U-Net начальные серии сверточных слоев вкраплены макс. слоями объединения, последовательно уменьшив разрешение входного изображения. Эти слои сопровождаются серией сверточных слоев, вкрапленных повышающей дискретизацией операторов, последовательно увеличивая разрешение входного изображения. Слой нормализации партии. введен перед каждым слоем ReLU. U-Net имени прибывает из того, что сеть может чертиться с симметричной формой как буква U.
Создайте 3-D сеть U-Net по умолчанию при помощи unetLayers
(Computer Vision Toolbox) функция. Задайте две сегментации класса. Также задайте допустимое дополнение свертки, чтобы избежать артефактов границы при использовании стратегии мозаики перекрытия предсказания тестовых объемов.
inputPatchSize = [132 132 132 4]; numClasses = 2; [lgraph,outPatchSize] = unet3dLayers(inputPatchSize,numClasses,'ConvolutionPadding','valid');
Чтобы лучше сегментировать меньшие области опухоли и уменьшать влияние больших фоновых областей памяти, этот пример использует dicePixelClassificationLayer
(Computer Vision Toolbox). Замените слой классификации пикселей на слой классификации пикселей 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
(Computer Vision Toolbox) функция, и затем повторно комбинирует закрашенные фигуры.
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
Processing test volume 1 Processing test volume 2 Processing test volume 3 Processing test volume 4 Processing test volume 5
Выберите одно из тестовых изображений, чтобы оценить точность семантической сегментации. Извлеките первую модальность из 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)])
Average Dice score of background across 5 test volumes = 0.9993
meanDiceTumor = mean(diceResult(:,2)); disp(['Average Dice score of tumor across ',num2str(j), ... ' test volumes = ',num2str(meanDiceTumor)])
Average Dice score of tumor across 5 test volumes = 0.9585
Рисунок показывает 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.
imageDatastore
| randomPatchExtractionDatastore
| transform
| dicePixelClassificationLayer
(Computer Vision Toolbox) | pixelLabelDatastore
(Computer Vision Toolbox) | semanticseg
(Computer Vision Toolbox) | trainingOptions
(Deep Learning Toolbox) | trainNetwork
(Deep Learning Toolbox)