Нейронная сеть: обновление весовой матрицы обратного распространения аффинного уровня в пакетном режиме - PullRequest
0 голосов

Я пытаюсь следовать книге о глубоком обучении, но я нашел некоторую часть об аффинном слое сети сбивающей с толку. Скажем, у меня есть сеть, которая принимает несколько изображений (0 ~ 9), написанных от руки (mnist), которые сведены в одномерный массив, например, np.array([123, 255, 0, ...]), и он будет выводить оценки для каждого возможного выхода, например, np.array([0., 0., 0.3, 0., 0., 0.6, 0., 0., 0., 0.1]) (Таким образом, изображение может быть числом 5).

Вот моя реализация аффинного слоя:

class AffineLayer(object):
    ...
    def backward(self, dy):
        dx = np.dot(dy, self._W.T)
        self._dW = np.dot(self._x.T, dy) # Question related part
        self._db = np.sum(dy, axis=0)
        dx = dx.reshape(self._original_x_shape)
        return dx
    ...

Вот некоторые объяснения:

  • self._W - весовая матрица.
  • Часть беспокойства здесь self._dW = np.dot(self._x.T, y) # Question related part.
  • Эта строка получена из равенства:

    X * W + B = Y
    (N,2) matrix product (2,3) (1,3) (N,3).

  • Обозначение (2,) взято из X.shape из numpy.array и т. Д. Чтобы упростить мою задачу, я выбираю эти номера измерений.

Конец терминологии, теперь возникает вопрос:

С помощью некоторой математики (опущено) мы можем получить равенство, используемое при обратном распространении, (поэтому в коде используется self._dW = np.dot(self._x.T, y)):

d L T d L
--- == X * ---
d W d Y

(2,3) (2,N) * (N,3).

Обратите внимание, что независимо от того, как я настраиваю N, то есть размер партии, размерность dL/dW, весовую матрицу частичной производной от L, не изменится, и она всегда (2,3).

Означает ли это, что суммарный эффект этих N партий объединяется / уплотняется в dL/dW? Это связано с тем, как я реализую выходной слой, например, Softmax-кросс-энтропийный слой в качестве конечного слоя. Мой текущий вывод для этого состоит в том, что N партия означает выполнение обратного распространения N раз, и для градации / амортизации общего эффекта этой партии требуется деление градиента dL/dW на N. Но теперь кажется, что мне нужно сделать это только один раз, и деление должно быть «на первом этапе».

Edit:

Я также нахожу версию, которая, кажется, разделяет ее на последнем шаге mnielsen / neural-network-and-deep-learning - GitHub , для справки.

Так как класс слоя softmax-cross-entropy является последним слоем сети, при обратном распространении он станет "первым шагом", как я упоминал выше:

class SoftmaxCrossEntropy(object):
    ...
    def backward(self, dout=1):
        batch_size = self._t.shape[0]
        # one-hot
        if self._t.size == self._y.size:
            dx = (self._y - self._t) / batch_size # <-- why divided by N here?
        else: # not one-hot
            dx = self._y * 1
            dx[np.arange(batch_size), self._t] -= 1
            dx = dx / batch_size       #    <-- why divided by N here?
        return dx
    ...

1 Ответ

0 голосов

Означает ли это, что влияние этих N групп входных данных объединяется / сгущается в dW?

Так как i-я строка X - это 1-й массив, связанный с i-м сглаженным изображением. Если я перенесу X в

T
X , тогда это столбцы для представления этих сплющенных изображений. Если N увеличится, хотя

размерность результата (dW) не изменится, промежуточные этапы вычисления каждого элемента

T d L
dW = X * ---
d Y , увеличение, что означает

N
dW = Sum ( pixel_info * class_scores_deriv. )
i,j n=1 i,n n,j ,, который N является партией

размер. Ясно, что каждый class_scores_derivative_(n,j) «присоединяется» к определению dW_(i,j), но это подразумевает, что необходимо деление на batch_size = N, потому что приведенное выше суммирование не является средним эффектом этой партии, но мне нужно dW для представляют среднее воздействие этой партии. Если я разделю каждый элемент class_scores_deriv., который является строкой
dx = (self._y - self._t) / batch_size, затем

N 1
Sum ( pixel_info * --- class_scores_deriv. )
n=1 i,n N n,j
1 N
= --- Sum ( pixel_info * class_scores_deriv. )
N n=1 i,n n,j
1
= --- dW
N , что является настоящим dW Я хочу.

Так что ответ (я надеюсь) должен быть

Вся партия определяет dW, но для его сжатия необходимы деления в SoftmaxCrossEntropy::backward(self, dout=1).

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