Educode — реализация сверточной нейронной сети

Проход 1: реализовать прямое распространение сверточного слоя

детали миссии

Задача этого уровня: реализовать прямое распространение сверточного слоя.

связанная информация

Для того, чтобы выполнить эту задачу, вам необходимо освоить:

  1. Проблемы в полносвязном слое;
  2. Что такое свертка;
  3. Что такое сверточный слой.

Содержание этого тренинга см. в главе 7 книги «Введение в глубокое обучение — теория и реализация на основе Python».

Проблемы с полносвязными слоями

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

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

С другой стороны, накладные расходы на вычисления и хранение на полностью подключенном уровне огромны. Все еще возьмем изображение в качестве примера, для изображения 224 × 224 × 3 (ширина и высота 224 пикселя, с тремя цветовыми каналами RGB), если мы хотим изменить количество каналов на 64, на выходе будет 224 × 224 × 64 карты объектов. Если используется полносвязный слой, всего требуется 224×224×3×224×224×64=483385147392 параметров и операций умножения и сложения, для простого хранения этих параметров требуется 1,7 ТБ места, что явно невыносимо. И если вы используете сверточный слой 3 × 3, который мы представим позже, вам потребуется только 64 × 3 × 3 × 3 = 1728 параметров и 224 × 224 × 64 × 3 × 3 × 3 = 86704128 операций умножения и сложения, общая память И вычислительные накладные расходы значительно уменьшились.

Операции свертки и сверточные слои

Операция свертки — очень распространенная операция в области обработки изображений, которая фактически является своего рода фильтрацией. Для входного изображения H×W операция свертки сдвигает ядро ​​свертки Kh×Kw на входное изображение, а ввод входного изображения в окно умножается на элемент в соответствующей позиции ядра свертки. чтобы получить окончательный результат. На рисунке ниже показаны этапы операции свертки.


Рис. 1. Операция свертки

Чтобы управлять методом скользящего окна операции свертки и формой выходной карты объектов, также вводятся две концепции шага и площадки.Для входных данных H×W ядро ​​свертки равно Kh×Kw, для операции свертки с размером шага S и заполнением P размер выходного изображения Ho​×Wo​ можно рассчитать по следующей формуле:

Ho​=(H−Kh​+2P)/S+1Wo​=(W−Kw​+2P)/S+1​

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

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


Рис. 2 Расчет сверточного слоя

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

Реализация сверточного слоя

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

Обучение имеет предопределенный Convolutionкласс, в конструкторе этого класса он получает соответствующий вес W, смещение b, размер шага strideи отступы pad. Вес W— это N×C×Kh×Kw numpy.ndarray, смещение b— это длина M numpy.ndarray, где N — количество выходных каналов, C — количество входных каналов, Kh и Kw — размеры свертки. ядро.

В этом упражнении вам нужно реализовать функцию прямого прохода forward(). forward()Вход функции x— размерность, равная 4 numpy.ndarray, форма — (B, C, H, W), где B — размер партии. Прежде всего, вам нужно xработать с im2col, обучение предоставило im2colоперацию, которая преобразует карту входных признаков в матрицу (B × Ho × Wo, Kh × Kw × C), каждая строка представляет собой окно свертки . Стоит отметить, что поскольку преобразованная матрица карты признаков равна (B×Ho×Wo, Kh×Kw×C), а вес W равен Co, C, Kh, Kw, следовательно, Когда мы реализуем это, нам нужно изменить форму W один раз, чтобы стать Co​, C×Kh​×Kw​, затем выполнить транспонирование, а затем выполнить матричное умножение:

Fo​^​=im2col(F)×W^T

В настоящее время Fo​^​ представляет собой (B×Ho​×Wo​, Co​), в настоящее время его можно преобразовать в (B, Co​, Ho​, Wo​) с помощью одной операции изменения формы и транспонирования Fo .

im2colОпределения функций, предоставляемых обучением, следующие: im2col(input_data, filter_h, filter_w, stride=1, pad=0), а значения соответствующих параметров:

  1. input_data: входная карта объектов;
  2. filter_hи filter_w: высота и ширина окна объединения;
  3. stride: размер шага объединения;
  4. pad: объединенное заполнение.

требования к программированию

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

Инструкция по тестированию

Платформа будет тестировать код, который вы пишете. Метод тестирования: платформа случайным образом генерирует входные данные x, веса Wи смещения b, а затем создает экземпляр класса в соответствии с вашим кодом реализации, Convolutionа затем использует этот экземпляр для выполнения вычислений прямого распространения. и сравните со стандартными ответами для сравнения. Потому что вычисление чисел с плавающей запятой может иметь ошибки, если ошибка между вашим ответом и стандартным ответом не превышает 10−5.

Пример ввода:

 
 
  1. x:
  2. [[[[0.7 0.25 0.87 0.76]
  3. [0.13 0.87 0.02 0.29]
  4. [0.81 0.92 0.7 0.13]
  5. [0.67 0.01 0.69 0.46]]
  6. [[0.41 0.78 0.91 0.3 ]
  7. [0.56 0.73 0.88 0.2 ]
  8. [0.47 0.06 0.41 0.24]
  9. [0.79 0.2 0.84 0.2 ]]]
  10. [[[0.94 0.19 0.83 0.79]
  11. [0.93 0.65 0.68 0.98]
  12. [0.16 0.9 0.15 0.71]
  13. [0.49 0.21 0.89 0.33]]
  14. [[0.56 0.82 0.6 0.11]
  15. [0.98 0.73 0.86 0.29]
  16. [0.48 0.31 0.96 0.73]
  17. [0.86 0.94 0.78 0.57]]]]
  18. W:
  19. [[[[ 0.73 0.61 0.31]
  20. [-1.07 -1.13 -0.19]
  21. [-0.24 0.9 -1.68]]
  22. [[-0.59 -0.84 -0.37]
  23. [-0.74 -0.83 -0.23]
  24. [ 0.26 0.44 -0.42]]]
  25. [[[-0.4 0.42 1.27]
  26. [ 0.94 -0.58 1.41]
  27. [-1.91 -1.18 1.93]]
  28. [[-0.03 -1.14 0.72]
  29. [-2.05 -0.45 -0.6 ]
  30. [-0.84 0.1 -0. ]]]]
  31. b:
  32. [1.62 1.12]
  33. stride: 1
  34. pad: 1

Тогда соответствующая карта выходных объектов:

 
 
  1. [[[[-1.14 0.1 -1.35 -0.52]
  2. [-0.08 -1.59 -0.81 0.93]
  3. [ 0.59 -2.91 -0.92 0.28]
  4. [ 0.51 0.7 0.52 -0.28]]
  5. [[ 2. -0.53 -1.93 -1.6 ]
  6. [ 3.15 -2.23 -1.62 -3.13]
  7. [ 2.07 0.59 0.42 -1.93]
  8. [ 1.29 1.66 0.27 -0.83]]]
  9. [[[-0.26 -1.56 -1.55 0.36]
  10. [-1.97 -1.57 -2.57 0.73]
  11. [ 0.55 -1.75 -0.36 0.22]
  12. [-0.04 -1.09 -1.43 -1.38]]
  13. [[ 0.35 -0.79 -0.78 -3. ]
  14. [ 2.82 -1.5 0.63 -2.71]
  15. [ 2.43 -0.31 0.33 -4.35]
  16. [ 1.08 0.88 -1.33 -0.7 ]]]]

Приведенные выше результаты имеют ошибки округления, которые можно игнорировать.

Код реализации:

импортировать numpy как np

из utils импортировать im2col


 

свертка класса:

    def __init__(self, W, b, шаг=1, блокнот=0):

        р'''

        Инициализация сверточного слоя

        Параметр:

        - W: numpy.array, (C_out, C_in, K_h, K_w)

        - b: numpy.array, (C_out)

        - шаг: интервал

        - колодка: внутр.

        '''

        сам.W = W

        я.б = б

        self.stride = шаг

        self.pad = блокнот

    защита вперед (я, х):

        р'''

        Прямое распространение сверточных слоев

        Параметр:

        - x: numpy.array, (B, C, H, W)

        Возвращаться:

        - y: numpy.array, (B, C', H', W')

             Н' = (Н - Х + 2П) / S + 1

             Вт' = (Вт - кВт + 2P) / S + 1

        '''

        ########## Начинать ##########

        FN, C, FH, FW = self.W.shape

        N, C, H, W = x.shape

        out_h = int(1 + (H + 2 * self.pad - FH) / self.step)

        out_w = int(1 + (W + 2 * self.pad - FW) / self.stride)

        col = im2col(x, FH, FW, self.stride, self.pad)

        col_w = self.W.reshape(FN, -1).T

        out = np.dot(col, col_w) + self.b

        out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)

        вернуться

        ########## Конец ##########

Проход 2: реализовать прямое распространение слоя пула

детали миссии

Задача этого уровня: реализовать прямое распространение слоя пула.

связанная информация

Для того, чтобы выполнить эту задачу, вам необходимо освоить:

  1. Рецептивное поле и субдискретизация;
  2. Определение объединяющего слоя.

Содержание этого тренинга см. в главе 7 книги «Введение в глубокое обучение — теория и реализация на основе Python».

Рецептивное поле и субдискретизация

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

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

объединяющий слой

Слой пула подобен сверточному слою, перемещая окно на карте входных объектов и вычисляя значение объекта в окне с помощью функции сокращения для получения выходного значения. Слой пула, который использует max в качестве функции разрешения, называется пулом max, а слой пула, который использует среднее значение в качестве функции разрешения, называется пулом среднего, и оба они очень часто используются. Обычно слой пула устанавливает размер окна Kh​×Kw​, а также шаг и отступы. Обычно используемая конфигурация объединяющего слоя: Kh​=Kw​=2, размер шага равен 2, а отступ равен 0. Этот объединяющий слой может уменьшить длину и ширину карты объектов наполовину. На рисунке ниже показано, как рассчитывается максимальный пул.


Рисунок 1 Максимальное объединение

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

Реализация слоя пула

При реализации объединяющего слоя он аналогичен реализации сверточного слоя.Чтобы в полной мере использовать удобство расчета матриц, входную карту объектов обычно преобразуют в большую матрицу посредством одной операции.Каждая строка этой матрицы im2colсоответствует одно из окон пула. Таким образом, операция свертки становится построчной максимальной или средней операцией. Для конкретного анализа, пожалуйста, обратитесь к введению в разделах 7.3 и 7.5 учебника.

В этом упражнении вам нужно только реализовать максимальное объединение. Обучение имеет предопределенный MaxPoolкласс, и в конструкторе этого класса он принимает соответствующий размер окна пула pool_h, pool_wшаг strideи отступы pad.

В этом упражнении вам нужно реализовать функцию прямого прохода forward(). forward()Вход функции x— размерность, равная 4 numpy.ndarray, форма — (B, C, H, W), где B — размер партии. Прежде всего, вам нужно xработать с im2col, обучение предоставило im2colоперацию, которая преобразует карту входных признаков в матрицу (B × Ho × Wo, Kh × Kw × C), каждая строка представляет собой окно свертки .

требования к программированию

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

Инструкция по тестированию

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

Пример ввода:

 
 
  1. x:
  2. [[[[0.7 0.25 0.87 0.76]
  3. [0.13 0.87 0.02 0.29]
  4. [0.81 0.92 0.7 0.13]
  5. [0.67 0.01 0.69 0.46]]
  6. [[0.41 0.78 0.91 0.3 ]
  7. [0.56 0.73 0.88 0.2 ]
  8. [0.47 0.06 0.41 0.24]
  9. [0.79 0.2 0.84 0.2 ]]]
  10. [[[0.94 0.19 0.83 0.79]
  11. [0.93 0.65 0.68 0.98]
  12. [0.16 0.9 0.15 0.71]
  13. [0.49 0.21 0.89 0.33]]
  14. [[0.56 0.82 0.6 0.11]
  15. [0.98 0.73 0.86 0.29]
  16. [0.48 0.31 0.96 0.73]
  17. [0.86 0.94 0.78 0.57]]]]
  18. pool_h: 2
  19. pool_w: 2
  20. stride: 2
  21. pad: 0

Тогда соответствующий выходной нейрон:

 
 
  1. [[[[0.7 0.87]
  2. [0.92 0.7]]
  3. [[0.78 0.91]
  4. [0.79 0.84]]]
  5. [[[0.94 0.98]
  6. [0.49 0.89]]
  7. [[0.98 0.86]
  8. [0.94 0.96]]]]

Давайте начнем вашу миссию, я желаю вам успеха!


Код реализации: 

импортировать numpy как np

из utils импортировать im2col


 

класс Макспул:

    def __init__(self, pool_h, pool_w, шаг=1, блокнот=0):

        р'''

        Инициализация слоя пула

        Параметр:

        - pool_h: целое

        - pool_h: целое

        - шаг: интервал

        - колодка: внутр.

        '''

        self.pool_h = pool_h

        self.pool_w = pool_w

        self.stride = шаг

        self.pad = блокнот

    защита вперед (я, х):

        р'''

        Прямое распространение слоя пула

        Параметр:

        - x: numpy.array, (B, C, H, W)

        Возвращаться:

        - y: numpy.array, (B, C, H', W')

             Н' = (Н - Х + 2П) / S + 1

             Вт' = (Вт - кВт + 2P) / S + 1

        '''

        ########## Начинать ##########

        N, C, H, W = x.shape

        out_h = int(1 + (H - self.pool_h) / self.stride)

        out_w = int(1 + (W - self.pool_w) / self.stride)

        col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)

        col = col.reshape(-1, self.pool_h * self.pool_w)

        выход = np.max (столбец, ось = 1)

        out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)

        вернуться

        ########## Конец ##########

 

рекомендация

отblog.csdn.net/qq_57409899/article/details/124616135
рекомендация