【问题标题】:Bilinear Tensor Product in TensorFlowTensorFlow 中的双线性张量积
【发布时间】:2016-03-10 16:39:28
【问题描述】:

我正在重新实现this paper,关键操作是双线性张量积。我几乎不知道那是什么意思,但这篇论文有一个很好的小图形,我理解。

关键操作是e_1 * W * e_2,我想知道如何在tensorflow中实现,因为其余的应该很简单。

基本上,给定 3D 张量 W,将其切片为矩阵,对于第 j 个切片(矩阵),将其在每一边乘以 e_1 和 e_2 ,产生一个标量,它是结果向量中的第 j 个条目(此操作的输出)。

所以我想执行 e_1(一个 d 维向量)、W(dxdxk 张量)和 e_2(另一个d 维向量。这个产品能否像现在一样在 TensorFlow 中简洁地表达,还是我必须以某种方式定义自己的操作?

早期编辑

为什么将这些张量相乘不起作用,有什么方法可以更明确地定义它以使其起作用?

>>> import tensorflow as tf
>>> tf.InteractiveSession()
>>> a = tf.ones([3, 3, 3])
>>> a.eval()
array([[[ 1.,  1.,  1.],
        [ 1.,  1.,  1.],
        [ 1.,  1.,  1.]],

       [[ 1.,  1.,  1.],
        [ 1.,  1.,  1.],
        [ 1.,  1.,  1.]],

       [[ 1.,  1.,  1.],
        [ 1.,  1.,  1.],
        [ 1.,  1.,  1.]]], dtype=float32)
>>> b = tf.ones([3, 1, 1])
>>> b.eval()
array([[[ 1.]],

       [[ 1.]],

       [[ 1.]]], dtype=float32)
>>> 

错误信息是

ValueError: Shapes TensorShape([Dimension(3), Dimension(3), Dimension(3)]) and TensorShape([Dimension(None), Dimension(None)]) must have the same rank

目前

事实证明,将两个 3D 张量相乘也不适用于 tf.matmul,但 tf.batch_matmul 可以。 tf.batch_matmul 也会做 3D 张量和矩阵。然后我尝试了 3D 和矢量:

ValueError: Dimensions Dimension(3) and Dimension(1) are not compatible

【问题讨论】:

  • 你可以通过简单的重塑来做到这一点。
  • 你最终实施了这篇论文吗?

标签: tensorflow


【解决方案1】:

您可以通过简单的重塑来做到这一点。对于两个矩阵乘法中的第一个,您有 k*d、长度为 d 的向量进行点积。

这应该很接近:

temp = tf.matmul(E1,tf.reshape(Wddk,[d,d*k]))
result = tf.matmul(E2,tf.reshape(temp,[d,k]))

【讨论】:

  • 没有“更清洁”的方法吗?我不得不做所有这些重塑,这让我在审美上感到困扰,但如果那是我必须做的......如何在 tensorflow 中实现重塑?它们是移动所有值,还是只是读取值的模式?
  • 我认为他们可能只是改变了“模式”又名步幅,就像在 numpy 中一样。那是super-powerful。他们在conv2d 的文档中暗示了这一点。在修复216 或175 之前,我认为没有更简单的方式来表达这一点。 einsum('i,j,ijk',E,E,W)!
  • TensorFlow 中的 Reshapes 无需副本即可重复使用相同的数据。但 TensorFlow 不使用跨步 - 张量始终以行优先顺序存储。
【解决方案2】:

您可以在 W 和 e2 之间执行 3 阶张量和向量乘法,生成一个二维数组,然后将结果与 e1 相乘。以下函数利用张量积和张量收缩来定义此积(例如 W * e3)

import sympy as sp

def tensor3_vector_product(T, v):
    """Implements a product of a rank 3 tensor (3D array) with a 
       vector using tensor product and tensor contraction.

    Parameters
    ----------
    T: sp.Array of dimensions n x m x k

    v: sp.Array of dimensions k x 1

    Returns
    -------
    A: sp.Array of dimensions n x m

    """
    assert(T.rank() == 3)
    # reshape v to ensure a 1D vector so that contraction do 
    # not contain x 1 dimension
    v.reshape(v.shape[0], )
    p = sp.tensorproduct(T, v)
    return sp.tensorcontraction(p, (2, 3))

您可以使用ref 中提供的示例来验证此乘法。上面的函数收缩第二个和第三个轴,在你的情况下我认为你应该收缩 (1, 2) 因为 W 被定义为 d x d x k 而不是 k x d x d 在我的情况下。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    • 2021-02-07
    • 1970-01-01
    相关资源
    最近更新 更多