tmp update

This commit is contained in:
张壹 2022-02-15 15:27:22 +08:00
parent aafcfc4279
commit 47b3e01cfb
5 changed files with 35 additions and 9 deletions

View File

@ -99,6 +99,7 @@ struct tag_callback_data {
void *instance; // 用户给出的运行实例
lbfgs_evaluate_t proc_evaluate; // 目标函数与模型梯度计算函数指针
lbfgs_progress_t proc_progress; // 迭代过程监控函数指针
lbfgs_precondition_t proc_precondition; // 预优函数指针
};
typedef struct tag_callback_data callback_data_t;
@ -250,7 +251,8 @@ int lbfgs(
lbfgs_evaluate_t proc_evaluate,
lbfgs_progress_t proc_progress,
void *instance,
lbfgs_parameter_t *_param
lbfgs_parameter_t *_param,
lbfgs_precondition_t proc_precondition
)
{
int ret;
@ -264,7 +266,7 @@ int lbfgs(
const int m = param.m;
lbfgsfloatval_t *xp = NULL;
lbfgsfloatval_t *g = NULL, *gp = NULL, *pg = NULL;
lbfgsfloatval_t *g = NULL, *gp = NULL, *pg = NULL; // gp (p for previous) pg (p for pesudo)
lbfgsfloatval_t *d = NULL, *w = NULL, *pf = NULL;
iteration_data_t *lm = NULL, *it = NULL;
lbfgsfloatval_t ys, yy;
@ -280,6 +282,7 @@ int lbfgs(
cd.instance = instance;
cd.proc_evaluate = proc_evaluate;
cd.proc_progress = proc_progress;
cd.proc_precondition = proc_precondition;
#if defined(USE_SSE) && (defined(__SSE__) || defined(__SSE2__))
/* Round out the number of variables. */
@ -379,6 +382,7 @@ int lbfgs(
ret = LBFGSERR_OUTOFMEMORY;
goto lbfgs_exit;
}
// 初始化计算L1模的数组
if (param.orthantwise_c != 0.) {
/* Allocate working space for OW-LQN. */
@ -455,6 +459,7 @@ int lbfgs(
vec2norm(&gnorm, pg, n);
}
// 为啥要保证xnorm大于等于1不明白
// 答 参考头文件中的注释 如果模型参数的模长小于1则使用梯度的模长作为收敛性的测试指标
if (xnorm < 1.0) xnorm = 1.0;
// 如果输入x即为最优化的解 则退出
if (gnorm / xnorm <= param.epsilon) {
@ -465,14 +470,14 @@ int lbfgs(
/* Compute the initial step:
step = 1.0 / sqrt(vecdot(d, d, n))
*/
// 计算估算的初始步长
// 计算估算的初始步长 这一步在实际应用中重要 在相似代码编写中需参考
vec2norminv(&step, d, n); // 计算数组L2模的倒数与注释的内容等效
k = 1;
end = 0;
for (;;) {
/* Store the current position and gradient vectors. */
veccpy(xp, x, n);
veccpy(xp, x, n); // p for previous
veccpy(gp, g, n);
/* Search for an optimal step. */
@ -485,7 +490,8 @@ int lbfgs(
param.orthantwise_c, param.orthantwise_start, param.orthantwise_end
);
}
// 线性搜索错误 此时则退回到上一次迭代的位置并退出
// 返回值小于0则表示线性搜索错误 此时则退回到上一次迭代的位置并退出
if (ls < 0) {
/* Revert to the previous point. */
veccpy(x, xp, n);
@ -560,6 +566,7 @@ int lbfgs(
s_{k+1} = x_{k+1} - x_{k} = \step * d_{k}.
y_{k+1} = g_{k+1} - g_{k}.
*/
// 计算最新保存的s和y
it = &lm[end];
vecdiff(it->s, x, xp, n); // 计算两个数组的差 it->s = x - xp
vecdiff(it->y, g, gp, n);
@ -582,8 +589,12 @@ int lbfgs(
Mathematics of Computation, Vol. 35, No. 151,
pp. 773--782, 1980.
*/
// m小于迭代次数
bound = (m <= k) ? m : k;
++k;
// end+1等于m则将其重置为0 循环保存
end = (end + 1) % m;
/* Compute the steepest direction. */
@ -607,6 +618,11 @@ int lbfgs(
vecscale(d, ys / yy, n); // 适当缩放d的大小
// 我们在这里提供一个预优函数的接口 返回 d = H0^-1 * d
if (cd.proc_precondition) {
cd.proc_precondition(cd.instance, x, d, n);
}
for (i = 0;i < bound;++i) {
it = &lm[j];
/* \beta_{j} = \rho_{j} y^t_{j} \cdot \gamma_{i}. */

View File

@ -463,6 +463,15 @@ typedef int (*lbfgs_progress_t)(
int ls
);
typedef void (*lbfgs_precondition_t)(
void *instance,
const lbfgsfloatval_t *x,
lbfgsfloatval_t *d,
const int n
);
/*
A user must implement a function compatible with ::lbfgs_evaluate_t (evaluation
callback) and pass the pointer to the callback function to lbfgs() arguments.
@ -550,7 +559,8 @@ int lbfgs(
lbfgs_evaluate_t proc_evaluate,
lbfgs_progress_t proc_progress,
void *instance,
lbfgs_parameter_t *param
lbfgs_parameter_t *param,
lbfgs_precondition_t proc_precondition
);
// 将一个参数类型内的全部变量值重置为默认值

View File

@ -71,7 +71,7 @@ int main(int argc, char *argv[])
Start the L-BFGS optimization; this will invoke the callback functions
evaluate() and progress() when necessary.
*/
ret = lbfgs(N, x, &fx, evaluate, progress, NULL, &param);
ret = lbfgs(N, x, &fx, evaluate, progress, NULL, &param, NULL);
/* Report the result. */
printf("L-BFGS optimization terminated with status code = %d\n", ret);

View File

@ -39,7 +39,7 @@ public:
Start the L-BFGS optimization; this will invoke the callback functions
evaluate() and progress() when necessary.
*/
int ret = lbfgs(N, m_x, &fx, _evaluate, _progress, this, NULL);
int ret = lbfgs(N, m_x, &fx, _evaluate, _progress, this, NULL, NULL);
/* Report the result. */
printf("L-BFGS optimization terminated with status code = %d\n", ret);

View File

@ -88,7 +88,7 @@ int TEST_FUNC::Routine()
//self_para.max_linesearch = 40;
//self_para.linesearch = LBFGS_LINESEARCH_BACKTRACKING_WOLFE;
int ret = lbfgs(3, m_x, &fx, _Func, _Progress, this, &self_para);
int ret = lbfgs(3, m_x, &fx, _Func, _Progress, this, &self_para, NULL);
clog << "L-BFGS optimization terminated with status: " << endl << lbfgs_strerror(ret) << endl;
clog << m_x[0] << " " << m_x[1] << " " << m_x[2] << endl;