我正在tensorflow中实现RBM。
使用小批量实施参数更新存在障碍
有2个张量
第一张量的形状是[100,3,1] 第二张量的形状是[100,1,4]
数字100是批次的大小。
所以我想将这些张量相乘,从而产生[100,3,4]张量。
但是当我实现像
这样的代码时 tf.tensordot(1st_tensor,2nd_tensor,[[2],[1]])
得到的张量'形状是[100,3,100,4]
我该如何解决这个问题?
答案 0 :(得分:4)
我不确定您是否仍然面临此问题(因为已经过了一个月)但我使用tf.tensordot
和tf.map_fn
解决了同样的问题,它接受嵌套的输入元素和并行化横跨第一个(通常是批处理)维度的函数。以下函数在任意等级的张量的最后两个维度上执行批量并行矩阵乘法(只要最后两个轴匹配矩阵乘法的目的):
def matmul_final_two_dims(tensor1, tensor2):
# set this to the appropriate value, as map_fn seems to have
# some dtype inference difficulties:
_your_dtype_here = tf.float64
return tf.map_fn(lambda xy: tf.tensordot(xy[0], xy[1], axes=[[-1], [-2]]),
elems=(tensor1, tensor2), dtype=_your_dtype_here)
使用示例:
>> batchsize = 3
>> tensor1 = np.random.rand(batchsize,3,4,5,2) # final dims [5,2]
>> tensor2 = np.random.rand(batchsize,2,3,2,4) # final dims [2,4]
>> sess.run(tf.shape(matmul_final_two_dims(tensor1, tensor2)))
array([3, 3, 4, 5, 2, 3, 4], dtype=int32)
>> matmul_final_two_dims(tensor1,tensor2)
<tf.Tensor 'map_1/TensorArrayStack/TensorArrayGatherV3:0' shape=(3, 3, 4, 5, 2, 3, 4) dtype=float64>
特别注意输出的第一个维度是正确的批量大小,并且形状中的最终2
是张量缩小的。但是,您必须执行某种tf.transpose
操作才能在适当的位置获取维度 - 5
索引,因为输出矩阵的索引按照它们在输入张量中的显示进行排序。 / p>
我正在使用TFv1.1。 tf.map_fn
可以并行化,但我不确定上述是否是最有效的实现。供参考:
einsum
(docs here)来完成您想要的任务:
>> tensor1 = tf.constant(np.random.rand(3,4,5))
>> tensor2 = tf.constant(np.random.rand(3,5,7))
>> tf.einsum('bij,bjk->bik', tensor1, tensor2)
<tf.Tensor 'transpose_2:0' shape=(3, 4, 7) dtype=float64>
答案 1 :(得分:0)
您可以改用tf.keras.backend.batch_dot;它期望第一个维度为batch_size
,并应按照您希望的方式进行操作。