Levenberg-Marquardt 优化算法的 keras 实现作为自定义优化器
keras implementation of Levenberg-Marquardt optimization algorithm as a custom optimizer
我正在尝试将 Levenberg-Marquardt 算法实现为 Keras 优化器,如前所述 here 但我有几个问题,最大的一个是这个错误
TypeError: Tensor objects are not iterable when eager execution is not enabled. To iterate over this tensor use tf.map_fn.
快速搜索后我发现这与 tensorflow 是如何连接的 运行ning 带有图表的程序,我在 details.I 中发现这个答案很有用 from SO但它是关于损失函数,而不是优化器。
说到点子上。
我的尝试是这样的:
from keras.optimizers import Optimizer
from keras.legacy import interfaces
from keras import backend as K
class Leveberg_Marquardt(Optimizer):
def __init__(self, tau =1e-2 , lambda_1=1e-5, lambda_2=1e+2, **kwargs):
super(Leveberg_Marquardt, self).__init__(**kwargs)
with K.name_scope(self.__class__.__name__):
self.iterations = K.variable(0, dtype='int64', name='iterations')
self.tau = K.variable(tau,name ='tau')
self.lambda_1 = K.variable(lambda_1,name='lambda_1')
self.lambda_2 = K.variable(lambda_2,name='lambda_2')
@interfaces.legacy_get_updates_support
def get_updates(self, loss, params):
grads = self.get_gradients(loss,params)
self.updates = [K.update_add(self.iterations,1)]
error = [K.int_shape(m) for m in loss]
for p,g,err in zip(params,grads,error):
H = K.dot(g, K.transpose(g)) + self.tau * K.eye(K.max(g))
w = p - K.pow(H,-1) * K.dot(K.transpose(g),err) #ended at step 3 from http://mads.lanl.gov/presentations/Leif_LM_presentation_m.pdf
if self.tau > self.lambda_2:
w = w - 1/self.tau * err
if self.tau < self.lambda_1:
w = w - K.pow(H,-1) * err
# Apply constraints.
if getattr(p, 'constraint', None) is not None:
w = p.constraint(w)
self.updates.append(K.update_add(err, w))
return self.updates
def get_config(self):
config = {'tau':float(K.get_value(self.tau)),
'lambda_1':float(K.get_value(self.lambda_1)),
'lambda_2':float(K.get_value(self.lambda_2)),}
base_config = super(Leveberg_Marquardt, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
Q1 我可以在不深入 tensorflow 的情况下修复这个错误吗(我希望我可以通过保持在 Keras 级别来做到这一点)
Q2 我使用keras后端的方式正确吗?
我的意思是,在这一行中
H = K.dot(g, K.transpose(g)) + self.tau * K.eye(K.max(g))
我应该使用 keras 后端函数,或 numpy 或纯 python 以便 运行 这段代码没有输入数据是 numpy 数组的问题?
Q3这个问题更多的是关于算法本身。
我是否正确实施了 LMA?我必须说,我不确定如何处理边界条件,我猜 tau/lambda 值,也许你知道更好的方法?
我试图了解 keras 中的所有其他优化器是如何工作的,但即使是 SGD 代码对我来说也是模棱两可的。
Q4 我是否需要以任何方式更改本地文件 optimizers.py?
为了 运行 它正确地初始化我的优化器:
myOpt = Leveberg_Marquardt()
然后简单地将它传递给 complie 方法。然而,在快速查看 optimizers.py 的源代码后,我发现代码中有一些地方明确写入了优化器的名称(例如反序列化函数)。为我的自定义优化器扩展它很重要还是我可以保留它?
我非常感谢任何帮助和未来行动的方向。
Q1 Can I fix this error without going deep into tensorflow (I wish I
could do this by staying on Keras level)
A1 我相信即使修复了这个错误,在keras不支持的算法的实现中仍然存在问题,例如错误术语f(x;w_0)-y
来自文档的 keras 优化器不可用。
Q2 Do I use keras backend in correct way?
A2 是的,您必须使用 keras 后端进行此计算,因为 g
是张量对象而不是 numpy 数组。但是,我认为 H
的正确计算应该是 H = K.dot(K.transpose(g), g)
以获取 Nx1 向量 g 并执行外积以生成 NxN 矩阵。
Q3 This question is more about the algorith itself.
A3 如 A1 中所述,我不确定 keras 是否支持此算法所需的输入。
Q4 Do I need to change in any way local file optimizers.py?
A4 如果将提供的代码行作为优化器参数提供给 keras 的模型编译函数,则将 运行 优化器。为方便起见,keras 库支持通过名称调用内置的 类 和函数。
我正在尝试将 Levenberg-Marquardt 算法实现为 Keras 优化器,如前所述 here 但我有几个问题,最大的一个是这个错误
TypeError: Tensor objects are not iterable when eager execution is not enabled. To iterate over this tensor use tf.map_fn.
快速搜索后我发现这与 tensorflow 是如何连接的 运行ning 带有图表的程序,我在 details.I 中发现这个答案很有用 from SO但它是关于损失函数,而不是优化器。
说到点子上。
我的尝试是这样的:
from keras.optimizers import Optimizer
from keras.legacy import interfaces
from keras import backend as K
class Leveberg_Marquardt(Optimizer):
def __init__(self, tau =1e-2 , lambda_1=1e-5, lambda_2=1e+2, **kwargs):
super(Leveberg_Marquardt, self).__init__(**kwargs)
with K.name_scope(self.__class__.__name__):
self.iterations = K.variable(0, dtype='int64', name='iterations')
self.tau = K.variable(tau,name ='tau')
self.lambda_1 = K.variable(lambda_1,name='lambda_1')
self.lambda_2 = K.variable(lambda_2,name='lambda_2')
@interfaces.legacy_get_updates_support
def get_updates(self, loss, params):
grads = self.get_gradients(loss,params)
self.updates = [K.update_add(self.iterations,1)]
error = [K.int_shape(m) for m in loss]
for p,g,err in zip(params,grads,error):
H = K.dot(g, K.transpose(g)) + self.tau * K.eye(K.max(g))
w = p - K.pow(H,-1) * K.dot(K.transpose(g),err) #ended at step 3 from http://mads.lanl.gov/presentations/Leif_LM_presentation_m.pdf
if self.tau > self.lambda_2:
w = w - 1/self.tau * err
if self.tau < self.lambda_1:
w = w - K.pow(H,-1) * err
# Apply constraints.
if getattr(p, 'constraint', None) is not None:
w = p.constraint(w)
self.updates.append(K.update_add(err, w))
return self.updates
def get_config(self):
config = {'tau':float(K.get_value(self.tau)),
'lambda_1':float(K.get_value(self.lambda_1)),
'lambda_2':float(K.get_value(self.lambda_2)),}
base_config = super(Leveberg_Marquardt, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
Q1 我可以在不深入 tensorflow 的情况下修复这个错误吗(我希望我可以通过保持在 Keras 级别来做到这一点)
Q2 我使用keras后端的方式正确吗?
我的意思是,在这一行中
H = K.dot(g, K.transpose(g)) + self.tau * K.eye(K.max(g))
我应该使用 keras 后端函数,或 numpy 或纯 python 以便 运行 这段代码没有输入数据是 numpy 数组的问题?
Q3这个问题更多的是关于算法本身。
我是否正确实施了 LMA?我必须说,我不确定如何处理边界条件,我猜 tau/lambda 值,也许你知道更好的方法?
我试图了解 keras 中的所有其他优化器是如何工作的,但即使是 SGD 代码对我来说也是模棱两可的。
Q4 我是否需要以任何方式更改本地文件 optimizers.py?
为了 运行 它正确地初始化我的优化器:
myOpt = Leveberg_Marquardt()
然后简单地将它传递给 complie 方法。然而,在快速查看 optimizers.py 的源代码后,我发现代码中有一些地方明确写入了优化器的名称(例如反序列化函数)。为我的自定义优化器扩展它很重要还是我可以保留它?
我非常感谢任何帮助和未来行动的方向。
Q1 Can I fix this error without going deep into tensorflow (I wish I could do this by staying on Keras level)
A1 我相信即使修复了这个错误,在keras不支持的算法的实现中仍然存在问题,例如错误术语f(x;w_0)-y
来自文档的 keras 优化器不可用。
Q2 Do I use keras backend in correct way?
A2 是的,您必须使用 keras 后端进行此计算,因为 g
是张量对象而不是 numpy 数组。但是,我认为 H
的正确计算应该是 H = K.dot(K.transpose(g), g)
以获取 Nx1 向量 g 并执行外积以生成 NxN 矩阵。
Q3 This question is more about the algorith itself.
A3 如 A1 中所述,我不确定 keras 是否支持此算法所需的输入。
Q4 Do I need to change in any way local file optimizers.py?
A4 如果将提供的代码行作为优化器参数提供给 keras 的模型编译函数,则将 运行 优化器。为方便起见,keras 库支持通过名称调用内置的 类 和函数。