exponenta event banner

Изучение сети семантической сегментации с помощью Grad-CAM

В этом примере показано, как исследовать прогнозы семантической сети сегментации с помощью Grad-CAM.

Семантическая сеть сегментации классифицирует каждый пиксель в изображении, в результате чего изображение сегментируется по классу. Вы можете использовать Grad-CAM, метод глубокой визуализации обучения, чтобы увидеть, какие области изображения важны для решения о классификации пикселей.

Загрузить набор данных

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

Загрузить набор данных CamVid

Загрузите набор данных CamVid.

rng('default')

imageURL = 'http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/files/701_StillsRaw_full.zip';
labelURL = 'http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/data/LabeledApproved_full.zip';

outputFolder = fullfile(tempdir,'CamVid'); 
labelsZip = fullfile(outputFolder,'labels.zip');
imagesZip = fullfile(outputFolder,'images.zip');

if ~exist(labelsZip, 'file') || ~exist(imagesZip,'file')   
    mkdir(outputFolder)
       
    disp('Downloading 16 MB CamVid data set labels...'); 
    websave(labelsZip, labelURL);
    unzip(labelsZip, fullfile(outputFolder,'labels'));
    
    disp('Downloading 557 MB CamVid data set images...');  
    websave(imagesZip, imageURL);       
    unzip(imagesZip, fullfile(outputFolder,'images'));    
end
Downloading 16 MB CamVid data set labels...
Downloading 557 MB CamVid data set images...

Загрузить изображения CamVid

Использовать imageDatastore для загрузки изображений CamVid. imageDatastore позволяет эффективно загружать большую коллекцию образов на диск.

imgDir = fullfile(outputFolder,'images','701_StillsRaw_full');
imds = imageDatastore(imgDir);

Набор данных содержит 32 класса. Чтобы облегчить обучение, сократите число классов до 11, сгруппировав несколько классов из исходного набора данных. Например, создайте "Car«класс, который объединяет»Car", "SUVPickupTruck", "Truck_Bus", "Train«, и»OtherMoving"классы из исходного набора данных. Возврат сгруппированных идентификаторов меток с помощью функции поддержки camvidPixelLabelIDs, который приведен в конце этого примера.

classes = [
    "Sky"
    "Building"
    "Pole"
    "Road"
    "Pavement"
    "Tree"
    "SignSymbol"
    "Fence"
    "Car"
    "Pedestrian"
    "Bicyclist"
    ];

labelIDs = camvidPixelLabelIDs;

Используйте классы и идентификаторы меток для создания pixelLabelDatastore.

labelDir = fullfile(outputFolder,'labels');
pxds = pixelLabelDatastore(labelDir,classes,labelIDs);

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

Загрузка предварительно обученной сети семантической сегментации. Предварительно обученная модель позволяет выполнять весь пример без необходимости ждать завершения обучения. В этом примере загружается обученная сеть Deeplab v3 + с весами, инициализированными из предварительно обученной сети Resnet-18. Дополнительные сведения о создании и обучении сети семантической сегментации см. в разделе Семантическая сегментация с использованием глубокого обучения.

pretrainedURL = 'https://www.mathworks.com/supportfiles/vision/data/deeplabv3plusResnet18CamVid.mat';
pretrainedFolder = fullfile(tempdir,'pretrainedNetwork');
pretrainedNetwork = fullfile(pretrainedFolder,'deeplabv3plusResnet18CamVid.mat');

if ~exist(pretrainedNetwork,'file')
    mkdir(pretrainedFolder);
    disp('Downloading pretrained network (58 MB)...');
    websave(pretrainedNetwork,pretrainedURL);
end
Downloading pretrained network (58 MB)...
pretrainedNet = load(pretrainedNetwork); 
net = pretrainedNet.net;

Тестовая сеть

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

Загрузите тестовый образ.

figure
img = readimage(imds,615);
imshow(img,'InitialMagnification',35)

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

predLabels = semanticseg(img,net);

Просмотрите результаты.

cmap = camvidColorMap;
segImg = labeloverlay(img,predLabels,'Colormap',cmap,'Transparency',0.4);
figure
imshow(segImg,'InitialMagnification',40)

pixelLabelColorbar(cmap,classes)

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

Ознакомьтесь с прогнозами сети

Глубокие сети сложны, поэтому трудно понять, как сеть определяет конкретный прогноз. Можно использовать Grad-CAM для просмотра областей тестового изображения, используемых семантической сетью сегментации для классификации пикселей.

Grad-CAM вычисляет градиент дифференцируемого выходного сигнала, такого как оценка класса, относительно сверточных элементов в выбранном слое. Grad-CAM обычно используется для задач классификации изображений [2]; однако он также может быть распространен на проблемы семантической сегментации [3].

В задачах семантической сегментации уровень softmax сети выводит оценку для каждого класса для каждого пикселя в исходном изображении. Это контрастирует со стандартными проблемами классификации изображений, когда уровень softmax выводит оценку для каждого класса для всего изображения. Карта Grad-CAM для класса c

Mc = ReLU (∑kαckAk), где αck=1/N∑i,jdycdAi,jk

N - число пикселей, Ak - интересующая карта признаков, и yc соответствует баллу скалярного класса. Для простой проблемы классификации изображений yc является баллом softmax для класса интересов. Для семантической сегментации можно получить, уменьшив пиксельные оценки класса для интересующего класса до скаляра. Например, суммировать пространственные размеры слоя softmax: yc=∑ (i, j) ∈Pyi,jc, где P - пиксели в выходном слое семантической сети сегментации [3]. В этом примере выходным слоем является слой softmax перед слоем классификации пикселей. Карта Mc выделяет области, которые влияют на решение для класса C. Более высокие значения указывают области изображения, которые важны для решения о классификации пикселей.

Чтобы использовать Grad-CAM, необходимо выбрать слой элемента для извлечения карты элемента и слой сокращения для извлечения выходных активаций. Использовать analyzeNetwork поиск слоев для использования с Grad-CAM.

analyzeNetwork(net)

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

featureLayer = 'dec_relu4';

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

reductionLayer = 'softmax-out';

Вычислите карту Grad-CAM для классов дорог и дорожного покрытия.

classes = ["Road" "Pavement"];

gradCAMMap = gradCAM(net,img,classes, ...
    'ReductionLayer',reductionLayer, ...
    'FeatureLayer',featureLayer);

Сравните карту Grad-CAM для двух классов с картой семантической сегментации.

predLabels = semanticseg(img,net);
segMap = labeloverlay(img,predLabels,'Colormap',cmap,'Transparency',0.4);

figure;
subplot(2,2,1)
imshow(img)
title('Test Image')
subplot(2,2,2)
imshow(segMap)
title('Semantic Segmentation')
subplot(2,2,3)
imshow(img)
hold on
imagesc(gradCAMMap(:,:,1),'AlphaData',0.5)
title('Grad-CAM: ' + classes(1))
colormap jet
subplot(2,2,4)
imshow(img)
hold on
imagesc(gradCAMMap(:,:,2),'AlphaData',0.5)
title('Grad-CAM: ' + classes(2))
colormap jet

Карты Grad-CAM и карта семантической сегментации имеют схожую подсветку. Ни одна из карт не различает дорогу слева от перекрестка, которую семантическая карта сегментации помечает как дорожное покрытие. Карта Grad-CAM для класса дорожного покрытия показывает, что край дорожного покрытия важнее, чем центр для решения о классификации сети. Возможно, сеть неправильно классифицирует дорогу слева от перекрестка из-за плохой видимости кромки дорожного покрытия.

Обзор промежуточных слоев

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

Вычислите карту Grad-CAM для слоев, которые последовательно глубже в сети.

layers = ["res5b_relu","catAspp","dec_relu1"];
numLayers = length(layers);

res5b_relu уровень находится вблизи середины сети, тогда как dec_relu1 находится рядом с концом сети.

Изучение решений о классификации сети для классов автомобилей, дорог и дорожного покрытия. Для каждого слоя и класса вычислите карту Grad-CAM.

classes = ["Car" "Road" "Pavement"];
numClasses = length(classes);

gradCAMMaps = [];
for i = 1:numLayers
    gradCAMMaps(:,:,:,i) = gradCAM(net,img,classes, ...
        'ReductionLayer',reductionLayer, ...
        'FeatureLayer',layers(i));
end

Отображение карт Grad-CAM для каждого слоя и каждого класса. Строки представляют карту для каждого слоя, причем слои упорядочены от ранних в сети до конечных в сети.

figure;
idx = 1;
for i=1:numLayers
    for j=1:numClasses
        subplot(numLayers,numClasses,idx)
        imshow(img)
        hold on
        imagesc(gradCAMMaps(:,:,j,i),'AlphaData',0.5)
        title(sprintf("%s (%s)",classes(j),layers(i)), ...
            "Interpreter","none")
        colormap jet
        idx = idx + 1;
    end
end

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

Ссылки

[1] Бростоу, Габриэль Дж., Жюльен Фокер и Роберто Чиполла. «Классы семантических объектов в видео: база данных истинности земли высокой четкости». Письма 30, № 2 (январь 2009 года): 88-97. https://doi.org/10.1016/j.patrec.2008.04.005.

[2] Сельвараджу, Р. Р., М. Когсвелл, А. Дас, Р. Ведантам, Д. Парих и Д. Батра. «Grad-CAM: визуальные объяснения глубоких сетей с помощью локализации на основе градиента». В IEEE Международная конференция по компьютерному зрению (ICCV), 2017, стр. 618-626. Доступно по адресу Grad-CAM на сайте открытого доступа Фонда компьютерного зрения.

[3] Виноградова, Кира, Александр Дибров и Джин Майерс. «На пути к интерпретируемой семантической сегментации с помощью градиентно-взвешенного сопоставления активации класса (студенческий реферат)». Материалы конференции AAAI по искусственному интеллекту 34, № 10 (3 апреля 2020 года): 13943-44. https://doi.org/10.1609/aaai.v34i10.7244.

Вспомогательные функции

function labelIDs = camvidPixelLabelIDs()
% Return the label IDs corresponding to each class.
%
% The CamVid data set has 32 classes. Group them into 11 classes following
% the original SegNet training methodology [1].
%
% The 11 classes are:
%   "Sky", "Building", "Pole", "Road", "Pavement", "Tree", "SignSymbol",
%   "Fence", "Car", "Pedestrian",  and "Bicyclist".
%
% CamVid pixel label IDs are provided as RGB color values. Group them into
% 11 classes and return them as a cell array of M-by-3 matrices. The
% original CamVid class names are listed alongside each RGB value. Note
% that the Other/Void class are excluded below.
labelIDs = { ...
    
    % "Sky"
    [
    128 128 128; ... % "Sky"
    ]
    
    % "Building" 
    [
    000 128 064; ... % "Bridge"
    128 000 000; ... % "Building"
    064 192 000; ... % "Wall"
    064 000 064; ... % "Tunnel"
    192 000 128; ... % "Archway"
    ]
    
    % "Pole"
    [
    192 192 128; ... % "Column_Pole"
    000 000 064; ... % "TrafficCone"
    ]
    
    % Road
    [
    128 064 128; ... % "Road"
    128 000 192; ... % "LaneMkgsDriv"
    192 000 064; ... % "LaneMkgsNonDriv"
    ]
    
    % "Pavement"
    [
    000 000 192; ... % "Sidewalk" 
    064 192 128; ... % "ParkingBlock"
    128 128 192; ... % "RoadShoulder"
    ]
        
    % "Tree"
    [
    128 128 000; ... % "Tree"
    192 192 000; ... % "VegetationMisc"
    ]
    
    % "SignSymbol"
    [
    192 128 128; ... % "SignSymbol"
    128 128 064; ... % "Misc_Text"
    000 064 064; ... % "TrafficLight"
    ]
    
    % "Fence"
    [
    064 064 128; ... % "Fence"
    ]
    
    % "Car"
    [
    064 000 128; ... % "Car"
    064 128 192; ... % "SUVPickupTruck"
    192 128 192; ... % "Truck_Bus"
    192 064 128; ... % "Train"
    128 064 064; ... % "OtherMoving"
    ]
    
    % "Pedestrian"
    [
    064 064 000; ... % "Pedestrian"
    192 128 064; ... % "Child"
    064 000 192; ... % "CartLuggagePram"
    064 128 064; ... % "Animal"
    ]
    
    % "Bicyclist"
    [
    000 128 192; ... % "Bicyclist"
    192 000 192; ... % "MotorcycleScooter"
    ]
    
    };
end
function pixelLabelColorbar(cmap, classNames)
% Add a colorbar to the current axis. The colorbar is formatted
% to display the class names with the color.

colormap(gca,cmap)

% Add a colorbar to the current figure.
c = colorbar('peer', gca);

% Use class names for tick marks.
c.TickLabels = classNames;
numClasses = size(cmap,1);

% Center tick labels.
c.Ticks = 1/(numClasses*2):1/numClasses:1;

% Remove tick marks.
c.TickLength = 0;
end

function cmap = camvidColorMap
% Define the colormap used by the CamVid data set.

cmap = [
    128 128 128   % Sky
    128 0 0       % Building
    192 192 192   % Pole
    128 64 128    % Road
    60 40 222     % Pavement
    128 128 0     % Tree
    192 128 128   % SignSymbol
    64 64 128     % Fence
    64 0 128      % Car
    64 64 0       % Pedestrian
    0 128 192     % Bicyclist
    ];

% Normalize between [0 1].
cmap = cmap ./ 255;
end

См. также

| (Панель инструментов компьютерного зрения) | (Панель инструментов компьютерного зрения)

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