Обратное распространение ошибки сверточной нейронной сети – путаница

Вопрос или проблема

Я уже прочитал много статей на эту тему, и Градиентный спуск в свёрточных нейронных сетях от Jefkine кажется самым лучшим. Хотя, как сказал автор,

Для простоты мы будем рассматривать случай, когда входное изображение является grayscale, т.е. одноканальным C = 1.

Кроме того, он использует шаг = 1 и предполагает только 1 фильтр для той же цели.

Это окончательные уравнения для обратного распространения (взято из статьи):

Уравнения

Обозначения автора объяснены:

Обозначения

Я разобрался, как выполнять прямое распространение с шагом, глубиной и большим количеством фильтров, но не смог сделать то же самое с обратным распространением. Знаете ли вы, куда поместить 3-ю размерность, шаг и количество фильтров в эти уравнения?

Также, как обратно распространить смещение (предполагая, что есть 1 смещение на фильтр)?

Дайте знать, если что-то непонятно.

Заранее спасибо.

Это часто задаваемый вопрос (см. SO, Quora, Reddit). Я должен признать, что я не до конца понял обобщённое обратное распространение свёртки на 3D-объёмах, особенно когда используется цепная производная без использования вычислительных графов. Но я попробую.

Я буду использовать в основном нотацию из книги по глубокому обучению (скаляр $a$, матрица $\boldsymbol{M}$, $\boldsymbol{\mathsf{M}}$ и т.д.) и для некоторых величин нотацию из книги Нильсена, например, $\delta^l_{…}$ для ошибки нейрона на слое $l$, и буду считать свёрточный слой линейным слоем, т.е. выход является просто результатом свёртки без нелинейности $z^l_{…}$. Это не имеет значения, так как не влияет на размерность операций. Операции свёртки имеют индекс на основе единицы.

Более того, мы будем считать, что ошибка на выходе свёрточного слоя известна, так что нет необходимости рассматривать какой-либо другой слой. Далее, чтобы упростить нотацию, мы будем рассматривать одноэкземплярные пакеты и опустим размерность пакета. Наконец, мы предположим нулевую подкладу и шаг равный единице (извините, но иначе это становится слишком сложно).

Теперь у нас есть:

  1. $l$ – это $l$-й слой, где $l=1$ – это первый слой, а $l=\ell$ – последний слой.

  2. Входной тензор $\boldsymbol{\mathsf{X}} \in \mathbb{R}^{n \times
    n \times
    n}$
    с размерами ширина $w$, высота $h$ и три канала $c$.

  3. Тензор ядра $\boldsymbol{\mathsf{K}} \in \mathbb{R}^{n \times
    n \times
    n \times n}$
    с размерами ширина $m$, высота $n$, три канала $c$ и $k$ ядер, которые будут производить $k$ карты признаков.

  4. Каждое ядро $k$ в $\boldsymbol{\mathsf{K}}_{:,:,:,k}$ имеет веса $w_{…}$.

  5. Производная функции потерь $J$ по активации входа $z^l_{x,y,z}$, скажем, определяется как

    \begin{equation}
    \delta^l_{x,y,z} = \frac{\partial J}{\partial \; z^l_{x,y,z}}
    \end{equation}

Сначала нам нужно переформулировать уравнения в соответствующей форме:

3D-свёртка действует так, что один элемент на выходе $\mathsf{M}{\,}^{l}_{i,j,k}$ является скалярным результатом перемножения и сложения соответствующих элементов входа с одним ядром, веса которого $w^l_{m,n,c,k}$. То есть,

\begin{align}
{\big( (\boldsymbol{\mathsf{I}} * \boldsymbol{\mathsf{K}})(i,j,k)
\big)}^l
&= \sum_{c}
\sum_{m} \sum_{n} x^{l – 1}_{i + m – 1,j + n – 1,c} \cdot w^l_{m,n,c,k}
\label{eq:cross_correlation_3d_1}\\
z^l_{i,j,k} &= {\big( (\boldsymbol{\mathsf{I}} *
\boldsymbol{\mathsf{K}})(i,j,k) \big)}^l + b^l\\
\mathsf{M}{\,}^{l}_{i,j,k} &=
z^l_{i,j,k}.\label{eq:cross_correlation_3d_3}
\end{align}

Здесь $i,j,k$ – это итераторы вывода.

Стратегия, которую мы будем следовать, – это та, что объяснена Нильсеном с некоторыми изменениями приоритетов, т.е. сначала мы выведем правило обратного распространения ($\delta^l_{\cdot,\cdot,\cdot}$ в терминах $\delta^{l +
1}_{\cdot,\cdot,\cdot}$
). Во-вторых, выведем ошибку весов (производная потерь по весам ядра) в терминах $\delta^{l + 1}_{\cdot,\cdot,\cdot}$.

Вывод в 2D-случае предполагает, что в итоге мы получим некий вид свёртки ошибки слоя с ядрами.

Давайте начнем с ошибки одного элемента на слое $\delta^l_{m,n,u}$ по отношению к ошибке на слое $\delta^{l + 1}_{i,j,k}$. Чтобы применить цепное правило, нам нужно определить, какие выходные элементы $z^{l + 1}_{i,j,k}$ зависят от входного элемента $z^l_{m,n,u}$, чтобы мы могли складывать частные производные. Одним важным наблюдением является то, что один входной элемент влияет на все карты признаков (хотя не на все элементы), поэтому мы должны суммировать по всем выходным каналам $k$. Ещё одно (тривиальное?) наблюдение состоит в том, что многоканальная $\boldsymbol{\mathsf{K}}$ не перемещается по размерности глубины, поэтому индекс не содержит смещений. После того, как мы учли каналы, мы также должны учесть влияние входного элемента $z^l_{m,n,u}$ на одном конкретном выходном канале $z^l_{:,:,k}$. Используя 2D-аналогию, мы можем сказать, что данное конкретное ядро $k$ влияет на некоторые элементы в этом канале, а именно элементы, фиксированные на позициях $m,n$, и это результаты от ядра, которое было сдвинуто на $-a, -b$ (перспектива входа, мы вводим вспомогательные индексы $a$ и $b$). Наконец, мы знаем, что все ядра имеют одинаковую размерность (они упакованы в один 4D-тензор), таким образом, мы можем использовать одни и те же итераторы $a,b$ для всех ядер. Эти наблюдения приводят к

\begin{align}
\delta^l_{m,n,u} &= \sum_{k} \sum_a \sum_b \frac{\partial
J}{\partial \; z^{l +
1}_{m – a + 1,n – b + 1,k}}
\cdot \frac{\partial z^{l + 1}_{m – a + 1,n – b + 1,k}}{\partial
z^l_{m,n,u}}\label{eq:delta1}\tag{1}\\
&= \sum_{k} \sum_a \sum_b \delta^{l +
1}_{m – a + 1,n – b + 1,k}
\cdot \frac{\partial z^{l + 1}_{m – a + 1,n – b + 1,k}}{\partial
z^l_{m,n,u}}.\label{eq:delta2}\tag{2}
\end{align}

Это был один из самых сложных шагов, где я мог совершить ошибки. Не стесняйтесь исправлять меня.

Здесь мы, как обычно, подменили ошибку $\frac{\partial
J}{\partial \; z^{l + 1}_{m – a + 1,n – b + 1,k}}$
её определением
$\delta^{l +
1}_{m – a + 1,n – b + 1,k}$
.

Вы знаете, куда это ведет.

Теперь мы сосредоточимся на втором термине справа и развернем его. Здесь, снова мы вводим вспомогательные индексы $p, q, r$ и используем $x^l_{…} = z^l_{…}$ (как упоминалось, мы имеем дело с линейными слоями).

\begin{align}
\frac{\partial z^{l + 1}_{m – a + 1,n – b + 1,k}}{\partial z^l_{m,n,u}} &=
\frac{\partial}{\partial z^l_{m,n,u}} \Big(
\sum_{p} \sum_{q} \sum_{r} z^{l}_{(m – a + 1) + p – 1,(n – b + 1) + q – 1,r}
\cdot w^{l +
1}_{p,q,r,k}\Big)\label{eq1}\tag{3}\\
&=
\frac{\partial}{\partial z^l_{m,n,u}} \Big(
\sum_{p} \sum_{q} \sum_{r} z^{l}_{m – a + p,n – b + q,r}
\cdot w^{l + 1}_{p,q,r,k}\Big)\label{eq2}\tag{4}\\
&=
\frac{\partial}{\partial z^l_{m,n,u}} \Big( z^{l}_{m,n,u}
\cdot w^{l + 1}_{a,b,u,k}\Big)\label{eq3}\tag{5}\\
&= w^{l + 1}_{a,b,u,k}.\label{eq4}\tag{6}
\end{align}

В уравнении \ref{eq1} мы развернули, как упоминалось выше, затем в уравнении \ref{eq2} мы уменьшили индексы в соответствии с $(m – a + 1) + p – 1 = m – a + p, (n – b + 1) + q – 1 =
n – b + q$
. В уравнении \ref{eq3} мы наблюдаем, что все частные производные по отношению к $z^l_{m,n,u}$, за исключением случаев, когда $a = p, b = q, r = u$. Соответственно, веса должны иметь индексы $a,b,u,k$. Затем, подставляя уравнение \ref{eq4} в уравнение \ref{eq:delta2}, мы имеем:

\begin{align}
\delta^l_{m,n,u} &= \sum_{k} \sum_a \sum_b \delta^{l +
1}_{m – a + 1,n – b + 1,k}
\cdot w^{l + 1}_{a,b,u,k}.\label{eq:final1}\tag{7}
\end{align}

Вторая по сложности часть – это как интерпретировать уравнение \ref{eq:final1}. Как упоминалось выше, ясно, что это некий вид свёртки между ошибкой в конце свёрточного слоя (ошибкой, которую она получает от верхнего слоя) с тензором ядра. Одно, что мы можем сделать, это преобразовать (повернуть?) ядро, чтобы перепорядочить индексы, т.е.

\begin{align}
\delta^l_{m,n,u} &= \sum_{k} \sum_a \sum_b \delta^{l +
1}_{m – a + 1,n – b + 1,k}
\cdot w^{l + 1}_{a,b,k,u}.\label{eq:final2}\tag{8}
\end{align}

В уравнении \ref{eq:final2} мы видим, что нам нужно собрать все частные производные, соответствующие элементам во всех каналах $k$, которые были сгенерированы каналом $u$. Это не очень интуитивно и сложно визуализировать (по крайней мере для меня), так как все входные каналы комбинируются/сливаются для создания карты признаков. Так как же мы можем разделить карту признаков, чтобы собрать специфические входные элементы одного канала, которые были смешаны для формирования карты признаков? Оказывается, это возможно, если вы думаете в алгебраических терминах. Выход является тензором, и следовательно, при наличии правильных индексов операция может быть выполнена. Эта стандартная 3D-свёртка, безусловно, может быть выражена как 3D-кросс-корреляция. Идеи приветствуются.

Интересный конкретный пример представлен в Aggarwal 2018 на странице 355:

Чтобы понять приведённую выше транспозицию, рассмотрите ситуацию, в которой мы используем 20 фильтров на 3-канальном RGB-объёме для создания выходного объёма глубиной 20. При обратном распространении нам необходимо взять градиентный объём глубиной 20 и преобразовать его в градиентный объём глубиной 3. Поэтому нам нужно создать 3 фильтра для обратного распространения, каждый из которых предназначен для красного, зелёного и синего цветов. Мы извлекаем 20 пространственных срезов из 20 фильтров, которые применяются к красному цвету, инвертируем их, используя подход, показанный на рисунке 8.7, а затем создаём единственный фильтр глубиной 20 для обратного распространения градиентов в отношении красного среза. Аналогичные подходы используются для зелёных и синих срезов. Транспозиция и инверсия в уравнении 8.3 соответствуют этим операциям.

Производные функции стоимости по отношению к весам ядра и смещения оставлены в качестве упражнения 😉

Ответ или решение

Обратное распространение в сверточных нейронных сетях: Разъяснение сложностей

Обратное распространение в сверточных нейронных сетях (CNN) является одной из ключевых тем в области глубокого обучения. Несмотря на обилие ресурсов в сети, многие сталкиваются с трудностями в понимании работы алгоритма, особенно когда дело доходит до многомерных (3D) входов и множественного количества фильтров. Давайте подробнее рассмотрим этот процесс.

Основные концепции

  1. Сверточный слой – работает с многомерными входными данными, такими как цветные изображения. Обычно они представляются в виде тензоров с заданными размерами, где первыми измерениями являются высота и ширина изображения, а последним измерением – количество каналов (например, RGB).

  2. Фильтры – используются для извлечения признаков из изображений. Каждый фильтр имеет свои параметры (веса) и применяется ко всем полосам входного тензора. Это приводит к созданию многих выходных карт признаков.

  3. Ошибка (loss) – на каждом этапе обучения мы вычисляем ошибку на выходе слоя, используя функцию потерь.

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

В вашем случае существует несколько переменных, усложняющих процесс обратного распространения:

  • Многомерные данные (глубина – количество каналов);
  • Множественные фильтры;
  • Шаг (stride) – способ перемещения фильтра по входному объему.

Обратное распространение для многоканальных данных и фильтров

Обратное распространение в CNN можно разбить на несколько этапов:

  1. Выход проблемной ошибки:

    • Для заданного элемента ошибки на выходе CNN, (\delta^{l+1}{i,j,k}), нам нужно вычислить, как это значение влияет на элемент во входном слое (\delta^l{m,n,u}).
    • Учитывая, что каждый элемент входа может повлиять на множественные элементы в выходном пространстве, нужно аккуратно суммироватьContribution от всех фильтров и всех выходных карт.
  2. Переход от выходных значений к входным:

    • Это осуществляется с помощью свертки. Формально, ошибка в слое (l) может быть вычислена следующим образом:
      [
      \delta^l{m,n,u} = \sum{k} \sum{a} \sum{b} \delta^{l+1}{m – a + 1, n – b + 1, k} \cdot w^{l+1}{a,b,u,k}
      ]
      Здесь мы берем во внимание, что каждый фильтр может влиять на многоканальную карту выходного признака.
  3. Ошибки весов:

    • Ошибки весов фильтров можно вычислить, используя сумму производных ошибки по соответствующему выходу. Это делается по схеме:
      [
      \frac{\partial J}{\partial w^{l}{p,q,u,k}} = \sum{m,n} \delta{m,n,k} \cdot z^{l-1}{i,j,u}
      ]

Обратное распространение для смещения

Когда речь идет о смещениях (bias), их можно обрабатывать аналогично: учитывая, что на каждый фильтр навешивается одно смещение, нужно просто суммировать ошибки выходов по всем узлам:

[
\frac{\partial J}{\partial b^{l}{k}} = \sum{m,n} \delta^{l}_{m,n,k}
]

Заключение

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

Если после этого у вас останутся дополнительные вопросы или потребуется помощь в более глубоком составлении алгоритмов, не стесняйтесь обращаться.

Оцените материал
Добавить комментарий

Капча загружается...