2016-04-03 1 views
2

Я модифицировал уравнение 9.12 в http://www.deeplearningbook.org/contents/convnets.html для центрирования ядра свертки MxN.Реализация сверточного нейронного сетевого backprop в массиве ArrayFire (расчет градиента)

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

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

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

Например, в одном измерении, если G является [abcd], V является [wxyz], а M равно 3, тогда первая сумма - точка (G, [0 wxy]), вторая сумма - точка (G, [wxyz]), а третья сумма - точка (G, [xyz 0]).

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

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

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

+0

Вы понимаете, что пытаетесь реализовать сверток, используя сумму справа? Это очень неэффективно. ArrayFire имеет функции, называемые 'wrap' и' unwrap', которые позволят вам преобразовывать (strided) свертки в матричные умножения. Это то, что вам нужно использовать. –

ответ

2

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

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

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

Согласен?

Смежные вопросы