【问题标题】:Do the operations defined in array ops in Tensorflow have gradient defined?Tensorflow 中数组操作中定义的操作是否定义了梯度?
【发布时间】:2019-02-15 01:59:27
【问题描述】:

我想知道this link 中的张量流操作是否定义了梯度。我问是因为我正在实现一个自定义损失函数,当我运行它时,我总是有这个错误:

ValueError: An operation has `None` for gradient. Please make sure that all of your ops have a gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval.

这是我的自定义损失函数:

def calculate_additional_loss(y_true,y_pred):
#additional loss
x_decoded_normalized = original_dim* y_pred
#y_true = K.print_tensor(y_true, message='y_true = ')
#y_pred = K.print_tensor(y_pred, message='y_pred = ')
error = tf.constant(0, dtype= tf.float32)
additional_loss= tf.constant(0, dtype= tf.float32)
final_loss= tf.constant(0, dtype= tf.float32)
for k in range(batch_size):
    #add padding
    reshaped_elem_1 = K.reshape(x_decoded_normalized[k], [DIM,DIM])

    a = K.reshape(reshaped_elem_1[:,DIM-1], [DIM,1])
    b = K.reshape(reshaped_elem_1[:,1], [DIM,1])

    reshaped_elem_1 = tf.concat ([b,reshaped_elem_1], axis= 1)
    reshaped_elem_1 = tf.concat ([reshaped_elem_1,a], axis= 1)

    c= K.reshape(reshaped_elem_1[DIM-1,:], [1,DIM+2])
    d= K.reshape(reshaped_elem_1[1,:], [1,DIM+2])
    reshaped_elem_1 = tf.concat ([d,reshaped_elem_1],axis=0)
    reshaped_elem_1 = tf.concat ([reshaped_elem_1,c],axis=0)

    for (i,j) in range(reshaped_elem_1.shape[0],reshaped_elem_1.shape[1]):
        error = tf.add(error, tf.pow((reshaped_elem_1[i,j]- 
                       reshaped_elem_1[i,j+1]),-2), 
                       tf.pow((reshaped_elem_1[i,j]-reshaped_elem_1[i,j- 
                       1]),-2), tf.pow((reshaped_elem_1[i,j]- 
                       reshaped_elem_1[i-1,j]),-2), 
                       tf.pow((reshaped_elem_1[i,j]-reshaped_elem_1[i+1,j]),-2))
    additional_loss = tf.add(additional_loss, tf.divide(error, original_dim))
final_loss += tf.divide(additional_loss, batch_size)
print('final_loss', final_loss)
return final_loss

这就是我所说的:

models = (encoder, decoder)
additional_loss = calculate_additional_loss(inputs,outputs)
vae.add_loss(additional_loss)
vae.compile(optimizer='adam')
vae.summary()

plot_model(vae,to_file='vae_mlp.png',show_shapes=True)
vae.fit(x_train, epochs=epochs, batch_size=batch_size, validation_data=(x_test, None), verbose = 1, callbacks=[CustomMetrics()])

提前谢谢你。

【问题讨论】:

    标签: tensorflow keras loss-function gradient


    【解决方案1】:

    大多数操作都有定义的渐变。有些操作没有定义渐变,您收到的错误消息为您提供了一些示例。

    话虽如此,我在您的代码中看到了几个错误:

    1. final_loss 被定义为 tf.constant,但您正在尝试增加它。
    2. 您正在从range 获取一个元组
    3. error 被定义为 tf.constant,但您正在尝试增加它。
    4. 不要以这种方式在batch_size 上使用for 循环。而是使用 TensorFlow 函数直接处理 batch 维度。这样一来,您只是在增加您的节点。
    5. 您编写代码的方式让我觉得您将 TensorFlow 视为纯 Python。它不是。您定义图形,然后在会话中执行它。因此,在函数中使用 TF 函数来定义计算。

    【讨论】:

    • 感谢@Ujjwal 的贡献。我已经纠正了第 1 点和第 3 点。现在 final_losserror 是初始化为 0 的常量。关于第 4 点,我想在批处理中进行迭代(我的 batch_size:10 )。我找到了这个 TF 函数 'tf.train.batch' 但我认为它没有帮助。请问你有什么代码建议吗?我将编辑我的帖子以添加我调用此附加损失函数的位置。
    • 在您的代码中,您在loop 中执行的所有操作都可以直接在一个批处理上完成,例如reshapeconcat。因此,您可以完全消除 for 循环。常数是常数。如果将它们初始化为0,则意味着永远保持这种状态。如果你想修改它,你需要声明一个tf.Variable
    • 关于 for 循环,我试图编译模型,但我得到了这个错误:ValueError: Cannot reshape a tensor with 360 elements to shape [6,6] (36 elements) for 'Reshape_100' .这是我认为很合乎逻辑的。这就是为什么我首先要迭代。我的输入具有 (10,36) 的形状,这意味着 36 个元素的 10 个向量。我想重塑每个元素。那么在这种情况下你有什么建议呢?
    • 您不能只删除 for 循环。您必须在操作中包含批处理维度。
    • 你能不能举个例子,一个链接,我可以更好地理解你的意思
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    • 2019-06-25
    • 2020-09-07
    相关资源
    最近更新 更多