Python 批次的Tensorflow成对点积

Python 批次的Tensorflow成对点积,python,tensorflow,matrix,keras,Python,Tensorflow,Matrix,Keras,我想训练一个神经网络,为批次的每个元素输入三个浮动列表。例如,批处理的一个元素看起来像vec=[vec_a,vec_b,vec_c]=[1,2,3.],[1.5,6.7,9.],[3.4,0.4,0.3],我希望网络的第一层返回每个不同元素的成对点积。在这种情况下,这将是vec_a*vec_b+vec_a*vec_c+vec_b*vec_c(*在这种情况下表示两个向量之间的点积) 如果我想将其转换为tensorflow模型,我可以执行以下操作 import tensorflow as tf d

我想训练一个神经网络,为批次的每个元素输入三个浮动列表。例如,批处理的一个元素看起来像
vec=[vec_a,vec_b,vec_c]=[1,2,3.],[1.5,6.7,9.],[3.4,0.4,0.3]
,我希望网络的第一层返回每个不同元素的成对点积。在这种情况下,这将是
vec_a*vec_b+vec_a*vec_c+vec_b*vec_c
*
在这种情况下表示两个向量之间的点积)

如果我想将其转换为tensorflow模型,我可以执行以下操作

import tensorflow as tf

def pairwise_dot_product(x):
  matrix_dot_product = tf.tensordot(x, tf.transpose(x), axes=1)
  matrix_sum = tf.math.reduce_sum(matrix_dot_product)
  matrix_diag_sum = tf.linalg.trace(matrix_dot_product)
  return (matrix_sum - matrix_diag_sum)/2

model = tf.keras.Sequential()
model.add(tf.keras.layers.Lambda(pairwise_dot_product, input_shape=(None, ), name="pairwise_dot_product"))
model.compile(optimizer="sgd", loss="categorical_crossentropy")
如果我在
vec

model.layers[0].apply(vec)
我确实得到了正确的答案(
57.480003
)。现在的问题是,我想训练这个模型,使它看起来像这样
training_data=[vec_1,vec_2,vec_3,…]
。为了简单起见,假设我有
training_data=[vec,vec,…]
,因此我希望网络的第一层返回
[57.480003,57.480003,…]
。如何修改网络以实现此目的?我认为问题在于,我定义的
成对点积
函数应用于整个训练批,但我只想应用于批的每个元素(
vec
)。

尝试这种方法

def pairwise_dot_product(x):

    matrix_dot_product = tf.keras.backend.batch_dot(x, tf.transpose(x, [0,2,1]), axes=[2,1])
    matrix_sum = tf.math.reduce_sum(matrix_dot_product, axis=[1,2])
    matrix_diag_sum = tf.linalg.trace(matrix_dot_product)
    return (matrix_sum - matrix_diag_sum)/2

model = tf.keras.Sequential()
model.add(tf.keras.layers.Lambda(pairwise_dot_product, input_shape=(None,None), 
                                 name="pairwise_dot_product"))

vec = [[[1, 2.,3.], [1.5, 6.7, 9.], [3.4, 0.4, 0.3]]]
vec = tf.constant(vec*10) # repeat 10 times vec

model(vec)
结果:

<tf.Tensor: shape=(10,), dtype=float32, numpy=
array([57.480003, 57.480003, 57.480003, 57.480003, 57.480003, 57.480003,
       57.480003, 57.480003, 57.480003, 57.480003], dtype=float32)>


谢谢!你能解释一下你是怎么摘那些斧子的吗?如果我想用N个元素而不是3个元素的向量进行训练,会发生什么?转置需要适应3D输入(批次,3,3),所以我们只需要交换最新的2轴。批次点在关注轴上计算。我认为大小为3x3、10x10或NxN的向量没有任何问题