Предупреждение с использованием SciPy fmin_bfgs () для упорядоченных данных - PullRequest
0 голосов
/ 02 мая 2018

Я использую следующие cost() и gradient() регуляризованные функции:

def cost(theta, x, y, lam):
    theta = theta.reshape(1, len(theta))
    predictions = sigmoid(np.dot(x, np.transpose(theta))).reshape(len(x), 1)

    regularization = (lam / (len(x) * 2)) * np.sum(np.square(np.delete(theta, 0, 1)))

    complete = -1 * np.dot(np.transpose(y), np.log(predictions)) \
           - np.dot(np.transpose(1 - y), np.log(1 - predictions))
    return np.sum(complete) / len(x) + regularization


def gradient(theta, x, y, lam):
    theta = theta.reshape(1, len(theta))
    predictions = sigmoid(np.dot(x, np.transpose(theta))).reshape(len(x), 1)

    theta_without_intercept = theta.copy()
    theta_without_intercept[0, 0] = 0
    assert(theta_without_intercept.shape == theta.shape)
    regularization = (lam / len(x)) * np.sum(theta_without_intercept)

    return np.sum(np.multiply((predictions - y), x), 0) / len(x) + regularization

С этими функциями и scipy.optimize.fmin_bfgs() я получаю следующий вывод (что почти правильно):

Starting loss value: 0.69314718056 
Warning: Desired error not necessarily achieved due to precision loss.
         Current function value: 0.208444
         Iterations: 8
         Function evaluations: 51
         Gradient evaluations: 39
7.53668131651e-08
Trained loss value: 0.208443907192 

Формула для регуляризации ниже. Если я прокомментирую регуляризованные входные данные выше scipy.optimize.fmin_bfgs() работает хорошо и возвращает локальный оптимум правильно.

Есть идеи, почему?

enter image description here

ОБНОВЛЕНИЕ:

После дополнительных комментариев я обновил регуляризацию стоимости и градиента (в коде выше). Но это предупреждение все еще появляется (новые выходы выше). scipy check_grad функция возвращает следующее значение: 7.53668131651e-08.

ОБНОВЛЕНИЕ 2:

Я использую набор UCI Machine Learning Iris data. И на основе модели классификации One-vs-All подготовка первых результатов для Iris-setosa.

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Проблема была в моем исчислении, где по какой-то причине я суммирую theta значения в регуляризации: regularization = (lam / len(x)) * np.sum(theta_without_intercept). Нам не нужно np.sum регуляризованное значение на этом этапе. Это произведет регуляризацию avaregae для каждой тэты и следующей потери прогноза. В любом случае, спасибо за помощь.

Градиентный метод:

def gradient(theta, x, y, lam):
    theta_len = len(theta)
    theta = theta.reshape(1, theta_len)

    predictions = sigmoid(np.dot(x, np.transpose(theta))).reshape(len(x), 1)

    theta_wo_bias = theta.copy()
    theta_wo_bias[0, 0] = 0

    assert (theta_wo_bias.shape == theta.shape)
    regularization = np.squeeze(((lam / len(x)) *
                  theta_wo_bias).reshape(theta_len, 1))

    return np.sum(np.multiply((predictions - y), x), 0) / len(x) + regularization

Выход:

Starting loss value: 0.69314718056 
Optimization terminated successfully.
         Current function value: 0.201681
         Iterations: 30
         Function evaluations: 32
         Gradient evaluations: 32
7.53668131651e-08
Trained loss value: 0.201680992316 
0 голосов
/ 07 мая 2018

Поскольку вы пытаетесь выполнить регуляризацию L2, вам следует изменить значение в вашей функции стоимости с

regularization = (lam / len(x) * 2) * np.sum(np.square(np.delete(theta, 0, 1)))

до

regularization = (lam / (len(x) * 2)) * np.sum(np.square(np.delete(theta, 0, 1)))

Также градиентная часть регуляризации должна иметь ту же форму, что и вектор параметров theta. Поэтому я скорее думаю, что правильное значение будет

theta_without_intercept = theta.copy()
theta_without_intercept[0] = 0 #  You are not penalizing the intercept in your cost function, i.e. theta_0
assert(theta_without_intercept.shape == theta.shape)
regularization = (lam / len(x)) * theta_without_intercept

В противном случае градиент не будет правильным. Затем вы можете проверить правильность градиента, используя функцию scipy.optimize.check_grad().

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