Изменение весов фильтров в сверточном слое нейронной сети - PullRequest
0 голосов
/ 29 ноября 2018

Я изучаю архитектуру работы сверточных нейронных сетей.В процессе реализации я столкнулся с проблемой изменения весов в фильтрах.

Для простоты рассмотрим следующую структуру слоев:

    +-----------------------------------+
    |        Input image volume         |
    |               HxWxD               |
    +-----------------------------------+
                       |
    +-----------------------------------+
    |         Convolution layer         |
    |                                   |
    |      in: HxWxD, out: H1xW1xD1     |
    |                                   |
    |     K filters with size FxFxD     |
    |    S - stride, P - zero padding   |
    |    H1 = (H - F + 2P) / S + 1      |
    |    W1 = (W - F + 2P) / S + 1      |
    |              D1 = K               |
    +-----------------------------------+
                       |
    +-----------------------------------+
    |             ReLU layer            |
    |                                   |
    |    in: H1xW1xD1, out: H2xW2xD2    |
    |                                   |
    |     H2 = H1, W2 = W1, D2 = D1     |
    +-----------------------------------+
                       |
    +-----------------------------------+
    |          Maxpooling layer         |
    |                                   |
    |    in: H2xW2xD2, out: H3xW3xD3    |
    |                                   |
    |            scale [= 2]            |
    |          H3 = H2 / scale          |
    |          W3 = W2 / scale          |
    |              D3 = D2              |
    +-----------------------------------+
                       |
         [convert volume to vector]
         [W3xH3xD3 -> W3*H3*D3 = N]         
                       |
    +-----------------------------------+
    |        Full connected layer       |
    |                                   |
    |           in: N, out: M           |
    |                                   |
    |           W: matrix MxN           |
    |         activate: sigmoid         |
    +-----------------------------------+
                       |

Для еще большего упрощения рассмотримпример изображения 32x32 RGB.

Входной объем будет измеряться 32x32x3. В сверточном слое мы будем использовать K = 4 фильтра размером 5x5x3, с S = 1, P = 0, то есть слоем изVolume 32x32x3 получит объем 28x28x4 путем свертки входного объема с каждым из K фильтров.Слой ReLU сбрасывает все отрицательные числа в объеме и возвращает его, так что на выходе снова будет слой 28x28x4. Макспулирующий слой с множителем 2 превратит объем 28x28x4 в объем 14x14x4. Полностью подключенный слой получит вектор 14 * 14.* 4 = 784 элемента на входе, умножив его на матрицу W = [10x784] (мы распознаем 10 классов), получим вектор из 10 элементов со значениями от 0 до 1 (как активируется сигмоидом).После этого мы находим вектор ошибки e, который мы распространяем обратно, умножая транспонированную матрицу W на вектор e, и преобразуем его в объем 14x14x4, последовательно вводя его так же, как и преобразовывая объем в вектор.

Слой maxpooling вернет объем 28x28x4, в котором будут нули в немаксимальных элементах и ​​в элементах, где максимальным значением были соответствующие значения объема 14x14x4.

Уровень ReLU умножает каждый элемент на 1 или 0, в зависимости от того, получено ли положительное или отрицательное число на выходе, и возвращает тот же слой 28x28x4.

И здесь возникает проблема.Чтобы получить изменение весов, необходимо выполнить свертку входного объема 32x32x3 с объемом 28x28x4, получая при этом 4 тома 5x5x3.Предполагая, что дельта-объем разбит на 4 тома 28x28x1, но опять же, как получить 5x5x3, а не 5x5x1, чтобы изменить веса?

Еще раз кратко:

Вперед: [32x32x3]=> свертка с 4 фильтрами [5x5x3] => [28x28x4] => ReLu => [28x28x4] => maxpooling => [14x14x4] => векторизация => [784] => W * X => [10]

в обратном направлении: [10] => W ^ T * e => [784] => 'volumize' => [14x14x4] => unpool => [28x28x4] => * relu grad => [28x28x4] => ???

...