我正在使用带有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不能将列表作为输入处理。)
非常感谢任何建议!
答案 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)更容易找到。但上述解决方案应该有效。