I have the following code which attempts to minimize a log likelihood function.
#!/usr/bin/python
import math
import random
import numpy as np
from scipy.optimize import minimize
def loglikelihood(params, data):
(mu, alpha, beta) = params
tlist = np.array(data)
r = np.zeros(len(tlist))
for i in xrange(1,len(tlist)):
r[i] = math.exp(-beta*(tlist[i]-tlist[i-1]))*(1+r[i-1])
loglik = -tlist[-1]*mu
loglik = loglik+alpha/beta*sum(np.exp(-beta*(tlist[-1]-tlist))-1)
loglik = loglik+np.sum(np.log(mu+alpha*r))
return -loglik
atimes = [ 148.98894201, 149.70253172, 151.13717804, 160.35968355,
160.98322609, 161.21331798, 163.60755544, 163.68994973,
164.26131871, 228.79436067]
a= 0.01
alpha = 0.5
beta = 0.6
print loglikelihood((a, alpha, beta), atimes)
res = minimize(loglikelihood, (0.01, 0.1,0.1), method = 'BFGS',args = (atimes,))
print res
It gives me
28.3136498357
./test.py:17: RuntimeWarning: invalid value encountered in log
loglik = loglik+np.sum(np.log(mu+alpha*r))
status: 2
success: False
njev: 14
nfev: 72
hess_inv: array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
fun: 32.131359359964378
x: array([ 0.01, 0.1 , 0.1 ])
message: 'Desired error not necessarily achieved due to precision loss.'
jac: array([ -2.8051672 , 13.06962156, -48.97879982])
Notice that it hasn’t managed to optimize the parameters at all and the minimized value 32 is bigger than 28 which is what you get with a= 0.01, alpha = 0.5, beta = 0.6 . It’s possible this problem could be avoided by choosing better initial guesses but if so, how can I do this automatically?
Nelder-Mead, TNC and SLSQP work as drop-in replacements. None of the other methods do.
$begingroup$
I am getting the warning in the post subject when attempting to optimize a function in Python with the scipy.optimize.fmin_bfgs function.
The complete output:
Warning: Desired error not necessarily achieveddue to precision loss
Current function value: nan
Iterations: 1
Function evaluations: 18
Gradient evaluations: 3
It is not a fatal error, I am getting answers, but they are far from the optimum I search.
Are there any typical «noob» errors that might generate this error? I started working with this package only yesterday; as it is, I’m not even sure where to start looking.
Any help is appreciated!
Aron Ahmadia
6,8914 gold badges33 silver badges54 bronze badges
asked Apr 21, 2012 at 13:47
$endgroup$
$begingroup$
It is helpful in situations like this to take a look at the source code. This is easy because everything in scipy
is open source!
As you can see from reading the source code, the warning message is printed when warnflag==2
. This gets set elsewhere in the code when the linesearch
function returns None (it fails).
So why does linesearch fail? The goal of an optimization algorithm is to find the minima of some objective function through a successive set of iterations. The line search, in this case, is trying to find a step size where the approximations in BFGS are still valid. When the Hessian of your function or its gradient are ill-behaved in some way, the bracketed step size could be computed as zero, even though the gradient is non-zero.
I guess my suggestion is to either go to the literature (Nocedal and Wright has a good discussion of line search and the BFGS method) or to your function and make sure that it is well-behaved in the region you are searching.
answered Apr 21, 2012 at 15:51
Aron AhmadiaAron Ahmadia
6,8914 gold badges33 silver badges54 bronze badges
$endgroup$
5
#python #scipy #scipy-optimize-minimize
#питон #сципи #scipy-оптимизировать-минимизировать
Вопрос:
Я пытаюсь решить набор уравнений с помощью scipy.minimize, однако я не получаю удовлетворительных результатов, так что, возможно, я что-то делаю не так. Я хочу решить следующую систему уравнений.
12.25 * (x y * 2.2 z * 4.84) - 8.17437483750257 = 0 12.25 * (x y * 3.1 z * 9.61) - 21.9317236606432 = 0 12.25 * (x y * 4 z * 16) - 107.574834524443 = 0
Используя Wolfram Alpha, я получаю ответы
x=22.626570068753, y=-17.950683342597, z=3.6223614029055
Которые действительно решают систему уравнений, давая остаточную ошибку
9.407585821463726e-12
Теперь, используя scipy.минимизировать, я делаю:
import numpy as np from scipy.optimize import fsolve from scipy.optimize import minimize def my_func(p): points = [8.17437483750257, 21.9317236606432, 107.574834524443] h1 = abs(12.25 * (p[0] p[1] * 2.2 p[2] * 4.84) - points[0]) h2 = abs(12.25 * (p[0] p[1] * 3.1 p[2] * 9.61) - points[1]) h3 = abs(12.25 * (p[0] p[1] * 4 p[2] * 16) - points[2]) return h1 h2 h3 ini = np.array([22, -15, 5]) # Initial points close to solution res = minimize(my_func, ini) print(res) fun: 1.4196640741924451 hess_inv: array([[ 20.79329103, -14.63447889, 2.36145776], [-14.63447889, 10.30037625, -1.66214485], [ 2.36145776, -1.66214485, 0.26822135]]) jac: array([ 12.25 , 60.02499545, 254.43249989]) message: 'Desired error not necessarily achieved due to precision loss.' nfev: 261 nit: 8 njev: 64 status: 2 success: False x: array([ 21.39197235, -17.08623345, 3.48344393])
Во-первых, он говорит, что успех=Ложь, а во-вторых, он находит решения, которые не являются оптимальными.
Почему, имея начальные значения, близкие к оптимальному решению, он не может найти эти решения.
Что-то не так с определением оптимизатора?
Попробовал запустить его, дав начальные значения [0,0,0], и это просто дает ужасные результаты
ini = np.array([0, 0, 0]) # Initial points close to solution res = minimize(my_func, ini) print(res) fun: 73.66496363902732 hess_inv: array([[ 0.98461683, -0.04223651, -0.1207056 ], [-0.04223651, 0.88596592, -0.31885642], [-0.1207056 , -0.31885642, 0.13448927]]) jac: array([ 12.25 , 15.92499924, -18.98750019]) message: 'Desired error not necessarily achieved due to precision loss.' nfev: 164 nit: 1 njev: 40 status: 2 success: False x: array([0.02901304, 0.08994042, 0.29448233])
Примечание: Я не хочу использовать fsolve
для поиска решений, но minimize
. Причина в том, что моя реальная проблема заключается в том, что у меня больше уравнений, чем неизвестных, поэтому в конце я хочу найти решение, которое минимизирует ошибки всех этих уравнений. Однако, поскольку это не давало хороших результатов, я хотел сначала протестировать простую проблему, для которой существует точное решение. Но даже в этом случае это не работает. Как только я решу эту задачу, я расширю ее, добавив дополнительные уравнения.
Комментарии:
1. Ваша система линейна, почему вы хотите использовать подход нелинейной оптимизации, а не просто решать ее с помощью линейной алгебры???
2. Я отредактировал вопрос. В конце концов, мне нужен оптимизатор для системы с большим количеством уравнений, чем неизвестных. Система по-прежнему будет линейной, но решение не будет точным, это будет просто минимальная ошибка. Как я могу получить линейный минимизатор для решения этой проблемы?
3. Это звучит как обобщенный метод моментов. Помогает ли возведение в квадрат различий вместо использования абсолютных значений? Например.
h1 =(12.25 * (p[0] p[1] * 2.2 p[2] * 4.84) - points[0])**2
4. @ForceBru. Да! Я изменил сумму для квадрата, и это дает точный результат. Спасибо. Если вы сформулируете это как ответ, я приму его
5. @SembeiNorimaki Если у вас больше уравнений, чем неизвестных, но система все еще линейна, то ее все еще можно решить с помощью линейной алгебры, решение состоит в использовании линейных наименьших квадратов, как в f.ex. numpy.linalg.lstsq
Ответ №1:
…моя реальная проблема заключается в том, что у меня больше уравнений, чем неизвестных, поэтому в конце я хочу найти решение, которое минимизирует ошибки всех этих уравнений
Это очень похоже на проблему, решаемую в обобщенном методе моментов (GMM), где у вас также больше уравнений, чем неизвестных.
Проблемы такого рода обычно решаются с использованием метода наименьших квадратов. Предположим, вся ваша система выглядит так:
h1(x, y, z) = 0 h2(x, y, z) = 0 h3(x, y, z) = 0 h4(x, y, z) = 0
Он имеет 3 неизвестных и 4 уравнения. Тогда ваша целевая функция будет:
F(x, y, z) = H(x, y, z)' * W * H(x, y, z)
H(x, y, z)
является вектором всегоhj(x, y, z)
вышеперечисленногоH(x, y, z)'
является ли его транспонированиеW
является весовой матрицей
Если W
это матрица идентичности, вы получаете целевую функцию наименьших квадратов. Затем, F(x, y, z)
это квадратичная форма (в основном парабола в нескольких измерениях), которую должно быть просто оптимизировать, потому что она выпуклая и гладкая.
В вашем коде используются абсолютные значения , такие как h1 = abs(12.25 * (p[0] p[1] * 2.2 p[2] * 4.84) - points[0])
, но abs
может быть трудно различить вблизи источника, но именно там находится ваш оптимум, поскольку вы, по сути, хотите h1
равняться нулю.
Вы можете приблизить функцию абсолютного значения, возведя ошибку в квадрат:
h1 =(12.25 * (p[0] p[1] * 2.2 p[2] * 4.84) - points[0])**2
Это приводит в основном к тому же подходу, что и GMM (или наименьшие квадраты), и дает вам функцию, которую легко оптимизировать, так как квадрат гладкий вблизи начала координат.
Комментарии:
1. Да, в конце концов я закончил использовать метод наименьших квадратов, и я получаю лучшие результаты, чем при использовании нелинейного оптимизатора scipy.
Ответ №2:
Проблемы оптимизации (и решатели) обычно выигрывают от хорошей (гладкой) «поверхности оптимизации». Когда вы используете abs
функцию, она создает «прерывистую» поверхность с точками, производные которых не являются непрерывными.
Если вместо использования abs
вы используете квадратичную функцию (которая имеет тот же эффект), вы получите решение, близкое к тому, что вы ожидаете. Просто измените my_func
на:
def my_func(p): points = [8.17437483750257, 21.9317236606432, 107.574834524443] h1 = (12.25 * (p[0] p[1] * 2.2 p[2] * 4.84) - points[0])**2 h2 = (12.25 * (p[0] p[1] * 3.1 p[2] * 9.61) - points[1])**2 h3 = (12.25 * (p[0] p[1] * 4 p[2] * 16) - points[2])**2 return h1 h2 h3
Что у меня есть, так это:
fun: 8.437863292878727e-10 hess_inv: array([[ 0.64753863, -0.43474506, 0.06909179], [-0.43474506, 0.29487798, -0.04722923], [ 0.06909179, -0.04722923, 0.00761762]]) jac: array([-6.26698693e-12, 6.22490927e-10, -5.11716516e-10]) message: 'Optimization terminated successfully.' nfev: 55 nit: 7 njev: 11 status: 0 success: True x: array([ 22.62653789, -17.95066124, 3.62235782])
Я получаю следующее предупреждение об использовании оптимизации SciPy fmin_bfgs()
в NeuralNetwork
. Все должно быть понятно и просто, по алгоритму Backpropagation
.
1 Примеры обучения Feed Forward.
2 Рассчитайте срок погрешности для каждого блока.
3 Накопительный градиент (в первом примере я пропускаю термин регуляризации).
Starting Loss: 7.26524579601
Check gradient: 2.02493576268
Warning: Desired error not necessarily achieved due to precision loss.
Current function value: 5.741300
Iterations: 3
Function evaluations: 104
Gradient evaluations: 92
Trained Loss: 5.74130012926
Я только что выполнил ту же задачу с MATLAB, которая успешно выполнилась с функциями fmin
для оптимизации, но не могу понять, что я упустил в реализации Python. Как видите, даже scipy.optimize.check_grad
возвращает слишком большое значение.
def feed_forward(x, theta1, theta2):
hidden_dot = np.dot(add_bias(x), np.transpose(theta1))
hidden_p = sigmoid(hidden_dot)
p = sigmoid(np.dot(add_bias(hidden_p), np.transpose(theta2)))
return hidden_dot, hidden_p, p
def cost(thetas, x, y, hidden, lam):
theta1, theta2 = get_theta_from(thetas, x, y, hidden)
_, _, p = feed_forward(x, theta1, theta2)
# regularization = (lam / (len(x) * 2)) * (
# np.sum(np.square(np.delete(theta1, 0, 1)))
# + np.sum(np.square(np.delete(theta2, 0, 1))))
complete = -1 * np.dot(np.transpose(y), np.log(p))
- np.dot(np.transpose(1 - y), np.log(1 - p))
return np.sum(complete) / len(x) # + regularization
def vector(z):
# noinspection PyUnresolvedReferences
return np.reshape(z, (np.shape(z)[0], 1))
def gradient(thetas, x, y, hidden, lam):
theta1, theta2 = get_theta_from(thetas, x, y, hidden)
hidden_dot, hidden_p, p = feed_forward(x, theta1, theta2)
error_o = p - y
error_h = np.multiply(np.dot(
error_o, np.delete(theta2, 0, 1)), sigmoid_gradient(hidden_dot))
x = add_bias(x)
hidden_p = add_bias(hidden_p)
theta1_grad, theta2_grad =
np.zeros(theta1.shape[::-1]), np.zeros(theta2.shape[::-1])
records = y.shape[0]
for i in range(records):
theta1_grad = theta1_grad + np.dot(
vector(x[i]), np.transpose(vector(error_h[i])))
theta2_grad = theta2_grad + np.dot(
vector(hidden_p[i]), np.transpose(vector(error_o[i])))
theta1_grad = np.transpose(
theta1_grad / records) # + (lam / records * theta1)
theta2_grad = np.transpose(
theta2_grad / records) # + (lam / records * theta2)
return np.append(theta1_grad, theta2_grad)
def get_theta_shapes(x, y, hidden):
return (hidden, x.shape[1] + 1),
(y.shape[1], hidden + 1)
def get_theta_from(thetas, x, y, hidden):
t1_s, t2_s = get_theta_shapes(x, y, hidden)
split = t1_s[0] * t1_s[1]
theta1 = np.reshape(thetas[:split], t1_s)
theta2 = np.reshape(thetas[split:], t2_s)
return theta1, theta2
def train(x, y, hidden_size, lam):
y = get_binary_y(y)
t1_s, t2_s = get_theta_shapes(x, y, hidden_size)
thetas = np.append(
rand_init(t1_s[0], t1_s[1]),
rand_init(t2_s[0], t2_s[1]))
initial_cost = cost(thetas, x, y, hidden_size, lam)
print("Starting Loss: " + str(initial_cost))
check_grad1 = scipy.optimize.check_grad(
cost, gradient, thetas, x, y, hidden_size, lam)
print("Check gradient: " + str(check_grad1))
trained_theta = scipy.optimize.fmin_bfgs(
cost, thetas, fprime=gradient, args=(x, y, hidden_size, lam))
print("Trained Loss: " +
str(cost(trained_theta, x, y, hidden_size, lam)))
2 ответа
Опять же, было несколько проблем с расчетом, чтобы устранить все предупреждения и сделать успешный запуск оптимизации Scipy
, то же самое с функциями оптимизации Matlab
fminc
. (Рабочие примеры Python
можно найти в Github)
1. Обновите расчетную стоимость до правильной. Умножьте поэлементно на функцию затрат. Правильным решением по стоимости будет (со сроком регуляризации):
def cost(thetas, x, y, hidden, lam):
theta1, theta2 = get_theta_from(thetas, x, y, hidden)
_, _, p = feed_forward(x, theta1, theta2)
regularization = (lam / (len(x) * 2)) * (
np.sum(np.square(np.delete(theta1, 0, 1)))
+ np.sum(np.square(np.delete(theta2, 0, 1))))
complete = np.nan_to_num(np.multiply((-y), np.log(
p)) - np.multiply((1 - y), np.log(1 - p)))
avg = np.sum(complete) / len(x)
return avg + regularization
2. После выполнения этой операции мы получим значения nan
в термине Оптимизированный Theta
от Scipy
. В этом случае мы выполняем np.nan_to_num
выше. Примечание! Это Matlab
fminc
правильно работает с неожиданными числами.
3. Примените правильную регуляризацию и не забудьте удалить регуляризацию для значений смещения. Правильная функция градиента должна выглядеть так:
def gradient(thetas, x, y, hidden, lam):
theta1, theta2 = get_theta_from(thetas, x, y, hidden)
hidden_dot, hidden_p, p = feed_forward(x, theta1, theta2)
error_o = p - y
error_h = np.multiply(np.dot(
error_o, theta2),
sigmoid_gradient(add_bias(hidden_dot)))
x = add_bias(x)
error_h = np.delete(error_h, 0, 1)
theta1_grad, theta2_grad =
np.zeros(theta1.shape[::-1]), np.zeros(theta2.shape[::-1])
records = y.shape[0]
for i in range(records):
theta1_grad = theta1_grad + np.dot(
vector(x[i]), np.transpose(vector(error_h[i])))
theta2_grad = theta2_grad + np.dot(
vector(hidden_p[i]), np.transpose(vector(error_o[i])))
reg_theta1 = theta1.copy()
reg_theta1[:, 0] = 0
theta1_grad = np.transpose(
theta1_grad / records) + ((lam / records) * reg_theta1)
reg_theta2 = theta2.copy()
reg_theta2[:, 0] = 0
theta2_grad = np.transpose(
theta2_grad / records) + ((lam / records) * reg_theta2)
return np.append(
theta1_grad, theta2_grad)
0
GensaGames
26 Июн 2018 в 18:54
Просто интересно, почему вы пропустили этап регуляризации? Вы пробовали запускать программу с регуляризацией?
0
kamykam
15 Июн 2018 в 15:08
3 / 3 / 0 Регистрация: 02.04.2017 Сообщений: 273 |
|
1 |
|
Как минимизировать такую функцию?28.09.2019, 12:43. Показов 916. Ответов 7
Есть список значений Y и список X и я хочу минимизировать функцию такого вида(прикрепил картинку). Также есть начальные значения Theta0 = 1.537, Theta1 = 1.143, Theta2 = 0.01604. Как минимизировать такую функцию? Миниатюры
__________________
0 |
1315 / 1240 / 213 Регистрация: 19.02.2010 Сообщений: 3,569 |
|
28.09.2019, 13:00 |
2 |
Превращайте эту полиномиальную регрессию в линейную путём ввода новой независимой переменной Z=X^2, далее любыми способами решения задачи линейной множественной регрессии. Например, через решение СЛАУ методом Гаусса.
0 |
Key27 3 / 3 / 0 Регистрация: 02.04.2017 Сообщений: 273 |
||||||||||||
28.09.2019, 17:43 [ТС] |
3 |
|||||||||||
VTsaregorodtsev, Немного не правильно выразился. Попробую на конкретном примере Добавлено через 39 минут
А что делать, когда нужно найти минимум суммы Добавлено через 11 минут
Но получаю ошибку
0 |
4606 / 2027 / 359 Регистрация: 17.03.2012 Сообщений: 10,081 Записей в блоге: 6 |
|
30.09.2019, 11:49 |
4 |
0 |
woldemas 653 / 457 / 212 Регистрация: 06.09.2013 Сообщений: 1,265 |
||||
30.09.2019, 15:18 |
5 |
|||
А что делать, когда нужно найти минимум суммы Надо просто продифференцировать и приравнять производные к нулю. Если лень это делать, то можно найти формулу для коэффициентов множественной регрессии:
0 |
4606 / 2027 / 359 Регистрация: 17.03.2012 Сообщений: 10,081 Записей в блоге: 6 |
|
30.09.2019, 15:44 |
6 |
woldemas, не надо диференцировать.
0 |
653 / 457 / 212 Регистрация: 06.09.2013 Сообщений: 1,265 |
|
30.09.2019, 16:43 |
7 |
задача именно на минимизацию путём градиентного спуска Это в чистом виде полиномиальная регрессия (если я правильно понял обозначения — ТС там в скобках путается). Градиентный спуск даст тот же результат — там же целевая функция квадратичная.
0 |
4606 / 2027 / 359 Регистрация: 17.03.2012 Сообщений: 10,081 Записей в блоге: 6 |
|
30.09.2019, 16:52 |
8 |
woldemas, да я вижу, что регрессия.
0 |