В этом примере показано, как использовать карты приписывания градиента, чтобы заняться расследованиями, какие части изображения являются самыми важными для решений классификации, принятых глубокой нейронной сетью.
Глубокие нейронные сети могут быть похожими на лиц, принимающих решения, черного квадрата — они дают превосходные результаты на комплексных проблемах, но может быть трудно изучить, почему сеть дает конкретный выход. Explainability все больше важен, когда глубокие сети используются в большем количестве приложений. Чтобы считать сеть объяснимой, должно быть ясно, какие части входных данных сеть использует, чтобы принять решение и сколько эти данные вносят в сетевой выход.
Область значений методов визуализации доступна, чтобы определить, использует ли сеть разумные части входных данных, чтобы принять решение классификации. А также методы приписывания градиента, показанные в этом примере, можно использовать методы, такие как взвешенное градиентом отображение активации класса чувствительность поглощения газов и (CAM градиента). Для примеров смотрите
Методы приписывания градиента, исследуемые в этом примере, предоставляют карты пиксельного разрешения, которые показывают, какие пиксели являются самыми важными для классификации сети. Они вычисляют градиент счета класса относительно входных пикселей. Интуитивно, карта показывает, какие пиксели больше всего влияют на счет класса, когда изменено. Методы приписывания градиента производят карты с более высоким разрешением, чем те от CAM градиента или чувствительности поглощения газов, но которые имеют тенденцию быть намного более шумными, когда хорошо обученная глубокая сеть не строго зависит от точного значения определенных пикселей. Используйте методы приписывания градиента, чтобы найти широкие области изображения, которые важны для классификации.
Самая простая карта приписывания градиента является градиентом счета класса к предсказанному классу относительно каждого пикселя во входном изображении [1]. Это показывает, какие пиксели оказывают самое большое влияние на счет класса, и поэтому какие пиксели являются самыми важными для классификации. В этом примере показано, как использовать приписывание градиента и два расширенных метода: ведомая обратная связь [2] и интегрированные градиенты [3]. Использование этих методов является объектом дебатов, когда не ясно, сколько понимания эти расширения могут обеспечить в модель [4].
Загрузите предварительно обученную сеть GoogLeNet.
net = googlenet;
Извлеките входной размер изображений и выходные классы сети.
inputSize = net.Layers(1).InputSize(1:2); classes = net.Layers(end).Classes;
Загрузите изображение. Изображение имеет собаку по имени Лэйка. Измените размер изображения к сетевому входному размеру.
img = imread("laika_grass.jpg");
img = imresize(img,inputSize);
Классифицируйте изображение и отобразите предсказанный класс и классификационную оценку.
[YPred, scores] = classify(net, img);
[score, classIdx] = max(scores);
predClass = classes(classIdx);
imshow(img);
title(sprintf("%s (%.2f)",string(predClass),score));
Сеть классифицирует Laika как миниатюрного пуделя, который является разумным предположением. Она - крест пуделя/кокер-спаниеля.
Методы приписывания градиента используют нахождение градиента счета предсказания относительно входного изображения. Карта приписывания градиента вычисляется с помощью следующей формулы:
где представляет важность пикселя в местоположении к предсказанию класса , счет softmax к тому классу, и изображение в пиксельном местоположении [1].
Преобразуйте сеть в dlnetwork
так, чтобы можно было использовать автоматическое дифференцирование, чтобы вычислить градиенты.
lgraph = layerGraph(net); lgraph = removeLayers(lgraph,lgraph.Layers(end).Name); dlnet = dlnetwork(lgraph);
Задайте имя softmax слоя, 'prob'
.
softmaxName = 'prob';
Чтобы использовать автоматическое дифференцирование, преобразуйте изображение Laika к dlarray
.
dlImg = dlarray(single(img),'SSC');
Используйте dlfeval
и gradientMap
функция (заданный в разделе Supporting Functions этого примера), чтобы вычислить производную . gradientMap
функционируйте передает изображение вперед через сеть, чтобы получить баллы класса и содержит вызов dlgradient
оценивать градиенты баллов относительно изображения.
dydI = dlfeval(@gradientMap,dlnet,dlImg,softmaxName,classIdx);
Карта приписывания dydI
227 227 3 массивами. Каждый элемент в каждом канале соответствует градиенту счета класса относительно входного изображения для того канала исходного изображения RGB.
Существует много способов визуализировать эту карту. Непосредственно строя карту приписывания градиента, когда изображение RGB может быть неясным, когда карта является обычно довольно шумной. Вместо этого суммируйте абсолютные значения каждого пикселя по измерению канала, затем перемасштабируйте между 0
и 1
. Отобразите карту приписывания градиента с помощью пользовательской палитры с 255 цветами, которая сопоставляет значения 0
белому и 1
к черному цвету.
map = sum(abs(extractdata(dydI)),3); map = rescale(map); cmap = [linspace(1,0,255)' linspace(1,0,255)' linspace(1,0,255)']; imshow(map, "Colormap", cmap); title("Gradient Attribution Map (" + string(predClass) + ")");
Самые темные части карты - сосредоточенные вокруг собаки. Карта является чрезвычайно шумной, но она действительно предполагает, что сеть использует ожидаемую информацию в изображении, чтобы выполнить классификацию. Пиксели у собаки оказывают намного больше влияния на классификационную оценку, чем пиксели травянистого фона.
Можно получить более резкую карту приписывания градиента путем изменения сети, назад проходят через слои ReLU так, чтобы элементы градиента, которые меньше нуля и элементов входа к слою ReLU, которые меньше нуля, были оба обнулены. Это известно как ведомую обратную связь [2].
Ведомая обратная связь обратная функция:
где потеря, вход к слою ReLU, и выход.
Можно записать пользовательский слой с нестандартным обратным проходом и использовать его с автоматическим дифференцированием. Пользовательский класс слоя CustomBackpropReluLayer
это реализует эту модификацию, включен как вспомогательный файл в этом примере. Когда автоматическое дифференцирование backpropagates через CustomBackpropReluLayer
объекты, это использует модифицированную ведомую функцию, определяемую обратной связи в пользовательском слое.
Используйте функцию поддержки replaceLayersofType
(заданный в разделе Supporting Functions этого примера), чтобы заменить все экземпляры reluLayer
в сети с экземплярами CustomBackpropReluLayer
. Установите BackpropMode
свойство каждого CustomBackpropReluLayer
к "guided-backprop"
.
customRelu = CustomBackpropReluLayer(); customRelu.BackpropMode = "guided-backprop"; lgraphGB = replaceLayersOfType(lgraph, ... "nnet.cnn.layer.ReLULayer",customRelu);
Преобразуйте график слоев, содержащий CustomBackpropReluLayers
в dlnetwork
.
dlnetGB = dlnetwork(lgraphGB);
Вычислите и постройте карту приписывания градиента для сети с помощью ведомой обратной связи.
dydIGB = dlfeval(@gradientMap,dlnetGB,dlImg,softmaxName,classIdx); mapGB = sum(abs(extractdata(dydIGB)),3); mapGB = rescale(mapGB); imshow(mapGB, "Colormap", cmap); title("Guided Backpropagation (" + string(predClass) + ")");
Вы видите, что ведомый метод обратной связи более ясно подсвечивает различные части собаки, такие как глаза и нос.
Можно также использовать метод Зейлер-Фергуса для обратной связи через слои ReLU [5]. Для метода Зейлер-Фергуса обратная функция дана как:
Установите BackpropMode
свойство CustomBackpropReluLayer
экземпляры к "zeiler-fergus"
.
customReluZF = CustomBackpropReluLayer(); customReluZF.BackpropMode = "zeiler-fergus"; lgraphZF = replaceLayersOfType(lgraph, ... "nnet.cnn.layer.ReLULayer",customReluZF); dlnetZF = dlnetwork(lgraphZF); dydIZF = dlfeval(@gradientMap,dlnetZF,dlImg,softmaxName,classIdx); mapZF = sum(abs(extractdata(dydIZF)),3); mapZF = rescale(mapZF); imshow(mapZF,"Colormap", cmap); title("Zeiler-Fergus (" + string(predClass) + ")");
Вычисленное использование карт приписывания градиента метода обратной связи Зейлер-Фергуса намного менее ясно, чем те, вычисленное использование вело обратную связь.
Интегрированный подход градиентов вычисляет, интегрирует градиенты счета класса относительно пикселей изображения через набор изображений, которые линейно интерполированы между базовым изображением и оригинальным изображением интереса [3]. Интегрированный метод градиентов спроектирован, чтобы быть чувствительным к изменениям в пиксельном значении по интегрированию, таким что, если изменение в пиксельном значении влияет на счет класса, что пиксель имеет ненулевое значение в карте. Нелинейность в сети, такая как слои ReLU, может предотвратить эту чувствительность в более простых методах приписывания градиента.
Интегрированная карта приписывания градиентов вычисляется как
,
где значение карты для класса в пиксельном местоположении , базовое изображение, и изображение на расстоянии вдоль пути между базовым изображением и входным изображением:
.
В этом примере интегрированная формула градиентов упрощена путем подведения итогов по дискретному индексу,, вместо того, чтобы объединяться :
,
с
.
Для данных изображения выберите базовое изображение, чтобы быть черным изображением нулей. Найдите изображение, которое является различием между оригинальным изображением и базовым изображением. В этом случае, differenceImg
совпадает с оригинальным изображением, когда базовое изображение является нулем.
baselineImg = zeros([inputSize, 3]); differenceImg = single(img) - baselineImg;
Создайте массив изображений, соответствующих дискретным шагам вдоль линейного контура от базового изображения до исходного входного изображения. Большее число изображений даст более сглаженные результаты, но займет больше времени, чтобы вычислить.
numPathImages = 25; соединения каналом = нули ([inputSize 3 numPathImages-1]); for n=0:numPathImages-1 соединения каналом (::: n+1) = baselineImg + (n) / (numPathImages-1) * differenceImg; end фигура; imshow (imtile (перемасштабируют (соединения каналом))); заголовок"Images Along Integration Path");
Преобразуйте мини-пакет изображений пути к dlarray
. Отформатируйте данные с форматом 'SSCB'
для пространственных двух, один канал и пакетные размерности. Каждое изображение пути является одним наблюдением в мини-пакете. Вычислите карту градиента для получившегося пакета изображений вдоль пути.
dlPathImgs = dlarray(pathImgs, 'SSCB');
dydIIG = dlfeval(@gradientMap, dlnet, dlPathImgs, softmaxName, classIdx);
Для каждого канала суммируйте градиенты всех наблюдений в мини-пакете.
dydIIGSum = sum(dydIIG,4);
Умножьте каждый элемент суммированных карт приписывания градиента с соответствующим элементом differenceImg
. Чтобы вычислить интегрированную карту приписывания градиента, суммируйте по каждому каналу и перемасштабировать.
dydIIGSum = differenceImg .* dydIIGSum; mapIG = sum(extractdata(abs(dydIIGSum)),3); mapIG = rescale(mapIG); imshow(mapIG, "Colormap", cmap); title("Integrated Gradients (" + string(predClass) + ")");
Вычисленная карта показывает, что сеть более строго фокусируется на поверхности собаки как средние значения выбора ее класса.
Методы приписывания градиента, продемонстрированные здесь, могут использоваться, чтобы проверять, фокусируется ли ваша сеть на ожидаемых частях изображения при создании классификации. Чтобы получить хорошее понимание пути, ваша модель работает, и объясните решения классификации, можно выполнить эти методы на области значений изображений и найти определенные функции, которые строго способствуют конкретному классу. Немодифицированный метод приписываний градиента, вероятно, будет более надежным методом для объяснения сетевых решений. В то время как ведомая обратная связь и интегрированные методы градиента могут произвести самые ясные карты градиента, не ясно, сколько понимания эти методы могут обеспечить в то, как модель работает [4].
Функциональный gradientMap
вычисляет градиенты счета относительно изображения, для заданного класса. Функция принимает одно изображение или мини-пакет изображений. В этом примере, функциональном gradientMap
введен в разделе Compute Gradient Attribution Map Using Automatic Differentiation.
function dydI = gradientMap(dlnet, dlImgs, softmaxName, classIdx) % Compute the gradient of a class score with respect to one or more input % images. dydI = dlarray(zeros(size(dlImgs))); for i=1:size(dlImgs,4) I = dlImgs(:,:,:,i); scores = predict(dlnet,I,'Outputs',{softmaxName}); classScore = scores(classIdx); dydI(:,:,:,i) = dlgradient(classScore,I); end end
replaceLayersOfType
функционируйте заменяет все слои заданного класса с экземплярами нового слоя. Новые слои называют с теми же именами как исходные слои. В этом примере, функциональном replaceLayersOfType
введен в разделе Sharpen the Gradient Attribution Map с помощью Ведомой Обратной связи.
function lgraph = replaceLayersOfType(lgraph, layerType, newLayer) % Replace layers in the layerGraph lgraph of the type specified by % layerType with copies of the layer newLayer. for i=1:length(lgraph.Layers) if isa(lgraph.Layers(i), layerType) % Match names between old and new layer. layerName = lgraph.Layers(i).Name; newLayer.Name = layerName; lgraph = replaceLayer(lgraph, layerName, newLayer); end end end
[1] Симонян, Карен, Андреа Ведальди и Эндрю Зиссермен. “Глубоко В Сверточных Сетях: Визуализация Моделей Классификации Изображений и Карт Выступа”. ArXiv:1312.6034 [Cs], 19 апреля 2014. http://arxiv.org/abs/1312.6034.
[2] Springenberg, Йост Тобиас, Алексей Досовицкий, Томас Брокс и Мартин Ридмиллер. “Борьба за Простоту: Вся Сверточная Сеть”. ArXiv:1412.6806 [Cs], 13 апреля 2015. http://arxiv.org/abs/1412.6806.
[3] Sundararajan, Mukund, Ankur Taly и Кики Ян. "Аксиоматическое приписывание для глубоких сетей". Продолжения 34-й международной конференции по вопросам машинного обучения (PMLR) 70 (2017): 3319-3328
[4] Адебайо, Джулиус, Джастин Джилмер, Майкл Муелли, Иэн Гудфеллоу, Мориц Хардт и Ким. “Проверки работоспособности на Карты Выступа”. ArXiv:1810.03292 [Cs, Статистика], 27 октября 2018. http://arxiv.org/abs/1810.03292.
[5] Zeiler, Мэтью Д. и Роб Фергус. "Визуализируя и Изучая Сверточные Сети". В Компьютерном зрении – ECCV 2014. Читайте лекции Примечаниям в Информатике 8689, отредактированный D. Флот, Т. Пэдждла, Б. Шиле, Т. Тейтелэарс. Спрингер, Хан, 2014.
googlenet
| occlusionSensitivity
| dlarray
| dlgradient
| dlfeval
| dlnetwork
| gradCAM
| imageLIME