是否可以将 Tensorflow Graphics 的 Levenberg-Marquardt 优化器与 Tensorflow 2.0 模型集成?

Posted

技术标签:

【中文标题】是否可以将 Tensorflow Graphics 的 Levenberg-Marquardt 优化器与 Tensorflow 2.0 模型集成?【英文标题】:Is it possible to integrate Levenberg-Marquardt optimizer from Tensorflow Graphics with a Tensorflow 2.0 model? 【发布时间】:2020-02-22 04:16:35 【问题描述】:

我有一个 Tensorflow 2.0 tf.keras.Sequential 模型。现在,我的技术规范规定使用 Levenberg-Marquardt 优化器来拟合模型。 Tensorflow 2.0 并未将其作为开箱即用的优化器提供,但可在 Tensorflow Graphics 模块中使用。

tfg.math.optimizer.levenberg_marquardt.minimize 函数接受 residuals(残差是 Python callable 返回张量)和 variables(与我的模型权重对应的张量列表)作为参数。

将我的模型转换为残差和变量的最佳方法是什么?

如果我正确理解 minimize 函数的工作原理,我必须提供两个残差。第一个残差必须为每个学习案例调用我的模型,并将所有结果聚合到一个张量中。第二个残差必须将所有标签作为单个常量张量返回。问题是 tf.keras.Sequential.predict 函数返回一个 numpy 数组而不是张量。我相信如果我将它转换为张量,最小化器将无法计算关于变量的雅可比。

变量也有同样的问题。似乎没有办法将模型中的所有权重提取到张量列表中。

【问题讨论】:

你知道怎么做吗?我正在努力实现类似的目标。我正在尝试训练一个浅层神经网络(在 matlab 上使用 Levenberg-Marquardt 并且做得非常好)。然而,在 Keras 上使用 ADAM 训练的同一个系统确实很糟糕。 @psimeson,不是真的。我最终对公式进行了硬编码。现在,每当模型发生变化时,我都必须相应地更改公式。 嘿@psimeson 你有这方面的消息吗?我被困在同一个问题上:将旧的 matlab 脚本转换为 keras 【参考方案1】:

从实现/API 的角度来看,tfg.math.optimizer.levenberg_marquardt.minimize 和 Keras 优化器之间存在重大差异。

Keras 优化器,例如 tf.keras.optimizers.Adam 使用梯度作为输入并更新 tf.Variables。

相比之下,tfg.math.optimizer.levenberg_marquardt.minimize 本质上是在图形模式下展开优化循环(使用tf.while_loop 构造)。它采用初始参数值并生成更新的参数值,这与 Adam & co 不同,后者仅应用一次迭代并通过 assign_add 实际更改 tf.Variables 的值。

回到理论上的大图,Levenberg-Marquardt 不是任何非线性优化问题(例如 Adam)的通用梯度下降式求解器。它专门解决非线性最小二乘优化,因此它不是像 Adam 这样的优化器的直接替代品。在梯度下降中,我们计算损失相对于参数的梯度。在 Levenberg-Marquardt 中,我们计算残差关于参数的雅可比行列式。具体来说,它使用tf.linalg.lstsq(在内部使用雅可比矩阵计算的Gram矩阵上的Cholesky分解)反复解决Jacobian @ delta_params = residualsdelta_params的线性化问题,并应用delta_params作为更新。

请注意,这个lstsq 操作在参数数量上具有三次复杂度,因此在神经网络的情况下,它只能应用于相当小的网络。

另请注意,Levenberg-Marquardt 通常用作批处理算法,而不是像 SGD 这样的小批量算法,尽管没有什么可以阻止您在每次迭代中对不同的小批量应用 LM 迭代。 p>

我认为您可能只能通过类似的方式从 tfg 的 LM 算法中获得一次迭代

from tensorflow_graphics.math.optimizer.levenberg_marquardt import minimize as lm_minimize

for input_batch, target_batch in dataset:

    def residual_fn(trainable_params):
        # do not use trainable params, it will still be at its initial value, since we only do one iteration of Levenberg Marquardt each time.
        return model(input_batch) - target_batch

    new_objective_value, new_params = lm_minimize(residual_fn, model.trainable_variables, max_iter=1)
    for var, new_param in zip(model.trainable_variables, new_params):
        var.assign(new_param)

相比之下,我相信以下简单的方法行不通,我们在计算残差之前分配模型参数:

from tensorflow_graphics.math.optimizer.levenberg_marquardt import minimize as lm_minimize

dataset_iterator = ...

def residual_fn(params):
    input_batch, target_batch = next(dataset_iterator)
    for var, param in zip(model.trainable_variables, params):
        var.assign(param)
    return model(input_batch) - target_batch

final_objective, final_params = lm_minimize(residual_fn, model.trainable_variables, max_iter=10000)
for var, final_param in zip(model.trainable_variables, final_params):
    var.assign(final_param)

主要的概念问题是residual_fn 的输出相对于其输入params 没有梯度,因为这种依赖关系通过tf.assign。但它甚至可能在此之前失败,因为使用了图形模式下不允许的构造。

总的来说,我认为最好编写自己的 LM 优化器,它适用于 tf.Variables,因为 tfg.math.optimizer.levenberg_marquardt.minimize 有一个非常不同的 API,它并不适合优化 Keras 模型参数,因为你不能直接计算 model(input, parameters) - target_value没有tf.assign

【讨论】:

以上是关于是否可以将 Tensorflow Graphics 的 Levenberg-Marquardt 优化器与 Tensorflow 2.0 模型集成?的主要内容,如果未能解决你的问题,请参考以下文章

使用 android.graphics.pdf 创建多页 PDF

是否可以在 TensorFlow 上加载学习模型(.t7)?

是否可以通过 Aspect Fit 调整大小在 Core Graphics 中显示图像?

如何将 CoreML 模型转换为 TensorFlow 模型?

是否有将 tensorflow NN 转换为 Jax 的模块?

Ubuntu 18.04 64位安装tensorflow-gpu