如何在 Tensorflow 中创建优化器

Posted

技术标签:

【中文标题】如何在 Tensorflow 中创建优化器【英文标题】:How to create an optimizer in Tensorflow 【发布时间】:2016-11-20 17:26:23 【问题描述】:

我想在 Tensorflow 上为我的网络编写一个新的优化算法。我希望实现Levenberg Marquardt optimization algorithm,它现在已从 TF API 中排除。我发现关于如何编写自定义优化器的文档很差,所以我问是否有人可以给我任何建议。谢谢。

【问题讨论】:

阻尼因子与张量流无关。神经网络不需要岭回归……我不了解这个社区。 +1 提出了一个很好的令人兴奋的问题。对我来说,提供一个好的答案需要一些学习,这是我最喜欢的 SO 方面。 您是否曾设法在 TensorFlow 中创建自定义优化器?如果你有一个通过 github 链接到你的代码或其他东西会非常有帮助! dga's answer 如果您想在 TensorFlow 语言接口之间制作(可能)更快且可重用的优化器,则很有用,但如果您只想在 Python 中实现一个优化器以在 Python 中使用,请查看 @ 987654323@:tensorflow.org/api_docs/python/tf/contrib/opt/… 你最终能完成你的目标吗?我也想做同样的事,并愿意听听你的经历,阿尔贝托。谢谢 【参考方案1】:

最简单的优化器示例可能是gradient descent optimizer。它显示了如何创建基本optimizer class 的实例。优化器基类文档解释了这些方法的作用。

优化器的 python 端向图中添加了新节点,用于计算和应用反向传播的梯度。它提供传递给操作的参数并执行优化器的一些高级管理。然后,您需要实际的“应用”操作。

Ops 有一个 python 和一个 C++ 组件。编写训练操作与general process of adding an Op to TensorFlow 相同(但专业化)。

有关计算和应用梯度的一组训练操作示例,请参阅 python/training/training_ops.py - 这是实际训练操作的 Python 粘合剂。请注意,这里的代码主要是关于形状推断的——计算将在 C++ 中进行。

应用渐变的实际数学由 Op 处理(回想一下,通常,op 是用 C++ 编写的)。在这种情况下,应用渐变操作在core/kernels/training_ops.cc 中定义。例如,您可以在其中看到 ApplyGradientDescentOp 的实现,它引用了一个函子 ApplyGradientDescent:

var.device(d) -= grad * lr();

操作本身的实现遵循添加操作文档中描述的任何其他操作的实现。

【讨论】:

感谢您的解释。这是在 C++ 中完成的吗?我看不出用 C++ 编写这个简单的计算(标量乘法和逐元素减法)应该比 Python 快得多。对于原型优化器,在 Python 中做所有事情都会很有用。你知道这是否可能吗? @danijar 原因很简单,Python 只是 Tensorflow 的可用接口之一。在 C++ 中实现核心机制有助于为其他语言创建接口。 抱歉,tensorflow 的代码真的很密集而且很混乱。那么在代码中究竟哪里可以找到apply_gradient 操作在数学上的作用呢?例如,我正在阅读github.com/tensorflow/tensorflow/blob/master/tensorflow/python/…,它似乎没有任何数学表达式,梯度下降优化器github.com/tensorflow/tensorflow/blob/master/tensorflow/python/… 的代码也没有。我在哪里可以看到应用渐变的使用情况? 此文件提供了如何在 Python 中实现优化器类的一个很好的示例:github.com/openai/iaf/blob/master/tf_utils/adamax.py【参考方案2】:

在运行 Tensorflow 会话之前,应该启动一个 Optimizer,如下所示:

# Gradient Descent
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

tf.train.GradientDescentOptimizerGradientDescentOptimizer 类的对象,顾名思义,它实现了梯度下降算法。

方法 minimize() 以“成本”作为参数被调用,由 compute_gradients()apply_gradients()apply_gradients() 两个方法组成/strong>。

对于大多数(自定义)优化器实现,apply_gradients() 方法需要进行调整。

此方法依赖于我们将创建的(新)优化器(类)来实现以下方法:_create_slots()、_prepare()、_apply_dense() 和 _apply_sparse() .

_create_slots()_prepare() 创建和初始化额外的 变量,例如动量。

_apply_dense()_apply_sparse() 实现了更新变量的实际操作。

Ops 通常是用 C++ 编写的。无需自己更改 C++ 标头,您仍然可以通过这些方法返回一些 Ops 的 python 包装器。 这样做如下:

def _create_slots(self, var_list):
   # Create slots for allocation and later management of additional 
   # variables associated with the variables to train.
   # for example: the first and second moments.
   '''
   for v in var_list:
      self._zeros_slot(v, "m", self._name)
      self._zeros_slot(v, "v", self._name)
   '''
def _apply_dense(self, grad, var):
   #define your favourite variable update
    # for example:
   '''
   # Here we apply gradient descents by substracting the variables 
   # with the gradient times the learning_rate (defined in __init__)
   var_update = state_ops.assign_sub(var, self.learning_rate * grad) 
   '''
   #The trick is now to pass the Ops in the control_flow_ops and 
   # eventually groups any particular computation of the slots your 
   # wish to keep track of:
   # for example:    
   '''
    m_t = ...m... #do something with m and grad
    v_t = ...v... # do something with v and grad
    '''
  return control_flow_ops.group(*[var_update, m_t, v_t])

有关示例的更详细说明,请参阅此博客文章 https://www.bigdatarepublic.nl/custom-optimizer-in-tensorflow/

【讨论】:

您的示例对如何使用它没有帮助。你只是扔了一些功能,就是这样。我试过这样打电话:p = PowerSign()distance = RosenbrockOpt(p)。没用! 嗨@cyboroid,我不确定你是如何使用这些课程的。这是一个使用该博客文章中的代码的快速 colab 笔记本。colab.research.google.com/drive/… 谢谢。我回复晚了,但你的笔记本工作,我不确定我做错了什么。看起来和我做的一模一样。 @BenoitDescamps 您能否分享一个在 TensorFlow 2.0 中执行此操作的示例?

以上是关于如何在 Tensorflow 中创建优化器的主要内容,如果未能解决你的问题,请参考以下文章

介绍 TensorFlow 估算器

如何在张量流中创建独立的 LSTM 单元?

如何使用 TensorFlow 在一层中创建并行线性计算?

尝试在tensorflow中创建OCR,字母训练后怎么办?

Tensorflow:如何正确使用 Adam 优化器

Tensorflow2.0笔记