exponenta event banner

Классификация изображений с большим количеством решений с помощью blockedImage и глубокое обучение

В этом примере показано, как классифицировать изображения всего слайда (WSI) с множественными разрешениями, которые не помещаются в память с помощью Inception-v3 глубокой нейронной сети.

Единственным окончательным способом диагностики рака молочной железы является изучение образцов тканей, собранных из биопсии или операции. Образцы обычно получают с окрашиванием гематоксилином и эозином (H&E) для увеличения контрастности структур в ткани. Традиционно патологи исследуют ткань на стеклянных предметах под микроскопом, чтобы обнаружить опухолевую ткань. Диагностика требует времени, так как патологи должны тщательно проверить весь слайд при близком увеличении. Кроме того, патологи могут не заметить небольших опухолей. Методы глубокого обучения направлены на автоматизацию обнаружения опухолевой ткани, экономию времени и улучшение частоты обнаружения мелких опухолей.

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

Считывание WSI является проблемой, поскольку изображения не могут быть загружены как единое целое в память и, следовательно, требуют неосновных методов обработки изображений. Этот тип большого образа с несколькими решениями можно хранить и обрабатывать с помощью blockedImage(Панель инструментов обработки изображений). Можно извлекать пакеты данных из blockedImage объекты с использованием blockedImageDatastore(Панель инструментов обработки изображений).

Этот пример показывает, как обучить сеть глубокого обучения классифицировать опухоли на очень больших изображениях с множественным разрешением с использованием blockedImage и blockedImageDatastore. В примере представлены результаты классификации в виде тепловых карт, которые показывают вероятность того, что местная ткань является опухолевой. Локализация опухолевых областей позволяет медицинским патологоанатомам исследовать конкретные области и быстро идентифицировать опухоли любого размера на изображении.

Загрузить данные обучения

В этом примере используются WSI из вызова Camelyon16 [1]. Данные этого вызова содержат в общей сложности 400 WSI лимфатических узлов из двух независимых источников, разделенных на 270 тренировочных изображений и 130 тестовых изображений. WSI хранятся в виде файлов TIF в разделенном формате с 11-уровневой структурой пирамид.

Набор тренировочных данных состоит из 159 WSI нормальных лимфатических узлов и 111 WSI лимфатических узлов с опухолью и здоровой тканью. Обычно опухолевая ткань представляет собой небольшую часть здоровой ткани. Координаты истинности земли границ поражения сопровождают изображения опухоли.

Размер каждого учебного файла составляет приблизительно 2 ГБ. Если вы не хотите загружать набор данных обучения или обучать сеть, перейдите непосредственно к разделу Train или Download the Network в этом примере.

Создайте каталог для хранения набора данных обучения.

trainingImageDir = fullfile(tempdir,'Camelyon16','training');
if ~exist(trainingImageDir,'dir')
    mkdir(trainingImageDir);
    mkdir(fullfile(trainingImageDir,'normal'));
    mkdir(fullfile(trainingImageDir,'tumor'));
    mkdir(fullfile(trainingImageDir,'lesion_annotations'));
end

trainNormalDataDir = fullfile(trainingImageDir,'normal');
trainTumorDataDir = fullfile(trainingImageDir,'tumor');
trainTumorAnnotationDir = fullfile(trainingImageDir,'lesion_annotations');

Чтобы загрузить данные обучения, перейдите на веб-сайт Camelyon17 и нажмите первую ссылку «CAMELYON16 набор данных». Откройте каталог «Обучение» и выполните следующие действия.

  • Загрузите файл «lesion_annotations.zip». Извлеките файлы в каталог, указанный trainTumorAnnotationDir переменная.

  • Откройте «обычный» каталог. Загрузите изображения в каталог, указанный trainNormalDataDir переменная.

  • Откройте каталог «опухоль». Загрузите изображения в каталог, указанный trainTumorDataDir переменная.

Укажите количество обучающих изображений. Обратите внимание, что одно из тренировочных изображений нормальной ткани, 'normal _ 144.tif', имеет метаданные, которые не могут быть прочитаны blockedImage объект. В этом примере используются оставшиеся 158 учебных файлов.

numNormalFiles = 158;
numTumorFiles = 111;

Визуализация данных обучения

Чтобы лучше понять обучающие данные, отобразите одно обучающее изображение. Поскольку загрузка всего изображения в память с максимальным разрешением невозможна, нельзя использовать традиционные функции отображения изображения, такие как imshow. Для отображения и обработки данных изображения используйте blockedImage(Панель инструментов обработки изображений).

Создать blockedImage объект из обучающего изображения опухоли.

tumorFileName = fullfile(trainTumorDataDir,'tumor_001.tif');
tumorImage = blockedImage(tumorFileName);

Проверить размеры blockedImage на каждом уровне разрешения. Уровень 1 имеет наибольшее количество пикселей и является лучшим уровнем разрешения. Уровень 10 имеет наименьшее число пикселей и является самым крупным уровнем разрешения. Соотношение сторон непротиворечиво, что указывает на то, что уровни не охватывают одну и ту же мировую зону.

levelSizeInfo = table((1:length(tumorImage.Size))', ...
    tumorImage.Size(:,1), ...
    tumorImage.Size(:,2), ...
    tumorImage.Size(:,1)./tumorImage.Size(:,2), ...
    'VariableNames',["Resolution Level" "Image Width" "Image Height" "Aspect Ratio"])
levelSizeInfo=11×4 table
    Resolution Level    Image Width    Image Height    Aspect Ratio
    ________________    ___________    ____________    ____________

            1           2.2118e+05        97792           2.2618   
            2           1.1059e+05        49152             2.25   
            3                55296        24576             2.25   
            4                27648        12288             2.25   
            5                13824         6144             2.25   
            6                 7168         3072           2.3333   
            7                 1577         3629          0.43455   
            8                 3584         1536           2.3333   
            9                 2048         1024                2   
           10                 1024          512                2   
           11                  512          512                1   

Отображение blockedImage на уровне грубого разрешения с использованием bigimageshow(Панель инструментов обработки изображений). Возврат дескриптора к bigimageshow объект. Для настройки отображения можно использовать маркер перемещения. Изображение содержит много пустого пробела. Ткань занимает лишь небольшую часть изображения.

h = bigimageshow(tumorImage,'ResolutionLevel',8);

Увеличьте изображение одной части изображения, установив горизонтальный и вертикальный пространственные границы относительно самого высокого уровня разрешения. Изображение выглядит размытым, потому что этот уровень разрешения очень грубый.

xlim([29471,29763]);
ylim([117450,118110]);

Для просмотра дополнительных сведений измените уровень разрешения на более точный.

h.ResolutionLevel = 1;

Создать маски

Объем вычислений можно уменьшить путем обработки только интересующих регионов (ROI). Используйте маску для определения ROI. Маска - это логическое изображение, в котором true пикселы представляют ROI.

Чтобы дополнительно уменьшить количество вычислений, создайте маски на уровне грубого разрешения, которые можно обрабатывать полностью в памяти, а не поблочно. Если пространственная привязка уровня грубого разрешения соответствует пространственной привязке более тонких уровней разрешения, то местоположения на уровне грубого разрешения соответствуют местоположениям на более мелких уровнях. В этом случае можно использовать грубую маску для выбора блоков для обработки на более мелких уровнях. Дополнительные сведения см. в разделах Настройка пространственных ссылок для заблокированных изображений (панель обработки изображений) и Эффективная обработка заблокированных изображений с помощью маски (панель обработки изображений).

Укажите уровень разрешения, используемый для создания маски. В этом примере используется уровень разрешения 7, который является грубым и вписывается в память. Обратите внимание, что blockedImage объект автоматически сортирует уровни в изображении с множественным разрешением от тончайшего до грубого на основе количества пикселей на каждом уровне. Несколько Camelyon16 файлов изображений содержат маску промежуточного разрешения. Этот пример игнорирует маску при определении и чтении седьмого уровня данных изображения.

resolutionLevel = 7;

Создание масок для обычных изображений

На нормальных изображениях ROI состоит из здоровой ткани. Цвет здоровой ткани отличается от цвета фона, поэтому используйте пороговое значение цвета для сегментации изображения и создания ROI. Цветовое пространство L * a * b * обеспечивает наилучшее цветоделение для сегментации. Преобразуйте изображение в цветовое пространство L * a * b *, а затем пороговое значение канала a * для создания маски ткани.

Можно использовать функцию помощника createMaskForNormalTissue для создания масок с использованием пороговых значений цвета. Эта вспомогательная функция присоединена к примеру как вспомогательный файл.

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

  • Создать blockedImage из файла изображения TIF.

  • Задание пространственных ссылок на все уровни разрешения из метаданных изображения.

  • Получите изображение на уровне грубого разрешения.

  • Преобразуйте грубое изображение в цветовое пространство L * a * b *, а затем извлеките канал a *.

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

  • Создание единого разрешения blockedImage объект из маски и устанавливают пространственную привязку маски, соответствующую пространственной привязке входного изображения.

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

trainNormalMaskDir = fullfile(trainNormalDataDir,['normal_mask_level' num2str(resolutionLevel)]);
createMaskForNormalTissue(trainNormalDataDir,trainNormalMaskDir,resolutionLevel)

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

[normalImages,normalMasks] = createBlockedImageAndMaskArrays(trainNormalDataDir,trainNormalMaskDir);

Выберите образец обычного изображения и маски. Убедитесь, что границы пространственного мира маски соответствуют границам изображения на самом высоком уровне разрешения. Границы пространственного мира определяются WorldStart и WorldEnd свойства.

idx = 2;
[normalImages(idx).WorldStart normalImages(idx).WorldEnd]
ans = 11×6
105 ×

         0         0    0.0000    2.2118    0.9779    0.0000
         0         0    0.0000    2.2118    0.9830    0.0000
         0         0    0.0000    2.2118    0.9830    0.0000
         0         0    0.0000    2.2118    0.9830    0.0000
         0         0    0.0000    2.2118    0.9830    0.0000
         0         0    0.0000    2.2938    0.9830    0.0000
    0.0000    0.0000    0.0000    2.2118    0.9779    0.0000
         0         0    0.0000    2.2938    0.9830    0.0000
         0         0    0.0000    2.6214    1.3107    0.0000
         0         0    0.0000    2.6214    1.3107    0.0000
      ⋮

[normalMasks(idx).WorldStart normalMasks(idx).WorldEnd]
ans = 1×4

           0           0      221184       97792

Убедитесь, что маска содержит правильные значения ROI и пространственные ссылки. Отображение образца изображения с помощью bigimageshow функция. Получите оси, содержащие дисплей.

figure
hNormal = bigimageshow(normalImages(idx));
hNormalAxes = hNormal.Parent;

Создание новых осей поверх отображаемых blockedImage. В новых осях отобразите соответствующее изображение маски с частичной прозрачностью. Маска выделяет области, содержащие нормальную ткань.

hMaskAxes = axes;
hMask = bigimageshow(normalMasks(idx),'Parent',hMaskAxes, ...
    'Interpolation','nearest','AlphaData',0.5);
hMaskAxes.Visible = 'off';

Свяжите оси изображения с осями маски. При зумировании и панорамировании обе оси обновляются одинаково.

linkaxes([hNormalAxes,hMaskAxes]);

Увеличьте изображение одной части изображения, задав горизонтальный и вертикальный пространственные границы. Маска правильно перекрывает нормальную ткань.

xlim([45000 80000]);
ylim([130000 165000]);

Создание масок для изображений опухолей

На опухолевых изображениях ROI состоит из опухолевой ткани. Цвет опухолевой ткани похож на цвет здоровой ткани, поэтому нельзя использовать методы сегментации цвета. Вместо этого создайте ROI, используя наземные истинные координаты границ поражения, которые сопровождают изображения опухоли.

Можно использовать функцию помощника createMaskForTumorTissue для создания маски с использованием значений ROI. Эта вспомогательная функция присоединена к примеру как вспомогательный файл.

Функция помощника выполняет эти операции на каждом тренировочном изображении опухолевой ткани:

  • Создать blockedImage из файла изображения TIF.

  • Задание пространственных ссылок из метаданных изображения.

  • Считывание соответствующих аннотаций повреждений в XML-файлах и преобразование аннотаций в многоугольники (Polygon(Панель инструментов обработки изображений)).

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

  • Создание выходной логической маски blockedImage объект на более высоком уровне разрешения. Запись изображения маски по блокам с помощью setBlock функция.

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

trainTumorMaskDir = fullfile(trainTumorDataDir,['tumor_mask_level' num2str(resolutionLevel)]);
createMaskForTumorTissue(trainTumorDataDir,trainTumorAnnotationDir, ...
    trainTumorMaskDir,resolutionLevel);

Теперь, когда изображения опухолей и маски находятся на диске, создайте blockedImage объекты для управления данными с помощью функции помощника createBlockedImageAndMaskArrays. Эта функция создает массив blockedImage объекты из изображений опухоли и соответствующий массив blockedImage объекты из изображений опухолевой маски. Вспомогательная функция прикрепляется к примеру как вспомогательный файл.

[tumorImages,tumorMasks] = createBlockedImageAndMaskArrays(trainTumorDataDir,trainTumorMaskDir);

Выберите образец изображения опухоли и маски. Убедитесь, что границы пространственного мира маски соответствуют границам изображения на самом высоком уровне разрешения. Границы пространственного мира определяются XWorldLimits и YWorldLimits свойства.

idx = 5;
[tumorImages(idx).WorldStart tumorImages(idx).WorldEnd]
ans = 11×6
105 ×

         0         0    0.0000    2.1965    0.9779    0.0000
         0         0    0.0000    2.2016    0.9830    0.0000
         0         0    0.0000    2.2118    0.9830    0.0000
         0         0    0.0000    2.2118    0.9830    0.0000
         0         0    0.0000    2.2118    0.9830    0.0000
         0         0    0.0000    2.2938    0.9830    0.0000
    0.0000    0.0000    0.0000    2.1965    0.9779    0.0000
         0         0    0.0000    2.2938    0.9830    0.0000
         0         0    0.0000    2.6214    1.3107    0.0000
         0         0    0.0000    2.6214    1.3107    0.0000
      ⋮

[tumorMasks(idx).WorldStart tumorMasks(idx).WorldEnd]
ans = 1×4

           0           0      219648       97792

Убедитесь, что маска содержит правильные значения ROI и пространственные ссылки. Отображение образца изображения с помощью bigimageshow функция. Получите оси, содержащие дисплей.

figure
hTumor = bigimageshow(tumorImages(idx));
hTumorAxes = hTumor.Parent;

Создание новых осей поверх отображаемых blockedImage. В новых осях отобразите соответствующее изображение маски с частичной прозрачностью. Маска выделяет области, содержащие нормальную ткань.

hMaskAxes = axes;
hMask = bigimageshow(tumorMasks(idx),'Parent',hMaskAxes, ...
    'Interpolation','nearest','AlphaData',0.5);
hMaskAxes.Visible = 'off';

Свяжите оси изображения с осями маски. При зумировании и панорамировании обе оси обновляются одинаково.

linkaxes([hTumorAxes,hMaskAxes]);

Увеличьте изображение одной части изображения, задав горизонтальный и вертикальный пространственные границы. Маска правильно перекрывает опухолевую ткань.

xlim([45000 65000]);
ylim([130000 150000]);

Создание заблокированных хранилищ данных изображений для обучения и проверки

Извлечение исправлений учебных данных из blockedImage объекты, используйте blockedImageDatastore(Панель инструментов обработки изображений). Это хранилище данных считывает исправления blockedImage данные на одном уровне разрешения.

Цветовой дисбаланс и дисбаланс классов в необработанных учебных патчах потенциально могут смещать сеть. Цветовой дисбаланс является результатом неравномерного окрашивания ткани. Дисбаланс класса является результатом неравного количества опухоли и нормальной ткани в данных. Для устранения этих дисбалансов можно предварительно обработать и расширить хранилище данных.

В этом примере показано, как создать blockedImageDatastore который извлекает опухоль и нормальные пластыри для обучения сети. В примере также показано, как предварительно обрабатывать и дополнять хранилища данных, чтобы избежать смещения сети.

Выберите расположение обычных патчей ткани для чтения

Случайное разделение обычных изображений и соответствующих масок на два набора. Набор проверки содержит два случайно выбранных изображения и соответствующие маски. Обучающий набор содержит оставшиеся изображения и маски.

normalValnIdx = randi(numNormalFiles,[1 2]);
normalTrainIdx = setdiff(1:numNormalFiles,normalValnIdx);

Размер сегмента мал по сравнению с размером элементов изображения. По умолчанию a blockedImageDatastore извлекает патчи без перекрытия и без зазора, что создает огромное количество обучающих патчей. Можно уменьшить объем обучающих данных, указав подмножество исправлений. Укажите координаты фрагментов с помощью команды selectBlockLocations(Панель инструментов обработки изображений). Добавление промежутка между образцами учебных патчей с помощью BlockOffsets аргумент «имя-значение». Укажите смещение, превышающее размер сегмента. Увеличьте порог включения по сравнению со значением по умолчанию, равным 0,5, чтобы сеть работала на относительно однородных исправлениях.

patchSize = [299,299,3];
normalStrideFactor = 10;
blsNormalData = selectBlockLocations(normalImages(normalTrainIdx), ...
    "BlockSize",patchSize(1:2),"BlockOffsets",patchSize(1:2)*normalStrideFactor, ...
    "Masks",normalMasks(normalTrainIdx),"InclusionThreshold",0.75,"ExcludeIncompleteBlocks",true);

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

blsNormalDataVal = selectBlockLocations(normalImages(normalValnIdx), ...
    "BlockSize",patchSize(1:2), ...
    "Masks",normalMasks(normalValnIdx),"InclusionThreshold",0.75,"ExcludeIncompleteBlocks",true);

Создание хранилищ данных для обычных изображений

Создание хранилищ данных dsNormalData и dsNormalDataVal которые считывают исправления изображения из обычных изображений на самом высоком уровне разрешения для обучения и проверки, соответственно. Укажите координаты фрагментов с помощью команды BlockLocationSet аргумент пары имя-значение.

dsNormalData = blockedImageDatastore(normalImages(normalTrainIdx), ...
    "BlockLocationSet",blsNormalData);
dsNormalDataVal = blockedImageDatastore(normalImages(normalValnIdx), ...
    "BlockLocationSet",blsNormalDataVal);

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

imagesToPreview = zeros([patchSize 10],'uint8');
for n = 1:10
    im = read(dsNormalData);
    imagesToPreview(:,:,:,n) = im{1};
end
figure
montage(imagesToPreview,'Size',[2 5],'BorderSize',10,'BackgroundColor','k');

title("Training Patches of Normal Tissue")

Выберите расположение патчей опухолевой ткани для чтения

Случайным образом разделить изображения опухоли и соответствующие маски на два набора. Набор проверки содержит два случайно выбранных изображения и соответствующие маски. Обучающий набор содержит оставшиеся изображения и маски.

tumorValIdx = randi(numTumorFiles,[1 2]);
tumorTrainIdx = setdiff(1:numTumorFiles,tumorValIdx);

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

tumorStrideFactor = 3;
blsTumorData = selectBlockLocations(tumorImages(tumorTrainIdx), ...
    "BlockSize",patchSize(1:2),"BlockOffsets",patchSize(1:2)*tumorStrideFactor, ...
    "Masks",tumorMasks(tumorTrainIdx),"InclusionThreshold",0.75,"ExcludeIncompleteBlocks",true);

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

blsTumorDataVal = selectBlockLocations(tumorImages(tumorValIdx), ...
    "BlockSize",patchSize(1:2), ...
    "Masks",tumorMasks(tumorValIdx),"InclusionThreshold",0.75,"ExcludeIncompleteBlocks",true);

Создание хранилищ данных для изображений опухолей

Создать blockedImageDatastore из тренировочных изображений опухолей и масок. Хранилища данных dsTumorData и dsTumorDataVal считывать патчи изображений из изображений опухолей на самом высоком уровне разрешения для обучения и проверки, соответственно.

dsTumorData = blockedImageDatastore(tumorImages(tumorTrainIdx), ...
    "BlockLocationSet",blsTumorData);
dsTumorDataVal = blockedImageDatastore(tumorImages(tumorValIdx), ...
    "BlockLocationSet",blsTumorDataVal);

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

imagesToPreview = zeros([patchSize 10],'uint8');
for n = 1:10
    im = read(dsTumorData);
    imagesToPreview(:,:,:,n) = im{1};
end
montage(imagesToPreview,'Size',[2 5],'BorderSize',10,'BackgroundColor','k');
title("Training Patches of Tumor Tissue")

Нормализация цветов и данных обучения дополнению

Обучающие изображения имеют разное распределение цветов, поскольку набор данных получен из разных источников, и окрашивание ткани цветом не приводит к идентичным окрашенным изображениям. Необходима дополнительная предварительная обработка, чтобы избежать смещения сети.

Для предотвращения изменчивости цвета в этом примере данные предварительно обрабатываются стандартными методами нормализации окрашивания. Применение нормализации и увеличения пятен с помощью transform функция с пользовательскими операциями предварительной обработки, заданными функцией помощника augmentAndLabelCamelyon16. Эта функция присоединена к примеру как вспомогательный файл.

augmentAndLabelCamelyon16 функция выполняет следующие операции:

  • Нормализовать окрашивание с помощью normalizeStaining.m функция [4]. Нормализацию окрашивания проводят методом Маценко, который разделяет цветовые каналы H&E путем деконволюции цвета с помощью фиксированной матрицы, а затем воссоздает нормализованные изображения с индивидуальным скорректированным смешиванием. Функция возвращает нормализованное изображение, а также изображения H & E.

  • Добавление дрожания цвета с помощью jitterColorHSV(Панель инструментов обработки изображений). Дрожание цвета изменяет цвет каждого фрагмента, нарушая контрастность, оттенок, насыщенность и яркость изображения. Дрожание цвета выполняется в цветовом пространстве HSV, чтобы избежать нежелательных цветовых артефактов в изображении RGB.

  • Применение случайных комбинаций поворотов на 90 градусов и вертикального и горизонтального отражения. Рандомизированные аффинные преобразования делают сеть агностической по отношению к ориентации входных данных изображения.

  • Пометить патч как 'normal' или 'tumor'.

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

Создание хранилищ данных, которые преобразуют обычные образы обучения и проверки и помечают созданные исправления как 'normal'.

dsLabeledNormalData = transform(dsNormalData, ...
    @(x,info)augmentAndLabelCamelyon16(x,info,'normal'),'IncludeInfo',true);
dsLabeledNormalDataVal = transform(dsNormalDataVal, ...
    @(x,info)augmentAndLabelCamelyon16(x,info,'normal'),'IncludeInfo',true);

Создание хранилищ данных, которые преобразуют изображения обучения и проверки опухоли и помечают созданные исправления как 'tumor'.

dsLabeledTumorData = transform(dsTumorData, ...
    @(x,info)augmentAndLabelCamelyon16(x,info,'tumor'),'IncludeInfo',true);
dsLabeledTumorDataVal = transform(dsTumorDataVal, ...
    @(x,info)augmentAndLabelCamelyon16(x,info,'tumor'),'IncludeInfo',true);

Балансируйте опухоль и нормальные классы

Количество раковой ткани на опухолевых изображениях очень мало по сравнению с количеством нормальной ткани. Необходима дополнительная предварительная обработка, чтобы избежать обучения сети несбалансированным по классу данным, содержащим большое количество нормальной ткани и очень небольшое количество опухолевой ткани.

Для предотвращения дисбаланса классов в этом примере определяется пользовательское хранилище данных с именем randomSamplingDatastore это случайным образом выбирает нормальные и опухолевые тренировочные пластыри сбалансированным образом. Сценарий для определения этого пользовательского хранилища данных присоединен к примеру как вспомогательный файл. Дополнительные сведения см. в разделе Разработка пользовательского хранилища данных.

Создание пользовательского randomSamplingDatastore из обычных и тренировочных хранилищ данных об опухолях. Хранилище данных случайной выборки dsTrain предоставляет мини-пакеты обучающих данных в сеть на каждой итерации эпохи.

dsTrain = randomSamplingDatastore(dsLabeledTumorData,dsLabeledNormalData);

Чтобы ограничить количество исправлений, используемых во время проверки, в этом примере определяется пользовательское хранилище данных, называемое validationDatastore возвращает пять исправлений проверки из каждого класса. Сценарий для определения этого пользовательского хранилища данных присоединен к примеру как вспомогательный файл.

Создание пользовательского validationDatastore из нормального хранилища данных и хранилища данных валидации опухоли.

numValidationPatchesPerClass = 5;
dsVal = validationDatastore(dsLabeledTumorDataVal, ...
    dsLabeledNormalDataVal,numValidationPatchesPerClass);

Настройка Inception-v3 сетевых слоев

В этом примере используется сеть Inception-v3, сверточная нейронная сеть, обученная более чем миллиону изображений из базы данных ImageNet [3]. Сеть имеет 48 слоев глубиной и может классифицировать изображения на 1000 категорий объектов, таких как клавиатура, мышь, карандаш и многие животные. Сеть ожидает размер входного изображения 299 на 299 с 3 каналами.

inceptionv3 функция возвращает предварительно подготовленную сеть Inception-v3. Для Inception-v3 требуется модель Deep Learning Toolbox™ для пакета поддержки Inception-v3 Network. Если этот пакет поддержки не установлен, функция предоставляет ссылку для загрузки.

net = inceptionv3;

Заменить конечные слои

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

Извлеките график уровня из обученной сети.

lgraph = layerGraph(net);

Поиск имен двух заменяемых слоев с помощью поддерживающей функции findLayersToReplace. Эта функция присоединена к примеру как вспомогательный файл. В Inception-v3 этим двум слоям присвоены имена 'predictions' и 'ClassificationLayer_predictions'.

[learnableLayer,classLayer] = findLayersToReplace(lgraph)
learnableLayer = 
  FullyConnectedLayer with properties:

          Name: 'predictions'

   Hyperparameters
     InputSize: 2048
    OutputSize: 1000

   Learnable Parameters
       Weights: [1000×2048 single]
          Bias: [1000×1 single]

  Show all properties

classLayer = 
  ClassificationOutputLayer with properties:

            Name: 'ClassificationLayer_predictions'
         Classes: [1000×1 categorical]
    ClassWeights: 'none'
      OutputSize: 1000

   Hyperparameters
    LossFunction: 'crossentropyex'

Целью этого примера является выполнение бинарной сегментации между двумя классами, опухолевой и нетуморной областями. Создайте новый полностью связанный слой для двух классов. Замените исходный конечный полностью подключенный слой новым слоем.

numClasses = 2;
newLearnableLayer = fullyConnectedLayer(numClasses,'Name','predictions');
lgraph = replaceLayer(lgraph,learnableLayer.Name,newLearnableLayer);

Создайте новый слой классификации для двух классов. Замените исходный окончательный классификационный слой новым.

newClassLayer = classificationLayer('Name','ClassificationLayer_predictions');
lgraph = replaceLayer(lgraph,classLayer.Name,newClassLayer);

Укажите параметры обучения

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

checkpointsDir = fullfile(trainingImageDir,'checkpoints');
if ~exist(checkpointsDir,'dir')
    mkdir(checkpointsDir);
end

options = trainingOptions('rmsprop', ...
    'InitialLearnRate',1e-5, ...
    'SquaredGradientDecayFactor',0.99, ...
    'MaxEpochs',3, ...
    'MiniBatchSize',32, ...
    'Plots','training-progress', ...
    'CheckpointPath',checkpointsDir, ...
    'ValidationData',dsVal, ...
    'ExecutionEnvironment','auto', ...
    'Shuffle','every-epoch');

Обучение или загрузка сети

По умолчанию в примере загружается предварительно подготовленная версия обученной сети Inception-v3 с помощью функции помощника. downloadTrainedCamelyonNet. Вспомогательная функция прикрепляется к примеру как вспомогательный файл. Предварительно обученная сеть позволяет выполнять весь пример без ожидания завершения обучения.

Для обучения сети установите doTraining переменная в следующем коде true. Обучение сети с помощью trainNetwork функция.

Обучение на GPU, если он доступен. Для использования графического процессора требуются параллельные вычислительные Toolbox™ и графический процессор NVIDIA ® с поддержкой CUDA ®. Дополнительные сведения см. в разделе Поддержка графического процессора по выпуску (Панель инструментов параллельных вычислений). Обучение занимает около 20 часов на NVIDIA Titan X.

doTraining = false;
if doTraining
    trainedNet = trainNetwork(dsTrain,lgraph,options);
    modelDateTime = string(datetime('now','Format',"yyyy-MM-dd-HH-mm-ss"));
    save(strcat("trainedCamelyonNet-",modelDateTime,".mat"),'trainedNet');
else
    trainedCamelyonNet_url = 'https://www.mathworks.com/supportfiles/vision/data/trainedCamelyonNet.mat';
    netDir = fullfile(tempdir,'Camelyon16');
    downloadTrainedCamelyonNet(trainedCamelyonNet_url,netDir);
    load(fullfile(netDir,'trainedCamelyonNet.mat'));
end
Pretrained Inception-v3 network for Cameylon16 data set already exists.

Загрузка и предварительная обработка тестовых данных

Набор тестовых данных Camelyon16 состоит из 130 WSI. Эти изображения имеют как нормальную, так и опухолевую ткань. В этом примере используются два тестовых изображения из Camelyon16 тестовых данных. Размер каждого файла составляет приблизительно 2 ГБ.

Создайте каталог для хранения тестовых данных.

testingImageDir = fullfile(tempdir,'Camelyon16','testing');
if ~exist(testingImageDir,'dir')
    mkdir(testingImageDir);
    mkdir(fullfile(testingImageDir,'images'));
    mkdir(fullfile(testingImageDir,'lesion_annotations'));
end

testDataDir = fullfile(testingImageDir,'images');
testTumorAnnotationDir = fullfile(testingImageDir,'lesion_annotations');

Чтобы загрузить тестовые данные, перейдите на веб-сайт Camelyon17 и нажмите первую ссылку «CAMELYON16 набор данных». Откройте каталог тестирования и выполните следующие действия.

  • Загрузите файл «lesion_annotations.zip». Извлеките все файлы в каталог, указанный testTumorAnnotationDir переменная.

  • Откройте каталог «images». Загрузите первые два файла, «test_001.tif» и «test_002.tif.» Переместить файлы в каталог, указанный testDataDir переменная.

Укажите количество тестовых изображений.

numTestFiles = 2;

Создание масок для тестовых изображений

Тестовые изображения содержат смесь нормального и опухолевого изображений. Чтобы уменьшить количество вычислений во время классификации, определите значения ROI путем создания масок.

Укажите уровень разрешения, используемый для создания маски. В этом примере используется уровень разрешения 7, который является грубым и вписывается в память.

resolutionLevel = 7;

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

testTissueMaskDir = fullfile(testDataDir,['test_tissuemask_level' num2str(resolutionLevel)]);
createMaskForNormalTissue(testDataDir,testTissueMaskDir,resolutionLevel);

Создайте маски для изображений, содержащих опухолевую ткань. Пропустить изображения, которые не содержат опухолевую ткань. Можно использовать функцию помощника createMaskForTumorTissue для создания масок с использованием объектов ROI. Эта вспомогательная функция присоединена к примеру как вспомогательный файл. Дополнительные сведения об этой вспомогательной функции см. в разделе Создание масок для изображений опухолей.

testTumorMaskDir = fullfile(testDataDir,['test_tumormask_level' num2str(resolutionLevel)]);
createMaskForTumorTissue(testDataDir,testTumorAnnotationDir,testTumorMaskDir,resolutionLevel);

Классификация данных испытаний и создание тепловых карт

Каждое исследуемое изображение имеет две маски, одна указывает нормальную ткань и одна указывает опухолевую ткань. Создать blockedImage объекты для управления тестовыми данными и масками с помощью функции помощника createBlockedImageAndMaskArrays. Вспомогательная функция прикрепляется к примеру как вспомогательный файл.

[testImages,testTissueMasks] = createBlockedImageAndMaskArrays(testDataDir,testTissueMaskDir);
[~,testTumorMasks] = createBlockedImageAndMaskArrays(testDataDir,testTumorMaskDir);

Используйте обученную сеть Inception-v3 для идентификации патчей опухоли на тестовых изображениях, testImages. Классифицируйте тестовые изображения по блокам с помощью apply(Панель инструментов обработки изображений) с пользовательским конвейером обработки, указанным вспомогательной функцией tumorProbabilityHeatMap. Эта вспомогательная функция присоединена к примеру как вспомогательный файл. Чтобы уменьшить необходимый объем вычислений, укажите маску ткани testTissueMask чтобы apply функция обрабатывает только пластыри, которые содержат ткань. Укажите 'UseParallel' аргумент пары имя-значение как логическое значение, возвращаемое canUseGPU. Если поддерживаемый графический процессор доступен для вычисления, то apply функция вычисляет блоки параллельно.

tumorProbabilityHeatMap функция выполняет следующие операции на каждом блоке ткани:

  • Рассчитайте оценку вероятности опухоли, используя predict функция.

  • Создайте патч изображения тепловой карты со значениями пикселей, равными баллу вероятности опухоли.

apply функция сшивает тепловую карту каждого блока в одну тепловую карту для тестового изображения. Тепловая карта показывает, где сеть обнаруживает области, содержащие опухоли.

Чтобы визуализировать тепловую карту, наложите тепловую карту на исходное изображение и задайте прозрачность 'AlphaData' свойство в качестве маски ткани. Наложение показывает, насколько хорошо опухоль локализована на изображении. Области с высокой вероятностью возникновения опухолей отображаются красными пикселями. Области с низкой вероятностью образования опухолей отображаются синими пикселями.

outputHeatmapsDir = fullfile(testingImageDir,'heatmaps');
if ~exist(outputHeatmapsDir,'dir')
    mkdir(outputHeatmapsDir);
end

patchSize = [299,299,3];

for idx = 1:numTestFiles
    bls = selectBlockLocations(testImages(idx),'BlockSize',patchSize(1:2),'Mask',testTissueMasks(idx),...
        'InclusionThreshold',0,'Levels',1);
    testHeatMaps(idx) = apply(testImages(idx),@(x)tumorProbabilityHeatMap(x,trainedNet), ...
        'Level',1,'BlockLocationSet',bls,'UseParallel',canUseGPU,'OutputLocation',outputHeatmapsDir);

    figure
    hTest = bigimageshow(testImages(idx));
    hTestAxes = hTest.Parent;
    hTestAxes.Visible = 'off';

    hMaskAxes = axes;
    hMask = bigimageshow(testHeatMaps(idx),'Parent',hMaskAxes, ...
        "Interpolation","nearest","AlphaData",testTissueMasks(idx));
    colormap(jet(255));
    hMaskAxes.Visible = 'off';

    linkaxes([hTestAxes,hMaskAxes]);
    title(['Tumor Heatmap of Test Image ',num2str(idx)]);
end

Ссылки

[1] Эхтешэми Б. Б., и др. «Диагностическая оценка алгоритмов глубокого обучения для выявления метастазов в лимфатические узлы у женщин с раком молочной железы». Журнал Американской медицинской ассоциации. т. 318, № 22, 2017, стр. 2199-2210. doi: 10.1001/jama.2017.14585

[2] Сегеди, К., В. Ванхоуке, С. Иоффе, Ж. Шленс и З. Война. «Переосмысление архитектуры для компьютерного зрения». В работе Конференции IEEE по компьютерному зрению и распознаванию образов, 2818-2826. Лас-Вегас, NV: IEEE, 2016.

[3] ImageNet. http://www.image-net.org.

[4] Маценко, М., и др. «Метод нормализации гистологических слайдов для количественного анализа». В 2009 году Международный симпозиум IEEE по биомедицинской визуализации: От нано до макро, 1107-1110. Бостон, Массачусетс: IEEE, 2009.

[5] xml2struct https://www.mathworks.com/matlabcentral/fileexchange/28518-xml2struct.

См. также

| | | (Панель инструментов обработки изображений) | (Панель инструментов обработки изображений) | (Панель инструментов обработки изображений) | (Панель инструментов обработки изображений) | (Панель инструментов обработки изображений)

Связанные темы