Руководство для понимания сверточной нейронной сети

В современном мире мы широко используем изображения. Не правда ли? Вы когда-нибудь задумывались, как Facebook автоматически определяет лица на изображении, а затем сообщает, кто находится на изображении, как это было на рисунке выше. Когда я перемещаю указатель рядом с одним из лиц на изображении, он автоматически называет имя человека, и это не кто иной, как Ян Лекун (который предложил архитектуру CNN). Вы когда-нибудь пользовались Snapchat? Он сначала автоматически обнаруживает ваше лицо, а затем соответственно применяет выбранный вами фильтр. Нечто подобное делает и Apple Face ID, который автоматически разблокирует ваш телефон, когда обнаруживает ваше лицо перед устройством.

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

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

Этот пост разделен на три раздела. В первом мы попытаемся построить эту технику, следуя нашей собственной интуиции, что будет очень интересным и уникальным подходом к изучению этого магического трюка. Во втором разделе мы реализуем его на Python, чтобы увидеть его в действии. А в третьем разделе мы попробуем поэкспериментировать с этим, задав несколько интересных вопросов, чтобы изучить их и узнать больше.

Понимание семантического разрыва

Мы, Человеческие Существа, являемся визуальными существами, и мы видим различные объекты вокруг себя глазами, но задумывались ли вы когда-нибудь о том, что изображение означает для компьютера? Есть большая разница между тем, как мы воспринимаем изображения, и тем, как это делает компьютер. Мы особенно называем этот пробел Semantic Gap, который хорошо описан на изображении ниже.

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

import os 
import cv2 
import numpy as np
np.set_printoptions(threshold=np.inf)
image = cv2.imread('/cat.jpeg')
print(type(image))
image = cv2.resize(image , (28,28) , cv2.INTER_AREA)
print(image.shape)
#visualizing the seperate channels of image
print(image[: , : , 0]) #prints out Blue channel
print(image[: , : , 1]) #prints out Green channel
print(image[: , : , 2]) #prints out Red channel
#To visualize the whole image with all 3 channels
print(image[: , : , :])

Теперь вы спросите, есть ли способ, которым наш любимый компьютер узнает, какой объект присутствует в кадре. Вы держите пари, что есть, и мы собираемся его построить. Я знаю, это кажется сложной задачей, но, пожалуйста, терпи меня до конца. Мы обязательно это сделаем!

Первый и самый важный шаг на нашем пути:

Как я уже сказал, мы просто зададим вопросы, которые помогут нам создать классификатор изображений. Для краткости мы назовем классификатор изображений IC
Теперь мы готовы начать наше путешествие. Итак, давайте зададим первый вопрос: «Можете ли вы сказать, к какой категории относятся следующие изображения? Кошка или собака?

Я уверен, что вы правильно сказали! Они относятся к категории Cat, но подождите, сделайте шаг назад и подумайте, как вы пришли к такому выводу? Попробуйте подумать, как это сделал ваш мозг? Как можно быть настолько уверенным, что это изображения кошек, а не собак? Вы знаете, как выглядят кошки, и, вероятно, сделали проверку сходства между грубым изображением мордочки кошки, которое вы бессознательно сохранили в своем мозгу, с этими изображениями (точнее, средней частью этих изображений). images), и если он возвращает высокий балл. Тогда вы пришли к выводу, что на этих изображениях действительно изображены кошки.

Теперь вы можете спросить: «А нельзя ли включить тот же механизм в наш собственный классификатор изображений?» Это кажется отличной идеей, но она сопряжена с двумя основными проблемами:

  1. Какой образ будет действовать как образ (приблизительный образ), который мы сохранили в нашем сознании?
  2. Как мы собираемся измерить сходство между двумя изображениями?

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

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

Что касается второго вопроса, есть ли способ выполнить проверку сходства между двумя изображениями, другими словами, между большой матрицей (исходное изображение) и Маленькая матрица (грубое изображение)? Да! У нас есть кое-что, что может сделать это за нас. В математике он известен как внутренний продукт Фробениуса. Не бойся. Я объясню, что это такое и для чего он нужен.

Внутреннее произведение Фробениуса - это не что иное, как поэлементное умножение двух массивов с последующей операцией сложения. Допустим, у вас есть две сетки или матрицы и назовем их A и B, как показано ниже, тогда внутренний продукт Фробениуса (FIP) будет рассчитан следующим образом.

Внутренний продукт Фробениуса, как правило, является одним из способов измерения сходства между двумя объектами (матрицами). Это не что иное, как обобщенная версия скалярного произведения с одним отличием: скалярное произведение определяется для векторов, а внутреннее произведение - для матриц. То, как он точно измеряет сходство, выходит за рамки этого руководства, но если вы хотите узнать об одном и том же в деталях, не стесняйтесь проверить этот пост в блоге и этот, чтобы понять внутренний продукт.

Теперь у нас есть оба изображения (грубое и основное) и способ измерить сходство между двумя матрицами или изображениями. Прохладный! Итак, давайте посмотрим на наш очень простой конвейер для классификации изображения как кота или не кота, который включает в себя два шага:

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

Но будет ли этот конвейер или наш классификатор изображений работать для следующих изображений?

Нет, большое нет! Это не сработает для этих изображений, потому что на них нет лица кошки посередине. Это приведет к меньшему сходству между обоими изображениями, что означает неправильную классификацию. Можем ли мы решить эту проблему? Да мы можем. Вместо того, чтобы сосредотачиваться только на средней части изображения, нам следует выполнить проверку сходства для каждой части основного изображения с грубым изображением, что сделает наш классификатор изображений глобальным инвариантом перевода, что означает не имеет значения, где находится лицо или узор на изображении, наш классификатор изображений обязательно его обнаружит. Процесс очень прост, мы начинаем с верхнего левого угла основного изображения, выбираем Создаем небольшую матрицу того же размера, что и наше грубое изображение, затем делаем проверку на сходство между выбранной частью основного и грубого изображения. В конце концов, результат будет сохранен в выходной матрице, и мы должны повторить этот процесс для каждой части нашего основного изображения. Обратите внимание, что направление выбора определенной части основного изображения будет слева направо и сверху вниз. Количество шагов или единиц, с которыми мы перемещаем грубое изображение по основному изображению, известно как Шаг. Теперь позвольте мне прояснить этот момент с помощью следующей графики и псевдокода.

category = None
for selected_part in (each part of main image):
    1. calculate the similarity between selected part and rough part
    2. if similarity == HIGH:
    3.     category = cat
if category == cat:
     print("Cat is present in image")
else:
     print("Cat is not present in image")

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

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

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

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

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

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

  1. Входной объем: это может быть изображение с глубиной 3 (RGB) или это может быть результат предыдущей операции свертки.
  2. Матрица детектора признаков: будет составлять K ядер для обнаружения различных шаблонов.
  3. Карта функций: это будет результат операции свертки, которая просто сохранит значения подобия.

Формально комбинация этих трех компонентов известна как один слой свертки. И если вы задумываетесь, как на этот раз будет выполняться операция свертки. Присмотритесь внимательнее.

Теперь наш классификатор изображений может обнаруживать различные особенности в любом месте изображения. Похоже, мы делаем отличную работу. Но все еще есть необходимость в улучшении. Можем ли мы уменьшить нашу рабочую нагрузку? Обратите внимание на одну вещь: мы вручную определяем наши детекторы функций, что это конкретное ядро ​​должно обнаруживать эту конкретную функцию. Всегда ли это возможно? Можем ли мы, люди, идентифицировать все шаблоны, необходимые для построения нашего классификатора? Это вообще возможно? Ответ - нет, не можем. Но можем ли мы сделать наш компьютер достаточно умным, чтобы изучить сами детекторы функций? Да мы можем. Мы будем использовать вычислительную мощность современных компьютеров с помощью машинного обучения, чтобы обучить нашу машину тоннам изображений с соответствующими метками. Затем он сам идентифицирует различные детекторы признаков для построения надежного классификатора изображений. Если для вас это не так уж и важно, я предлагаю вам просмотреть этот блог.

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

Введение в нелинейность

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

CONV LAYER--> CONV LAYER--> CONV LAYER --------> CONV LAYER

Отзывать! Ранее мы узнали, что Свертка - это линейная операция, что просто означает, что не имеет значения, сколько слоев вы добавите в классификатор, он будет изучать только линейную функцию. И даже если вы добавите 100 слоев в свою сеть, все они будут действовать как один сверточный слой. Да, 100 Layers == 1 Layer Не верите? Отлично. Позвольте мне уточнить с помощью простых линейных уравнений.

Преобразование из `u` вy выполняется с помощью 3 линейных уравнений, но, как показано на изображении выше, это также можно сделать с помощью одного линейного уравнения 60u+31, что означает Power(3 linear equations) = Power of 1 linear equation.

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

  1. Изучить сложную и нелинейную функцию классификации изображений.
  2. Чтобы сделать нашу сеть мощной, сохранив 100 Layers == 100 Layers

Нелинейная функция или функция активации, которая сегодня широко распространена в сообществе глубокого обучения, - это ReLU (выпрямленная линейная единица).

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

def relu(x):
    if x < 0:
        return 0
    else:
        return x

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

Объединение: сделайте его более надежным и эффективным

До сих пор в этом руководстве мы уделяли гораздо больше внимания надежности классификатора изображений, но пока давайте также сосредоточимся на эффективности классификатора. Входными данными для нашего классификатора является изображение. Верно? И его размер может варьироваться в зависимости от решаемой проблемы. Изображения могут иметь форму28x28, 64x64, 128x128, 256x256. Чем больше размер изображения, тем больше параметров в нашем классификаторе изображений. В сообществе глубокого обучения хорошо известен тот факт, что чем больше у вас параметров, тем больше будет ваша модель и больше времени потребуется на обучение. Итак, разве нет способа избавиться от этой проблемы? Да, есть. Мы можем уменьшить форму входного объема, используя операцию, известную как Объединение.

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

На картинке выше красный массив - это наш подмассив, а маленькая синяя матрица - результат операции объединения. Уменьшение массива 20x20 с помощью 2x2array приведет к резкому изменению количества параметров в дальнейшей операции свертки. Небольшой подмассив известен как ядро ​​, и здесь также применима концепция шага, которая играет роль при принятии решения о том, на сколько шагов вы хотите, чтобы ваше ядро ​​переместилось. Мы можем использовать любую сводную статистику, чтобы заменить ее одним числом, и это можно сделать, взяв максимальное значение из подмассива, известного как Max-Pooling, или мы можем взять среднее значение подмассива, известное как Среднее объединение.

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

[Выше три разных изображения человеческого лица с небольшими различиями. Если вы внимательно заметили, расстояние между двумя парами глаз и расстояние между глазами и носом не одинаковы, но все же мы хотим, чтобы наш классификатор изображений идеально классифицировал все эти лица. Но чего еще мы ожидаем от нашего классификатора изображений? Мы хотим, чтобы наше ядро ​​детектора лица не фокусировалось на точном относительном положении глаз и носа, а вместо этого проверяло наличие одного глаза слева, одного глаза справа, носа посередине, за которым следуют губы и все ли Вышеуказанные условия выполнены, заявить как лицо. И это именно то, в чем нам помогает операция пула. Итак, пул выполняет в основном две функции, и теперь вы знаете их обе!

Последний компонент нашего классификатора изображений

Мы уже рассмотрели самое сложное. Теперь давайте рассмотрим самый простой и заставим наш классификатор полностью работать. Это даст нам единственное число, с помощью которого мы можем гарантировать, что это изображение кошки, верно? Но заметили ли вы еще одну вещь? Результат всех слоев, которые мы рассмотрели до сих пор, имеет форму (width,height,depth), но нас интересует одно-единственное число, которое может сказать нам, присутствует ли кошка на изображении или нет. Итак, как нам этого добиться? Как нам использовать все нейроны, присутствующие в выходном объеме предыдущих слоев, поскольку эти нейроны сообщают нам, присутствует ли конкретная функция в изображении или нет? Как нам разумно объединить информацию этих нейронов, чтобы получить единое число? Прежде всего, мы должны выполнить операцию под названием Flattening, чтобы мы могли разумно использовать все эти нейроны для получения этого единственного числа. Сглаживание - очень простая операция, которая преобразует входной объем формы (width,height,depth) в одномерный массив формы (K,1), где K=width*height*depth.

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

Если вы знаете о простой нейронной сети (без какого-либо причудливого слоя), то соединение нескольких полносвязных слоев с разным количеством нейронов эквивалентно наложению простой нейронной сети поверх Feature Extractor . Не правда ли? Изображение ниже немного проясняет концепцию, а также поможет вам понять, как одномерный массив будет преобразован в одно число.

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

Раздел 2: Сверточная нейронная сеть в действии

Мы очень подробно узнали о сверточной нейронной сети. Давайте переключим наш режим. А теперь хватит теории и интуиции. Давайте реализуем все, чему мы научились до сих пор, и построим сквозную архитектуру LeNet, которая была первой архитектурой CNN, разработанной не кем иным, как Яном Лекуном. Однако есть много других архитектур CNN, о которых вы можете прочитать здесь. Расположение различных слоев в архитектуре LeNet следующее:

Input -> Conv -> Activation -> MaxPooling -> Conv -> Activation -> MaxPooling -> Flattening -> FC -> FC

Мы будем использовать CNN для классификации рукописных цифр в одну из 10 категорий. И набор данных, который мы будем использовать, MNIST Database, что выглядит как

Теперь давайте реализуем все, что мы узнали до сих пор, в Python с помощью Keras.

Строки 1–10: Мы импортировали необходимые классы, которые потребуются в дальнейшем для реализации архитектуры LeNet.

Строка 13: Набор данных MNIST загружается в четыре переменные ((x_train,y_train), (x_test,y_test))

Строки 15–18: Эти строки распечатывают форму поезда и набор тестовых данных.

Строки 21 и 22: они нормализуют входные изображения путем преобразования диапазона каждого пикселя изображения из 0–255 в 0–1.

Строки 24–25: Выполняется горячее кодирование, которое в основном делается для того, чтобы явно сообщить нашей модели об отсутствии порядковых отношений между классами.

Строки 27 и 28: они изменят форму данных (как обучающих, так и тестовых) с (data.shape [0], 28, 28) на (data.shape [0], 28, 28, 1 ), который будет использоваться для обозначения количества каналов входного изображения для сверточного слоя.

Строки 38–49: Эти строки определяют архитектуру LeNet. Для реализации этой архитектуры мы использовали Sequential API керасов (строка 38). Первый скрытый слой сети - это сверточный слой с 30 фильтрами размера (5,5), за которым следует слой активации ReLu, а затем слой MaxPooling с размером пула. = (2,2) укладывается поверх предыдущего слоя. Эта комбинация трех слоев повторяется снова в соответствии с архитектурой. После этих 2 блоков из трех слоев операция сглаживания выполняется сглаживающим слоем (строка 47), а затем к двум полностью связанным слоям присоединяются 500 и 10 нейронов (строка 48 и 49).

Строки 52 и 53: Эти строки будут определять необходимый оптимизатор, который будет использоваться для обучения CNN (строка 52), а строка 53 будет компилировать определенную модель с categorical crossentropy в качестве функции потерь и accuracy в качестве метрика мониторинга.

Строка 56: она будет отвечать за обучение нашей CNN (реальной вещи) с числом эпох 10.

Строки 59–63: Эти строки будут использоваться для оценки обученной модели, которая поможет нам проверить, насколько хорошо наша модель будет работать с невидимыми данными, путем вычисления значения логарифмических потерь и точности теста. набор данных.

Если вы выполните приведенный выше код, вы получите следующий результат.

Accuracy of our model is 97.008%
Log loss value : 0.079

Поскольку точность нашей модели примерно равна 98%, а значение логарифмических потерь равно 0,079, что довольно хорошо.

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

Раздел 3. Игра с ConvNets, чтобы лучше понять их

В сообществе глубокого обучения большинство людей рассматривают сверточную нейронную сеть как «черные ящики», не уделяя особого внимания тому, как они делают то, что они делают. В этом разделе мы поиграем со сверточной нейронной сетью и в основном сосредоточимся на аспекте визуализации ConvNets. Мы узнаем больше о CNN, изучая некоторые из наиболее важных и интересных статей, но опять же задавая интересные вопросы. Этот раздел будет включать в себя все те детали, которые не часто обсуждаются и не известны большинству людей в сообществе глубокого обучения. Надеюсь, ты тоже узнаешь что-то новое. Вы взволнованы? Я знаю, что вы!

3.1: Визуализация промежуточных результатов

Мы очень хорошо знаем, что в сверточной нейронной сети присутствует очень много слоев, начиная от входного уровня до выходного (softmax) слоя. Будет забавным упражнением, если мы сможем визуализировать преобразование, выполняемое каждым слоем, или вывод каждого слоя, когда мы передаем изображение по сети. Это упражнение поможет нам увидеть, что именно каждый слой делает с входным изображением. Именно это и сделали авторы статьи: Понимание нейронных сетей посредством глубокой визуализации. Если вы хотите увидеть это в действии, вы можете использовать разработанный ими инструмент, который можно найти здесь.

3.2: Реконструкция изображения с учетом кода CNN

В предыдущем подразделе мы попытались визуализировать выходные данные промежуточных слоев по мере того, как изображение проходит через сеть, а выходные данные промежуточного слоя также известны как encoding этого изображения этого конкретного слоя. Но можно ли наряду с визуализацией вывода промежуточных слоев построить исходное изображение, используя кодировку изображения? Да, это возможно, и это подробно рассматривается в статье Понимание глубинных представлений изображений путем их инвертирования. Авторы этой статьи провели прямой анализ визуальной информации, содержащейся в промежуточных представлениях, задав вопрос: с учетом кодировки изображения, в какой степени возможно реконструировать само изображение?

Метод, который они использовали, довольно прост. Они спроецировали эту проблему как задачу оптимизации, которая будет вычислять приблизительное обратное представление изображения, так что разница или потеря между исходным представлением изображения (Φ (0)) и тем, которое мы пытаемся выяснить (Φ ( x)) должно быть минимальным.

Здесь x представляет изображение, которое мы пытаемся найти, Φ (0) - результат промежуточного слоя или кодирование изображения, Φ (x) - кодирование изображения, которое мы пытаемся найти, потеря (Φ ( x), Φ (0)) - разница между обоими кодировками, а λR (x) - член регуляризации. Функция потерь, которую они использовали для измерения разницы между двумя кодировками, - это Euclidean distance, которая математически выглядит следующим образом:

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

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

3.3: Какая часть изображения отвечает за классификацию?

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

3.3.1: Эксперимент с окклюзией

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

Чего ожидать от этого эксперимента?

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

Таким образом, теперь мы можем быть уверены, что именно присутствие объекта на изображении отвечает за вывод классификатора изображений.

3.3.2: Карта значимости

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

Они сделали это, просто вычислив градиент выходной оценки изображения (Score(Ic)) по отношению к изображению.

w * = ∂Sc / ∂I: градиент оценки класса по отношению к изображению.

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

3.4: Верно ли наше предположение?

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

Вся наша интуиция и объяснения основаны на наиболее важном и единственном предположении, что подмассивы, присутствующие в сверточном слое, действуют как детекторы признаков, но так ли это на самом деле? Как мы можем убедиться, что подмассивы действуют как детектор признаков? Есть ли способ быть уверенным в этом? Вы держите пари, что есть. Это будет очень важный раздел этой нанокниги, поскольку он будет проверять наши предположения о ConvNets, на которых основана вся эта нанокнига. Подходы, используемые для уверенности в этом, в основном разделены на два лагеря: один ориентирован на набор данных, а другой - на сете.

3.4.1: Сетецентрический подход к пониманию CNN

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

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

Здесь x - это входное изображение, которое нужно создать, ai (x) - значение i-й активации, а Rθ (x) - регуляризация. срок.

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

3.4.2: Подход к пониманию CNN, ориентированный на набор данных

Подход, ориентированный на набор данных, требует как обученной сверточной нейронной сети, так и передачи данных (изображений) через эту сеть. Один из основных подходов, ориентированных на набор данных, был впервые представлен в книге Мэтью Цейлера Визуализация и понимание сверточных сетей. В этой статье они представили технику визуализации, которая выявляет входные стимулы (часть входного изображения), которые возбуждают или активируют отдельные карты признаков на любом слое модели. Для этого они используют деконволюционную нейронную сеть, которую можно рассматривать как модель свертки, в которой используются те же компоненты (объединение, нелинейность), но в обратном порядке. Но вы спросите, что делает deconvnet и как он нам поможет? Поскольку входное изображение проходит через сеть, мы получили карту активации как выход промежуточных слоев, и когда мы прикрепили деконвнет к каждой карте активации, она отображает эти действия обратно в пространство входных пикселей. Отображение конкретной активации обратно в пространство входных пикселей сформирует тот узор в пространстве входных пикселей, который ищет эта активация.

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

Чтобы проверить свертку, деконвнет присоединяется к каждому из ее слоев, как показано на рис. 1 (вверху), обеспечивая непрерывный путь назад к пикселям изображения. Для начала, входное изображение представляется свёртке, а функции вычисляются во всех слоях. Чтобы проверить данную активацию свертки, мы устанавливаем все остальные активации в слое на ноль и передаем карты функций в качестве входных данных в присоединенный слой деконвнета. Затем мы последовательно (i) отменяем пул, (ii) исправляем и (iii) фильтруем, чтобы восстановить активность в нижележащем слое, которая привела к выбранной активации. Затем это повторяется до тех пор, пока не будет достигнуто пространство входных пикселей.

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

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

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

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

И не стесняйтесь связываться со мной в LinkedIn, подписывайтесь на меня в Twitter и Quora.