【问题标题】:Can I use a Tensor as a list index?我可以使用张量作为列表索引吗?
【发布时间】:2020-03-05 15:15:42
【问题描述】:

我有这个自定义 Keras 层,它可以在列表的元素之间进行选择,比如密集层,我希望它直接返回它预测的列表元素。 该列表是Keras.layers.Layer 的列表。 我有这段代码:

def call(self, inputs, context):   
    pred = tf.argmax(tf.matmul(context, self.kernel))
    return self.layers[pred](inputs)

它抛出一个错误:TypeError: list indices must be integers or slices, not Tensor,这是可以理解的,但我找不到让它工作的方法。 “pred”张量没有.numpy 属性,尽管我急切地运行程序,因为这发生在构建层时。

我知道可能没有解决方案,如果有,请提交关于如何以其他方式对这一层进行编码的想法。

【问题讨论】:

  • 我不确定,但我认为在子类化 tf.keras.Layer 时不能调用 .numpy。我认为 call 函数中的所有内容都必须在 tensorflow 本身中声明。所以让我们试试吧!如何使用tf.concatenatetf.stacktf.layers.Concatenate 或其他东西(而不是在列表中)对self.layers 进行分组,然后使用tf.gather 按索引选择正确的?
  • @Frederik Bode 你实际上不能在tf.keras.layers.Layer 中调用.numpy。你的想法听起来不错,但是一旦堆叠(还没有尝试过其他选项),层就会变成张量,你不能把它作为一个函数来调用。
  • eurgh - 它超级难看,但你可以嵌套tf.condtf.cond(tf.equals(pred, 0), self.layers[0](inputs), tf.cond(tf.equals(pred,1), self.layers[1](inputs), ...)。您可能可以使用递归或 for 循环来格式化这一点图形构造。
  • @Frederik Bode 我什至不知道 tf.cond 存在。这是你推荐的吗? for i, layer in enumerate(self.layers): tf.cond(tf.equals(pred, i), layer(inputs))

标签: python tensorflow keras deep-learning keras-layer


【解决方案1】:

还有一个更大的问题。

这一层将无法工作,因为您无法获得argmax 的导数,kernel 将无法训练。您将收到一条错误消息,例如“An operation has None for gradient”

作为一种解决方法,我建议您:

  • 1:计算所有层(希望它们具有相同的形状?)
  • 2:在第二维中堆叠他们的结果:tf.stack([listf_of_outputs],axis=1)
  • 2:对matmul的结果取一个softmax
  • 3:将softmax的结果重塑为与上面堆叠结果相同的维数:shape (-1, number_of_layers, _other_dims_if_exist, 1)
  • 4:将堆叠的结果乘以(按元素*)重塑后的 softmax 并对轴 1 求和。

【讨论】:

  • 这解释了为什么我的前一层也不起作用。我会尝试准确地编写代码,并让您随时了解它是否成功。值得庆幸的是,所有图层都应该具有相同的形状。
  • 非常感谢,这是我目前缺少的那种数学技巧。我已经能够构建我的第一个门控模型(尽管我仍然需要改进技术)!
  • :D -- 如果结果不是很好,你可以试试sigmoid而不是softmax,这样的话门会很漏水或者也可以关闭所有门。跨度>
  • 您将如何设置sigmoid 的参数,以便在闸门中有或多或少的“泄漏”?这对我的GNNs 来说可能是一个相当有趣的功能,我希望它尽可能地可定制。
  • 我通常会怎么做,而不是拥有Dense(16),我会拥有一个带有两个Dense(8) 的门。想象一下之前的层也是Dense(16),你有16*16+16=272 的权重,而16*8+8+C*2 的C 可能很小。从某种意义上说,它可以让您将图层切割成不同的块
猜你喜欢
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2015-12-01
相关资源
最近更新 更多