Как ТАКОЕ заполнение работает в сверточных нейронных сетях, когда шаг больше 1? - PullRequest
3 голосов
/ 12 июля 2020

Я пытаюсь реализовать двумерную свертку в python. У меня есть набор входных изображений с размерами (m, 64, 64, 3), где m - количество изображений. Я хочу использовать размер фильтра f = 8 и stride = 8 как для высоты, так и для ширины, а также ОДИН заполнение, чтобы сохранялись ширина и высота ввода (64, 64).

Используя формулу [ n '= floor ((n-f + 2 * pad) / stride + 1)] и положив n' = 64, n = 64, stride = 8, f = 8, я получу pad = 224 , что неоправданно велико.

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

Но когда я использовал библиотеку Keras и следующий код, он работал нормально.

X = keras.layers.Conv2D(filters=32, kernel_size=(8, 8), strides=(8, 8), padding='same')(X)

Вот моя реализация Conv2D в python:

import numpy as np

# A.shape = (1080, 64, 64, 3)
# W.shape = (8, 8, 3, 32)
# b.shape = (32,)

def conv_fwd(A, W, b, pad=0, stride=1):
    pad_A = np.pad(A, ((0, 0), (pad, pad), (pad, pad), (0, 0)), mode='constant')
    (m, w, h, nc) = A.shape
    (fw, fh, ncc, ncn) = W.shape

    if nc != ncc:
        raise Exception('Number of channels in kernel and input do not match')

    wn = int((w-fw+2*pad)/stride + 1)
    hn = int((h-fh+2*pad)/stride + 1)
    A_n = np.zeros((m, wn, hn, ncn))
    W = W.reshape(fw*fh*ncc, ncn)

    for i in range(wn):
        for j in range(hn):
            A_n[:, i, j] = pad_A[:, i*stride:i*stride+fw, j*stride:j*stride+fh].reshape(m, fw*fh*nc).dot(W) + b
    return A_n

Итак, я предполагаю есть другой процесс расчета заполнения в keras. Я попытался найти исходный код, но не нашел. Как это работает?

1 Ответ

0 голосов
/ 15 июля 2020

В формуле n' = floor((n-f+2*pad)/stride + 1 вы взяли n' == n == 64.

Это неверно. n' is equal to n только когда значение Stride is equal to 1, но здесь Stride больше 1 (8).

Это причина, по которой вы получаете очень высокое значение для Padding.

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

Первоначально создайте модель с Padding = Same, как показано ниже:

import tensorflow as tf
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(filters = 64, strides = (2,2), kernel_size = (3,3), 
input_shape = (64,64,3), padding = 'same'))
print(model.summary())

Краткое описание модели с Padding = Same показано ниже:

Model: "sequential_12"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_25 (Conv2D)           (None, 32, 32, 64)        1792      
=================================================================
Total params: 1,792
Trainable params: 1,792
Non-trainable params: 0

Если мы наблюдаем Shape из Image, это уменьшено с (64,64) до (32,32), хотя Padding == Same.

Теперь создайте модель с Padding = Valid, как показано ниже:

import tensorflow as tf
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(filters = 64, strides = (2,2), kernel_size = (3,3), 
input_shape = (64,64,3), padding = 'valid'))
print(model.summary())

Резюме для выше Модель показана ниже:

Model: "sequential_11"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_24 (Conv2D)           (None, 31, 31, 64)        1792      
=================================================================
Total params: 1,792
Trainable params: 1,792
Non-trainable params: 0

Если мы заметим, Shape из Convolutional Layer равно (None,31,31,64).

Теперь Padding можно получить по формуле ,

Height with SAME Padding - Height with VALID Padding

или

Width with SAME Padding - Width with VALID Padding

т.е. 32 - 31 = 1.

Padding в вашем случае, с Input Shape = (64, 64,3), Filter Size = 8, Strides = 8 равно 1 т.е.

Input равно Wi-Fi с заполнением th 1 строка и 1 столбец нулей .

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