Keras - 没有广播的Dot层?

时间:2017-04-04 22:35:42

标签: machine-learning tensorflow keras

我正在使用带有Tensorflow后端的Keras 2.0.2。我试图将批量点产品作为图层的一部分。我不完全确定如何做到这一点,而且我所看到的任何事情似乎都没有所需的功能。

特别是,我有两层形状(无,2,50,5,3)和(无,2,50,3,1),我想采取'的点积。 3'尺寸,并在(无,2,50)维度上广播 - 即,我想要输出(无,2,50,5,1)。我的用例很简单:我在一个序列的每个时间步计算一个矩阵(5,3)和一个向量(3,1),我想在每个时间步都得到它们的点积。

以下是一个显示我遇到的问题的示例:

import keras
import keras.backend as K
from keras.layers import Dot, Input

v1 = K.variable(value=np.random.rand(2, 50, 5, 3))
v2 = K.variable(value=np.random.rand(2, 50, 3, 1))
K.batch_dot(v1, v2)  # this works as desired, gives output shape: (2, 50, 5, 1)

x1 = Input((2, 50, 3, 5)) # shape: (None, 2, 50, 3, 5)
x2 = Input((2, 50, 3, 1)) # shape: (None, 2, 50, 3, 1)
Dot(3)([x1, x2]) # output shape is (None, 2, 50, 5, 2, 50, 1)

奇怪的是,Dot图层的代码(https://github.com/fchollet/keras/blob/master/keras/layers/merge.py)实际上使用的是K.batch_dot,但行为却不一样。

这似乎与文档中陈述的行为相矛盾: " E.g。如果应用于形状a的两个张量b(batch_size, n),     输出将是一个形状张量(batch_size, 1)     其中每个条目i将是其间的点积     a[i]b[i]。"

我尝试过其他没有成功的事情,例如将K.batch_dot包装在Lambda层中(只能输入一个输入 - 不应该有一个等效的通用层,需要多个输入吗?)或将Dot层包装在TimeDistributed Layer中(这似乎不起作用)因为TimeDistributed不能将列表作为输入处理。)

非常感谢任何建议!

1 个答案:

答案 0 :(得分:3)

所以我想出了几种方法:

1)如果你想学习你正在应用于矢量的矩阵的参数(这是你的输入的某个函数),你可以简单地应用一个具有线性激活而没有偏差的TimeDistributed Dense图层。

2)如果你想让矩阵成为你输入的某个函数(即你想将一个层的输出重新整形为一个矩阵,然后将它应用到某个矢量,这个矢量是你的数据的函数),你可以将K.batch_dot包装在Lambda图层中,其中图层将单个列表参数作为输入。 即: Lambda(lambda x: K.batch_dot(x[0], x[1]))([x1, x2])。 我以前做的事情的问题是我没有将输入作为列表,而Lamdba层不能输入超过1个。

还有文档问题 - 而且用例(2)应该(IMO)更容易找到。但上述解决方案应该有效。