Реализация обратной связи сверточной нейронной сети в ArrayFire (вычисление градиента)

Я изменил уравнение 9.12 в http://www.deeplearningbook.org/contents/convnets.html для центрирования ядра свертки MxN.

Это дает следующее выражение (примите пока на веру) для градиента, предполагая 1 входной и 1 выходной канал (для упрощения):

dK(krow, kcol) = sum(G(row, col) * V(row+krow-M/2, col+kcol-N/2); row, col)

Чтобы прочитать вышеизложенное, единственный элемент dK в krow, kcol равен сумме по всем строкам и столбцам произведения G, умноженного на сдвинутое V. Обратите внимание, что G и V имеют одинаковые размерности. Мы определим, что выход за пределы V приводит к нулю.

Например, в одном измерении, если G равно [a b c d], V равно [w x y z], а M равно 3, то первая сумма будет точечной (G, [0 w x y]), вторая сумма будет точечной (G, [w x y z ]), а третья сумма — точка (G, [x y z 0]).

В ArrayFire есть операция сдвига, но она выполняет циклический сдвиг, а не сдвиг с нулевой вставкой. Кроме того, размеры ядра MxN обычно малы, например, 7x7, поэтому кажется, что более оптимальной реализацией будет чтение G и V только один раз и накопление по ядру.

Для этого одномерного примера мы будем читать a и w,x и начинать с [a*0 aw ax]. Затем мы читаем b,y и добавляем [bw bx by]. Затем прочитайте c,z и добавьте [cx cy cz]. Затем прочтите d и, наконец, добавьте [dy dz d*0].

Есть ли прямой способ вычислить dK в ArrayFire? Я не могу не думать, что это какая-то свертка, но я не мог понять, как эта свертка будет выглядеть.


person Walt Donovan    schedule 03.04.2016    source источник
comment
Вы понимаете, что пытаетесь реализовать свертку, используя сумму, верно? Это очень и очень неэффективно. В ArrayFire есть функции с именами wrap и unwrap, которые позволяют преобразовывать (с шагом) свертки в умножение матриц. Это то, что вам нужно использовать.   -  person Pavan Yalamanchili    schedule 04.04.2016


Ответы (1)


Ах так. Для массива 3x3 dK я использую unwrap для преобразования моих входных массивов MxN в два вектора-столбца MxN. Затем я делаю 9 точечных произведений сдвинутых подмножеств двух векторов-столбцов. Нет, это не работает, так как сдвиг происходит в 2 измерения.

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

Хм, это требует слишком много памяти (иногда). Таким образом, окончательное решение состоит в том, чтобы выполнить gfor для вывода 3x3 и для каждого цикла сделать скалярное произведение развернутого один раз G и развернутого многократно V.

Согласовано?

person Walt Donovan    schedule 05.04.2016