如何强制 L-BFGS-B 不提前停止?投影梯度为零

机器算法验证 优化 Python 深度学习 scipy
2022-03-23 13:31:32

我正在尝试使用以下代码使用 fmin_l_bfgs_b 算法的 SciPy 实现:

imgOpt, cost, info = fmin_l_bfgs_b(func, x0=img, args=(spec_layer, spec_weight, regularization), approx_grad=1,bounds=constraintPairs, iprint=2)

变量 img 只是一个包含 784 个像素的向量,其中所有角都设置为 0,中间部分在 0 到 255 之间随机初始化。角的边界是 (0,0),中间部分的边界是 (0, 255 )。该函数是我的神经网络中隐藏神经元的加权输入。这一切都不应该是特别的。但是,当我运行算法时,它会立即停止,因为投影梯度为零。如何帮助算法找到合适的梯度估计,使其不会立即停止?

输出:

RUNNING THE L-BFGS-B CODE

it    = iteration number
nf    = number of function evaluations
nseg  = number of segments explored during the Cauchy search
nact  = number of active bounds at the generalized Cauchy point
sub   = manner in which the subspace minimization terminated:
        con = converged, bnd = a bound was reached
itls  = number of iterations performed in the line search
stepl = step length used
tstep = norm of the displacement (total step)
projg = norm of the projected gradient
f     = function value

           * * *

Machine precision = 2.220D-16
 N =          784     M =           10

   it   nf  nseg  nact  sub  itls  stepl    tstep     projg        f
    0    1     -     -   -     -     -        -     0.000D+00  1.694D+00

CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL            

 Total User time 0.000E+00 seconds.
2个回答

我对 SciPy 包装器了解不多,但底层 L-BFGS-B 代码提供了几个选项。R 接口的帮助文件列出了其中的几个。

假设您的渐变很小但实际上不是零,您有几个选项可以增加渐变的大小或减小软件可以容忍的大小。

  • 您可以重新调整参数,以便参数的微小差异会在目标函数中产生更大的变化。R 包装器有一种自动执行此操作的方法,但我在 SciPy 中没有看到。您也可以手动进行。
  • 您可以重新调整您的目标函数(例如通过将其乘以某个常数),以便差异和导数更大(例如大于105)。
  • 您可以调整方法的容差。您遇到的公差限制是 for pgtol,即105, 默认。L-BFGS-B 的文档似乎建议(在第 3 节末尾)您可以安全地将这个值降低到“机器精度的平方根”,大约是108在大多数机器上。pgtol如果您的梯度非常小,那么一旦您放松,其他公差限制(绝对和相对)也可能变得重要。

链接到 L-BFGS-B 文档(后记格式)

链接到 L-BFGS-B 的 R 文档

Scipy的BFGS求解器使用epsilon = 1e-8的步长来计算梯度(意思是对每个参数依次加1e-8,看看目标函数变化多少),对于某些应用来说是相当小的. 您可以根据问题的规模将其放大至任意数量 - 对于我的问题,我什至使用了 epsilon = 1。