【问题标题】:How do I find the non differentiable operation in my layer?如何在我的层中找到不可微分的操作?
【发布时间】:2019-09-10 00:06:44
【问题描述】:

我正在尝试在 keras 中创建一个包含许多操作的相当复杂的 lambda 层。在我实现它之后,我得到了一个ValueError: No gradients provided for any variable

虽然我只使用 keras 操作来转换数据,(除了我使用 numpy 创建的常量,我后来添加到张量中)我知道必须有一些不可微分的操作。现在我想知道如何确定它是哪一个,以便找到解决方法。

我还不想发布任何代码,因为它是竞赛的一部分,我想自己解决这个问题。如果因此难以理解我的问题,请告诉我。但是,我可以列出我正在使用的所有功能:

from tensorflow.keras import backend as K
from tensorflow.python.keras.layers import Lambda

...
def my_lambda_function(x):
    # uses:
    K.batch_dot
    K.cast
    K.clip
    K.concatenate
    K.one_hot
    K.reshape
    K.sum
    K.tile  # only applied to a constant created in numpy

...
# using the function in a model like this:
my_lambda_layer = Lambda(my_lambda_function)
result_tensor = my_lambda_layer(some_input)

我认为 K.one_hot 可能有问题,但我想在尝试使其可微之前确定这一点

【问题讨论】:

  • 信息不足,无法给出正确答案。您使用 one_hot 的事实意味着您正在处理离散数据,而且这通常是不可区分的。
  • 我正在创建一个层,该层基于最后一层的输出向量的位置应用一种诉诸向量。因此,我需要 one_hot 将输出向量映射到矩阵以将其与另一个相乘。不过,近似值会很好,因为离散化当然会杀死梯度。我想也许 tensorflow 可能会近似这些操作的梯度。

标签: python tensorflow keras keras-layer differentiation


【解决方案1】:

睡了几个小时后,这是我的简单解决方案:创建一个简单的 NN 进行测试并添加一个 lambda 层,我在其中分别尝试所有功能。然而,这只是发现问题的一种间接方式。这是我的代码:

from tensorflow.python.keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, Conv2DTranspose, Lambda
from tensorflow.python.keras.models import Sequential
from tensorflow.keras.datasets.mnist import load_data

from tensorflow.keras import backend as K

import tensorflow as tf
import numpy as np

(x_train, y_train), (x_test, y_test) = load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
x_train, x_test = np.reshape(x_train, (-1, 28, 28, 1)), np.reshape(x_test, (-1, 28, 28, 1))


def test_function(x):
    x_int = K.cast(x, tf.int16)  # this was one of the gradient killers in my case
    return K.cast(x_int, tf.float16)


model = Sequential()
model.add(Input(shape=(28, 28, 1)))
model.add(Conv2D(10, (5, 5), padding='same', activation='relu'))
model.add(MaxPooling2D())
model.add(Lambda(test_function))
model.add(UpSampling2D())
model.add(Conv2DTranspose(4, (5, 5), padding='same', activation='relu'))
model.add(Conv2DTranspose(1, (3, 3), padding='same', activation='sigmoid'))

model.compile(optimizer='adam',
              loss='mse',
              metrics=['accuracy'])

model.fit(x_train, x_train, epochs=5)
model.evaluate(x_test, x_test)

这对我有用,但我希望有更好的解决方案。

顺便说一句。我可以使用这些函数来近似地板操作(这也消除了渐变):

def a(x):
    two_pi = 2 * math.pi
    two_pi_x = x * two_pi
    sine = K.sin(two_pi_x)
    numerator = sine + two_pi_x
    return numerator / two_pi


def approximated_floor(x):
    x2 = a(a(a(x))) - 0.5
    return x2

【讨论】:

    猜你喜欢
    • 2019-06-03
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    相关资源
    最近更新 更多