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

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

Давайте рассмотрим InceptionV3 как нашу базовую сеть. Это одна из самых известных сверточных нейронных сетей, поэтому она соответствует нашей цели - не идти на компромисс в отношении общности. Его структура проиллюстрирована следующим образом.

Мы используем InceptionV3, предварительно обученный с набором данных ImageNet, чтобы запустить наш эксперимент. Задача сети - классифицировать различные объекты на изображении. Изображение входит в модель (или сеть) в качестве входных данных, а номер класса объекта в этом изображении появляется в качестве выходных данных.

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

Для начала нам нужно протестировать нашу первую собаку.

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

1. Мальтийская собака - 0,9292618
2. Лхаса - 0,0054057003
3. Западно-белый терьер - 0,0032469642
4. Ши-тцу - 0,0026330198
5. Японский спаниель - 0,0022667362

Модель идентифицирует объект на изображении как мальтийскую собаку с вероятностью 0,9293. Я не специалист по собакам, но простой поиск в Google показывает, что это действительно мальтийская собака.

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

Давай займемся расследованиями. Начнем с того, что заблокируем часть изображения рядом с собакой.

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

1. Мальтийская собака - 0,93191534
2. Лхаса - 0,008831738
3. Пекинский - 0,0027588836
4. Японский спаниель - 0,0026686913
5. Ши-тцу - 0,0024955475

Обратите внимание, что вероятность идентификации теперь увеличивается с 0,9293 до 0,9319. Таким образом, кадрирование изображения вокруг собаки фактически увеличивает точность модели. Идентичные тесты с другими изображениями дают качественно аналогичные результаты. В конце концов, это имеет смысл. Сеть уделяет больше внимания объекту и в значительной степени игнорирует его окружение.

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

1. Куропатка - 0,042628713
2. Тетерев - 0,035664327
3. Перепел - 0,027290314
4. Сорока - 0,024524875
5. Громкоговоритель - 0,020369

Из приведенных выше оценок вероятности следует, что модель не может точно идентифицировать объект. Куропатка стоит на первом месте, хотя и с очень небольшой вероятностью 0,0426. Малая вероятность указывает на то, что модель не очень уверена в своем ответе. «Мальтийская собака» появляется дальше в списке с вероятностью 0,0005.

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

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

Топ-5 показателей объекта на модифицированном изображении выше приведены ниже.

1. Мальтийский_собака - 0,602724
2. Западный высокогорный_белый терьер - 0,11070298
3. Норфолкский терьер - 0,011860368
4. Лхаса - 0,005608953
5. Японский спаниель - 0,004504432

Примечательно, что модель приходит к правильному ответу «мальтийская собака», хотя и со значительно меньшей степенью уверенности. Вероятность идентификации сейчас снизилась до 0,60 по сравнению с предыдущим максимумом 0,93.

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

Можем ли мы построить тепловую карту того, где сеть ищет свои прогнозы? Возможно, мы сможем. Давай займемся расследованиями. Для этого мы случайным образом скрываем до 50% изображения и изучаем реакцию метрики вероятности идентификации. Мы случайным образом закрываем сразу несколько небольших блоков так, чтобы общая скрытая область составляла 50% изображения. Мы записываем доверительную оценку в двумерный массив с размерами, равными исходному изображению, чтобы мы могли сравнивать различные случайные шаблоны. После каждой итерации мы добавляем массивы, чтобы получить общую оценку после нескольких прогонов. Чтобы учесть правильное определение объекта, смотрим ответы только одного класса.

Чтобы получить маску с блоками, которые будут покрывать часть изображений, давайте создадим одномерный единичный массив размером 5% нашего изображения и установим в ноль 50% значений в нем.

THRESHOLD_COEF = 0.5
IMG_SIZE_SMALL = int(IMG_SIZE*0.05)
rand_ar = np.ones(IMG_SIZE_SMALL*IMG_SIZE_SMALL, np.uint8)
rand_ar[0:int(IMG_SIZE_SMALL*IMG_SIZE_SMALL*THRESHOLD_COEF )] = 0

Далее смешиваем все значения и восстанавливаем маску в виде изображения из массива.

random.shuffle(rand_ar)
rand_ar = rand_ar.reshape(IMG_SIZE_SMALL, IMG_SIZE_SMALL)
rand_ar = Image.fromarray(np.uint8(rand_ar))
rand_ar = rand_ar.resize((IMG_SIZE, IMG_SIZE), Image.NEAREST)
rand_ar = np.stack((rand_ar,rand_ar,rand_ar), axis=2)

Получаем следующую маску.

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

С помощью этого измененного изображения сеть идентифицирует его как Maltese_dog с достоверностью 0,00052775315.

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

acc = np.zeros(IMG_SIZE*IMG_SIZE*3).reshape(IMG_SIZE,IMG_SIZE,3)
rand_ar = rand_ar.astype(np.int8)
acc = acc + rand_ar * pred[0][CLASS_NUM]
acc = acc + (rand_ar - 1) * pred[0][CLASS_NUM]

После 5000 итераций получаем следующий результат. Вот как сеть представляет мальтийскую собаку:

А так выглядят все наши маленькие друзья после нанесения термальной маски.

Обычно мы замечаем, что модель обращает внимание на лица.

Но что, если мы будем искать что-то еще на наших фотографиях? Хот-дог? Кто самый горячий?

Возможно, нам всем стоит немного остыть и поесть мороженого.

Наш мальтийский друг не похож на мороженое, и модель пытается его осмотреть. Но не единорог.

На этом пока все. В следующий раз мы перейдем к модели и рассмотрим ее подробнее.

Не бойтесь экспериментировать и узнавайте больше о машинном обучении.

Вы можете увидеть полный код эксперимента здесь.