Skip to content

Commit

Permalink
optimize bfgs/lbfgs chinese documents (PaddlePaddle#5294)
Browse files Browse the repository at this point in the history
  • Loading branch information
cxxly authored Sep 22, 2022
1 parent b6e5256 commit 4dca011
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 15 deletions.
91 changes: 84 additions & 7 deletions docs/api/paddle/incubate/optimizer/functional/minimize_bfgs_cn.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,36 @@ minimize_bfgs
.. py:function:: paddle.incubate.optimizer.functional.minimize_bfgs(objective_func, initial_position, max_iters=50, tolerance_grad=1e-07, tolerance_change=1e-09, initial_inverse_hessian_estimate=None, line_search_fn='strong_wolfe', max_line_search_iters=50, initial_step_length=1.0, dtype='float32', name=None)
使用 BFGS 方法求解可微函数 ``objective_func`` 的最小值。BFGS 是一种拟牛顿方法,用于解决可微函数上的无约束最优化问题。与之密切相关的是用于最优化的牛顿法,考虑迭代更新公式:
``minimize_bfgs`` 使用 BFGS 方法求解可微函数 ``objective_func`` 的最小值。

BFGS 是一种拟牛顿方法,用于解决可微函数上的无约束优化问题,通过如下迭代公式更新参数:

.. math::
x_{k+1} = x_{k} + H_k \nabla{f_k}
如果 :math:`H_k` 是函数 :math:`f` 在 :math:`x_k`的逆海森矩阵,此时就是牛顿法。如果 :math:`H_k` 满足对称性和正定性,用来作为逆海森矩阵的近似,则为高斯-牛顿法。在实际算法中,近似逆海森矩阵是通过整个或部分搜索历史的梯度计算得到,前者对应 BFGS,后者对应于 L-BFGS。
其中 :math:`H_k` 为通过 BFGS 方法得到的海森矩阵的近似逆矩阵。

BFGS 具体原理参考书籍 Jorge Nocedal, Stephen J. Wright, Numerical Optimization, Second Edition, 2006. pp179: Algorithm 7.5 (L-BFGS).


参考
使用方法
:::::::::
Jorge Nocedal, Stephen J. Wright, Numerical Optimization, Second Edition, 2006. pp140: Algorithm 6.1 (BFGS Method).
- minimize_bfgs 优化器当前实现为函数形式,与 Paddle 现有 SGD、Adam 优化器等使用略微有些区别。
SGD/Adam 等通过调用 backward()计算梯度,并使用 step()更新网络参数。 而 minimize_bfgs 传入
loss 函数,并返回优化后参数,返回参数需要通过 `paddle.assign <https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/assign_cn.html>`_ 以 inpalce 方式进行更新。具体参考代码示例 1.
- 由于当前实现上一些限制,当前 minimize_bfgs 要求函数输入为一维 Tensor。当输入参数维度超过一维,
可以先将参数展平,使用 minimize_bfgs 计算后,再 reshape 到原有形状,更新参数。具体参考代码示例 2.


.. warning::
该 API 目前为 Beta 版本,函数签名在未来版本可能发生变化。

.. note::
当前仅支持动态图模式使用。

.. note::
当前仅支持 Vector-scalar 形式函数,即目标函数输入为一维 Tensor,输出为只包含一个元素 Tensor。

参数
:::::::::
Expand All @@ -40,8 +58,67 @@ minimize_bfgs
- position (Tensor) - 最后一次迭代之后的位置,如果算法收敛,那么就是目标函数以初始位置开始迭代得到的最小值点。
- objective_value (Tensor) - 迭代终止位置的函数值。
- objective_gradient (Tensor) - 迭代终止位置的梯度。
- inverse_hessian_estimate (Tensor) - 迭代终止位置的近似逆海森矩阵
- inverse_hessian_estimate (Tensor) - 迭代终止位置的近似海森矩阵的逆

代码示例

代码示例 1
::::::::::
COPY-FROM: paddle.incubate.optimizer.functional.minimize_bfgs

.. code-block:: python
import paddle
# 随机模拟一批输入数据
inputs = paddle.normal(shape=(100, 1))
labels = inputs * 2.0
# 定义 loss 函数
def loss(w):
y = w * inputs
return paddle.nn.functional.square_error_cost(y, labels).mean()
# 初始化权重参数
w = paddle.normal(shape=(1,))
# 调用 bfgs 方法求解使得 loss 最小的权重,并更新参数
for epoch in range(0, 10):
# 调用 bfgs 方法优化 loss,注意返回的第三个参数表示权重
w_update= paddle.incubate.optimizer.functional.minimize_bfgs(loss, w)[2]
# 使用 paddle.assign,以 inplace 方式更新参数
paddle.assign(w_update, w)
代码示例 2
::::::::::

.. code-block:: python
import paddle
def flatten(x):
return x.flatten()
def unflatten(x):
return x.reshape((2,2))
# 假设网络参数超过一维
def net(x):
assert len(x.shape) > 1
return x.square().mean()
# 待优化函数
def bfgs_f(flatten_x):
return net(unflatten(flatten_x))
x = paddle.rand([2,2])
for i in range(0, 10):
# 使用 minimize_bfgs 前,先将 x 展平
x_update = paddle.incubate.optimizer.functional.minimize_bfgs(bfgs_f, flatten(x))[2]
# 将 x_update unflatten,然后更新参数
paddle.assign(unflatten(x_update), x)
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,30 @@ minimize_lbfgs

.. py:function:: paddle.incubate.optimizer.functional.minimize_lbfgs(objective_func, initial_position, history_size=100, max_iters=50, tolerance_grad=1e-08, tolerance_change=1e-08, initial_inverse_hessian_estimate=None, line_search_fn='strong_wolfe', max_line_search_iters=50, initial_step_length=1.0, dtype='float32', name=None)
使用 L-BFGS 方法求解可微函数 ``objective_func`` 的最小值。L-BFGS 是一种拟牛顿方法,用于解决可微函数上的无约束最优化问题。与之密切相关的是用于最优化的牛顿法,考虑迭代更新公式:
``minimize_lbfgs`` 使用 L-BFGS 方法求解可微函数 ``objective_func`` 的最小值。

.. math::
x_{k+1} = x_{k} + H_k \nabla{f_k}
L-BFGS 是限制内存的 BFGS 方法,适用于海森矩阵为稠密矩阵、内存开销较大场景。BFGS 参考 :ref:`cn_api_incubate_optimizer_functional_minimize_bfgs` .

如果 :math:`H_k` 是函数 :math:`f` 在 :math:`x_k`的逆海森矩阵,此时就是牛顿法。如果 :math:`H_k` 满足对称性和正定性,用来作为逆海森矩阵的近似,则为高斯-牛顿法。在实际算法中,近似逆海森矩阵是通过整个或部分搜索历史的梯度计算得到,前者对应 BFGS,后者对应于 L-BFGS
LBFGS 具体原理参考书籍 Jorge Nocedal, Stephen J. Wright, Numerical Optimization, Second Edition, 2006. pp179: Algorithm 7.5 (L-BFGS).


参考
使用方法
:::::::::
Jorge Nocedal, Stephen J. Wright, Numerical Optimization, Second Edition, 2006. pp179: Algorithm 7.5 (L-BFGS).
- minimize_bfgs 优化器当前实现为函数形式,与 Paddle 现有 SGD、Adam 优化器等使用略微有些区别。
SGD/Adam 等通过调用 backward()计算梯度,并使用 step()更新网络参数,而 minimize_lbfgs 传入
loss 函数,并返回优化后参数,返回参数需要通过 `paddle.assign <https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/assign_cn.html>`_ 以 inpalce 方式进行更新。具体参考代码示例 1.
- 由于当前实现上一些限制,当前 minimize_bfgs 要求函数输入为一维 Tensor。当输入参数维度超过一维,
可以先将参数展平,使用 minimize_bfgs 计算后,再 reshape 到原有形状,更新参数。具体参考代码示例 2.


.. warning::
该 API 目前为 Beta 版本,函数签名在未来版本可能发生变化。

.. note::
当前仅支持动态图模式下使用。

.. note::
当前仅支持 Vector-scalar 形式函数,即目标函数输入为一维 Tensor,输出为只包含一个元素 Tensor。

参数
:::::::::
Expand All @@ -40,6 +53,66 @@ minimize_lbfgs
- objective_value (Tensor):迭代终止位置的函数值。
- objective_gradient (Tensor):迭代终止位置的梯度。

代码示例


代码示例 1:
::::::::::

.. code-block:: python
import paddle
# 随机模拟一批输入数据
inputs = paddle.normal(shape=(100, 1))
labels = inputs * 2.0
# 定义 loss 函数
def loss(w):
y = w * inputs
return paddle.nn.functional.square_error_cost(y, labels).mean()
# 初始化权重参数
w = paddle.normal(shape=(1,))
# 调用 bfgs 方法求解使得 loss 最小的权重,并更新参数
for epoch in range(0, 10):
# 调用 bfgs 方法优化 loss,注意返回的第三个参数表示权重
w_update= paddle.incubate.optimizer.functional.minimize_lbfgs(loss, w)[2]
# 使用 paddle.assign,以 inplace 方式更新参数
paddle.assign(w_update, w)
代码示例 2:输入参数维度超过一维
::::::::::
COPY-FROM: paddle.incubate.optimizer.functional.minimize_lbfgs

.. code-block:: python
import paddle
def flatten(x):
return x.flatten()
def unflatten(x):
return x.reshape((2,2))
# 假设网络参数超过一维
def net(x):
assert len(x.shape) > 1
return x.square().mean()
# 待优化函数
def bfgs_f(flatten_x):
return net(unflatten(flatten_x))
x = paddle.rand([2,2])
for i in range(0, 10):
# 使用 minimize_lbfgs 前,先将 x 展平
x_update = paddle.incubate.optimizer.functional.minimize_lbfgs(bfgs_f, flatten(x))[2]
# 将 x_update unflatten,然后更新参数
paddle.assign(unflatten(x_update), x)

0 comments on commit 4dca011

Please sign in to comment.