keras(或任何其他机器学习框架)如何计算用于反向传播的 lambda 函数层的梯度?

问题描述 投票:0回答:2

Keras 允许添加计算用户定义的 lambda 函数的层。 我不明白的是 Keras 如何知道计算这个用户定义函数的反向传播的梯度。

machine-learning keras
2个回答
7
投票

使用 Theano/Tensorflow 和基于它们的库的好处之一。它们可以为您提供数学函数和运算的自动梯度计算。

Keras 通过调用获取它们:

# keras/theano_backend.py
def gradients(loss, variables):
    return T.grad(loss, variables)

# keras/tensorflow_backend.py
def gradients(loss, variables):
    '''Returns the gradients of `variables` (list of tensor variables)
    with regard to `loss`.
    '''
    return tf.gradients(loss, variables, colocate_gradients_with_ops=True)

依次由优化器(keras/optimizers.py)调用

grads = self.get_gradients(loss, params)
来获取梯度,用于为所有
params
编写更新规则。
params
这里是各层的可训练权重。但是 Lambda 功能层创建的层没有任何可训练的权重。但它们通过前向概率影响损失函数,从而间接影响其他层可训练权重梯度的计算。

唯一需要编写新梯度计算的时候是定义新的基本数学运算/函数时。此外,当您编写自定义损失函数时,自动梯度几乎总是负责梯度计算。但是,如果您实现自定义函数的分析梯度,您可以选择优化训练(并非总是如此)。例如,softwax 函数可以用 exp、sum 和 div 表示,而 auto grad 可以处理它,但其分析/符号梯度通常在 Theano/Tensorflow 中实现。

要实施新的操作,您可以查看以下链接: http://deeplearning.net/software/theano/extending/extending_theano.html https://www.tensorflow.org/versions/r0.12/how_tos/adding_an_op/index.html


0
投票

如果您将打印添加到 lambda 函数,如下所示:

import tensorflow as tf

def f(x):
    print(x)
    return x * 2

m = tf.keras.models.Sequential([
    tf.keras.layers.Input((1,)),
    tf.keras.layers.Lambda(f),
    tf.keras.layers.Dense(1),
   ])
m.compile(loss="mse", optimizer="SGD")
m.fit(tf.convert_to_tensor([1]), tf.convert_to_tensor([2]))

您会发现在训练期间您的函数实际上从未被使用真实值调用。相反,它使用不同的“占位符”张量调用两次,没有实际值:

Tensor("Placeholder:0", shape=(None, 1), dtype=float32)
Tensor("sequential_1/ExpandDims:0", shape=(None, 1), dtype=float32)

当您对这些张量执行操作时,会生成新的“符号”占位符值,您可以看到这些张量跟踪用于生成它们的操作。

(Pdb) (x * 2)._op
<tf.Operation 'mul_26' type=Mul>
(Pdb) (x * 2)._op.inputs
(<tf.Tensor 'Placeholder:0' shape=(None, 1) dtype=float32>, <tf.Tensor 'mul_27/y:0' shape=() dtype=float32>)

张量流数学运算还专门处理这些符号张量,生成新的符号变量并跟踪它们的生成方式。

(Pdb) tf.reduce_sum(x)._op
<tf.Operation 'Sum_1' type=Sum>

一旦您的函数返回由这些数学运算产生的最终符号张量,因为它可以访问整个图,它可以将其符号化。

但是,因为您的函数只是“象征性”调用,所以您无法使用

if
while
for
等定义自己的控制逻辑。相反,您必须使用 tf.condtf 等函数.while_loop.

替代方案,tf.function可以读取Python代码并用可微等价物替换流程控制。

© www.soinside.com 2019 - 2024. All rights reserved.