Почему класс MLP ScikitLearn не обновляет веса с помощью регуляризации - PullRequest
0 голосов
/ 16 октября 2019

Я пытаюсь понять правильное использование регуляризации L2 с классификаторами MLP и регрессорами. В настоящее время я изучаю это описание: регуляризация

Я также смотрю на реализацию SciKit Learn здесь . Метод _backprop (удаление комментариев):

def _backprop(self, X, y, activations, deltas, coef_grads,
                  intercept_grads):

n_samples = X.shape[0]

        # Forward propagate
        activations = self._forward_pass(activations)

        # Get loss
        loss_func_name = self.loss
        if loss_func_name == 'log_loss' and self.out_activation_ == 'logistic':
            loss_func_name = 'binary_log_loss'
        loss = LOSS_FUNCTIONS[loss_func_name](y, activations[-1])
        # Add L2 regularization term to loss
        values = np.sum(
            np.array([np.dot(s.ravel(), s.ravel()) for s in self.coefs_]))
        loss += (0.5 * self.alpha) * values / n_samples

        # Backward propagate
        last = self.n_layers_ - 2

        # The calculation of delta[last] here works with following
        # combinations of output activation and loss function:
        # sigmoid and binary cross entropy, softmax and categorical cross
        # entropy, and identity with squared loss
        deltas[last] = activations[-1] - y

        # Compute gradient for the last layer
        coef_grads, intercept_grads = self._compute_loss_grad(
            last, n_samples, activations, deltas, coef_grads, intercept_grads)

        # Iterate over the hidden layers
        for i in range(self.n_layers_ - 2, 0, -1):
            deltas[i - 1] = safe_sparse_dot(deltas[i], self.coefs_[i].T)
            inplace_derivative = DERIVATIVES[self.activation]
            inplace_derivative(activations[i], deltas[i - 1])

            coef_grads, intercept_grads = self._compute_loss_grad(
                i - 1, n_samples, activations, deltas, coef_grads,
                intercept_grads)

        return loss, coef_grads, intercept_grads

Возвращает потерю в виде трех возвращаемых параметров. Но в этом методе потери не используются, даже если к нему добавлено значение регуляризации L2. Пожалуйста, не deltas[last] = activations[-1] - y термин. Это начальный расчет градиента. Работает как для регрессии (с потерей MSE), так и для классификации (с потерей перекрестной энтропии). Но не следует ли к этому добавить термин регуляризации? В противном случае термин регуляризации, по-видимому, вообще не используется при обратном распространении и обновлении весов.

Вышеупомянутый метод вызывается из _fit_stochastic.

Соответствующий код:

batch_loss, coef_grads, intercept_grads = self._backprop(
                        X[batch_slice], y[batch_slice], activations, deltas,
                        coef_grads, intercept_grads)
                    accumulated_loss += batch_loss * (batch_slice.stop -
                                                      batch_slice.start)

                    # update weights
                    grads = coef_grads + intercept_grads
                    self._optimizer.update_params(grads)

batch_loss используется только для изменения accumulated_loss, который контролирует, сколько потерь накапливает модель. Веса обновляются в self._optimizer.update_params(grads), но термин регуляризации здесь не действует.

Если регуляризация не используется, это имеет смысл в качестве окончательной активации - ожидаемый результат становится градиентом потерь. Однако, поскольку используется регуляризация, не следует ли добавлять параметр L2 reg к потере и использовать его для каждого обновления веса?

...