exponenta event banner

Визуализация активации сверточной нейронной сети

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

Для примера требуются Toolbox™ глубокого обучения и Toolbox™ обработки изображений.

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

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

net = squeezenet;

Чтение и показ изображения. Сохраните его размер для использования в будущем.

im = imread('face.jpg');
imshow(im)

imgSize = size(im);
imgSize = imgSize(1:2);

Просмотр архитектуры сети

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

analyzeNetwork(net)

Слой «Ввод изображения» определяет размер ввода. Можно изменить размер изображения перед его передачей по сети, но сеть также может обрабатывать изображения большего размера. При подаче в сеть изображений большего размера активации также увеличиваются. Однако, поскольку сеть обучается изображениям размером 227-на-227, она не обучается распознавать объекты или признаки, превышающие этот размер.

Показать активации первого сверточного слоя

Исследуйте элементы, наблюдая, какие области в сверточных слоях активируются на изображении, и сравнивая их с соответствующими областями на исходных изображениях. Каждый уровень сверточной нейронной сети состоит из множества 2-D массивов, называемых каналами. Пропустите изображение через сеть и проверьте выходные активации conv1 слой.

act1 = activations(net,im,'conv1');

Активации возвращаются в виде массива 3-D, при этом третье измерение индексирует канал на conv1 слой. Чтобы показать эти активации с помощью imtile измените форму массива на 4-D. Третье измерение на входе в imtile представляет цвет изображения. Задайте третий размер размером 1, поскольку активации не имеют цвета. Четвертое измерение индексирует канал.

sz = size(act1);
act1 = reshape(act1,[sz(1) sz(2) 1 sz(3)]);

Теперь можно отобразить активации. Каждая активация может принимать любое значение, поэтому нормализуйте выходные данные с помощью mat2gray. Все активации масштабируются таким образом, что минимальная активация равна 0, а максимальная - 1. Отображение 64 изображений на сетке 8 на 8, по одному для каждого канала в слое.

I = imtile(mat2gray(act1),'GridSize',[8 8]);
imshow(I)

Исследование активаций в определенных каналах

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

Измените размер активизаций в канале 22 так, чтобы они имели тот же размер, что и исходное изображение, и отобразите активизации.

act1ch22 = act1(:,:,:,22);
act1ch22 = mat2gray(act1ch22);
act1ch22 = imresize(act1ch22,imgSize);

I = imtile({im,act1ch22});
imshow(I)

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

Найти самый сильный канал активации

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

[maxValue,maxValueIndex] = max(max(max(act1)));
act1chMax = act1(:,:,:,maxValueIndex);
act1chMax = mat2gray(act1chMax);
act1chMax = imresize(act1chMax,imgSize);

I = imtile({im,act1chMax});
imshow(I)

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

Исследование более глубокого слоя

Большинство сверточных нейронных сетей учатся обнаруживать такие особенности, как цвет и края в их первом сверточном слое. В более глубоких сверточных слоях сеть учится обнаруживать более сложные функции. Более поздние слои создают свои элементы, комбинируя элементы более ранних слоев. Исследовать fire6-squeeze1x1 таким же образом, как и conv1 слой. Расчет, изменение формы и отображение активаций в сетке.

act6 = activations(net,im,'fire6-squeeze1x1');
sz = size(act6);
act6 = reshape(act6,[sz(1) sz(2) 1 sz(3)]);

I = imtile(imresize(mat2gray(act6),[64 64]),'GridSize',[6 8]);
imshow(I)

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

[maxValue6,maxValueIndex6] = max(max(max(act6)));
act6chMax = act6(:,:,:,maxValueIndex6);
imshow(imresize(mat2gray(act6chMax),imgSize))

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

В сетке всех каналов есть каналы, которые могут активироваться на глазах. Дальнейшее изучение каналов 14 и 47.

I = imtile(imresize(mat2gray(act6(:,:,:,[14 47])),imgSize));
imshow(I)

Многие из каналов содержат области активации, которые являются как светлыми, так и темными. Это положительные и отрицательные активации, соответственно. Однако используются только положительные активации из-за выпрямленного линейного блока (ReLU), который следует за fire6-squeeze1x1 слой. Чтобы исследовать только положительные активации, повторите анализ, чтобы визуализировать активации fire6-relu_squeeze1x1 слой.

act6relu = activations(net,im,'fire6-relu_squeeze1x1');
sz = size(act6relu);
act6relu = reshape(act6relu,[sz(1) sz(2) 1 sz(3)]);

I = imtile(imresize(mat2gray(act6relu(:,:,:,[14 47])),imgSize));
imshow(I)

По сравнению с активациями fire6-squeeze1x1 слой, активации fire6-relu_squeeze1x1 слой четко указывает области изображения, которые имеют сильные черты лица.

Проверьте, распознает ли канал глаза

Проверьте наличие каналов 14 и 47 fire6-relu_squeeze1x1 слой активируется на глазах. Введите новое изображение с одним закрытым глазом в сеть и сравните полученные активации с активациями исходного изображения.

Прочтите и покажите изображение одним закрытым глазом и вычислите активации fire6-relu_squeeze1x1 слой.

imClosed = imread('face-eye-closed.jpg');
imshow(imClosed)

act6Closed = activations(net,imClosed,'fire6-relu_squeeze1x1');
sz = size(act6Closed);
act6Closed = reshape(act6Closed,[sz(1),sz(2),1,sz(3)]);

Постройте график изображений и активизаций на одном рисунке.

channelsClosed = repmat(imresize(mat2gray(act6Closed(:,:,:,[14 47])),imgSize),[1 1 3]);
channelsOpen = repmat(imresize(mat2gray(act6relu(:,:,:,[14 47])),imgSize),[1 1 3]);
I = imtile(cat(4,im,channelsOpen*255,imClosed,channelsClosed*255));
imshow(I)
title('Input Image, Channel 14, Channel 47');

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

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

См. также

| |

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