LeNet – как сочетать формы данных

Здравствуйте и вновь добро пожаловать на занятия по теме «Свёрточные нейронные сети: глубокое обучение на языке Python, часть 3».

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

Для начала давайте вновь рассмотрим базовую архитектуру LeNet. На самом деле она состоит всего из двух простых этапов.

Первый этап – многократное применение свёрточных и агрегационных слоёв – часто их сокращённо называют ConvPool-слоями.

Второй этап – простое использование обычных нейронных сетей, в точности таких же, с которыми мы работали в 1-й и 2-й частях курсов по глубокому обучению.

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

Давайте подробнее рассмотрим первый этап – свёртку и агрегирование:

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

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

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

Теперь обсудим непосредственно форму представления. В первом слое у нас есть ряд изображений, представляющий собой четырёхмерный массив размером NxCxWxH, где N – количество образцов, C – количество цветовых каналов, W – ширина, а H – высота. После проведения свёртки изменится лишь одна из этих размерностей. Действительно, N, конечно же, измениться не может – если у нас N изображений на входе, то должно быть и N изображений на выходе. Ширина и высота могут меняться, хотя и не обязательно. В частности, ширина может измениться до величины [ширина + фильтр – 1] или до величины [ширина – фильтр + 1], или остаться прежней – в зависимости от выбранных параметров в функции свёртки. Не забывайте, что параметры можно настраивать.

Следовательно, у нас остаётся только одна размерность – цвет. Она и будет меняться. Интенсивность цвета можно рассматривать в качестве значения признака.

Таким образом, размерностями фильтра являются: количество входных карт признаков, количество исходящих карт признаков, ширина фильтра и его высота, причём в данном случае не обязательно именно в таком порядке, поскольку Theano и TensorFlow располагают их в разной последовательности.

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

И сугубо чтобы проверить, насколько на данном этапе вы усвоили материал, устроим мини-викторину.

Вопрос: сколько требуется чисел, чтобы определить форму каждого фильтра свёртки?

Даю вам несколько секунд на размышления!

 

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

Рассмотрим простенький пример. Пусть количество изображений равно 15, три цветовых канала, а ширина и высота изображений равна 32; размер фильтра равен (3, 10, 5, 5), где числа представляют соответственно количество входных карт признаков, количество исходящих карт признаков, ширину фильтра и его высоту.

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

Даю минуту на размышление!

 

Ответ: данные будут иметь размер (15, 10, 32, 32), поскольку 15 – количество образцов – остаётся неизменным, ширина и высота изображений, согласно условиям, – также неизменны. Единственное, что поменялось, – количество карт признаков, изменившееся с 3 до 10, где 10 – количество исходящих карт признаков.

Далее мы можем сделать вторую свёртку, в которой количество входных признаков уже будет равно 10. Но вы уже знаете, что неотъемлемой часть LeNet является агрегирование, о котором мы поговорим далее. Технически мы можем установить размер агрегирования (1, 1), что равнозначно отсутствию агрегирования. Такая ситуация – не редкость, но описание причин этого выходит за рамки данного курса.

Перейдём теперь к агрегированию.

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

Проведём ещё одну простейшую мини-викторину.

Мы знаем, что наши данные имеют четыре размерности – NxCxWxH.

Вопрос: на какую из этих размерностей влияет агрегирование?

Даю минуту на размышления.

Ответ: агрегирование затрагивает лишь ширину и высоту.

Агрегирование – это пространственное преобразование. Количество изображений, разумеется, при этом должно оставаться прежним, как и количество карт признаков – мы же не собираемся убирать признаки.

Следующий вопрос мини-викторины.

Мы только что закончили свёртку, и теперь наши данные имеют размер (15, 10, 32, 32), то есть ширина и высота равны 32.

Вопрос: предположим, теперь мы применяем операцию агрегирования с размером пула (2, 2). Каков будет размер данных после агрегирования?

У вас минута на размышления. Или поставьте видео на паузу. Если вы не можете наглядно представить рассматриваемую операцию, советую попробовать нарисовать её на бумаге.

Ответ: (15, 10, 16, 16). Снижение дискретизации в два раза означает, что результат должен быть в два раза меньше входных данных.

Следующее, о чём мы должны поговорить, – о взаимодействии между ConvPool-слоями и слоями прямого распространения.

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

Как же нам вписать четырёхмерный массив в двухмерный?

Ответ тот же, что и при работе с изображениями в нейронных сетях прямого распространения. Напомним, что всё, что нужно сделать, – это сгладить данные, чтобы они стали двухмерными. В нейронной сети прямого распространения каждый входной узел обрабатывается одинаково, так что не имеет значения, из какого цветового канала появился пиксель. Единственная не изменяющаяся размерность – это N, поскольку если у нас есть N изображений на входе, то мы должны получить N изображений и на выходе, которые соответствовали бы N целевых меток. Как вы увидите, и Theano, и Numpy имеют простые функции сглаживания, тогда как в TensorFlow дела с этим обстоят весьма отвратительно.

И наконец последний вопрос нашей мини-викторины!

Предположим, у нас есть ряд изображений с размерами (15, 3, 32, 32), где 15 – количество изображений, 3 – количество цветовых каналов, 32 и 32 – ширина и высота изображений. Предположим также, что все свёртки составлены таким образом, чтобы конечные изображения имели те же ширину и высоту, что и первоначальные. Количество ConvPool-слоёв равно двум. В первом ConvPool-слое количество карт признаков равно 10, ширина фильтра равна 5, высота фильтра также равна 5, а размер пула равен (2, 2). Во втором ConvPool-слое количество карт признаков равно 8, ширина фильтра, как и его высота, равна 3, размер пула вновь-таки равен (2, 2). Имеется один слой прямого распространения с 100 скрытых узлов.

Вопрос: каким должен быть размер матрицы весовых коэффициентов в слое прямого распространения?

Даю минуту на размышления!

Итак, прежде всего надо выяснить размеры данных после первой свёртки. На самом деле мы это уже вычисляли – размеры будут (15, 10, 32, 32). После первого агрегирования они станут равными (15, 10, 16, 16) – это мы тоже уже вычисляли. После второй свёртки они станут равными (15, 8, 16, 16), а после второго агрегирования – (15, 8, 8, 8).

Далее, как мы знаем, нам необходимо сгладить данные. Это значит, что мы должны объединить все данные, за исключением первой размерности, равной 15. Таким образом, данные будут сглажены до двухмерного массива размером (15, 512), а следовательно, каждый входной образец будет представлять собой вектор размером 512. Поскольку размер слоя прямого распространения составляет 100 узлов, то матрица весовых коэффициентов будет иметь размер (512, 100).

У вас может возникнуть вопросы: Сколько вставить ConvPool-слоёв? Сколько вставить слоёв прямого распространения? Какими должны быть размеры фильтра? Какое количество карт признаков использовать?

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

Понравилась статья? Поделить с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: