Tensorflow:在函数内部填充张量

时间:2019-09-11 14:34:54

标签: python tensorflow

我要定义的是以下想法:

考虑这些张量

a = tf.constant([1., 1.5, 1.2]) # tensor with shape [3,]
b = tf.constant([1., 2., 3.])   # ""
c = tf.constant([3., 0., 6.])   # ""

t = tf.constant([0.5, 0.6, 0.7, 2., 4., 5., 6.]) # tensor with shape [7,]

现在让我们考虑我要计算一个新的张量,使用先前的张量的每个元素,例如:

def new_tensor(a, b, c, t):
    X = tf.constant([[tf.sin(a*t[1]), b*t[3], c+t[4]], 
        [tf.cos(b*t[5]), tf.atan2(t[5], c), a+t[2]+b],  
        [a+t[4], a+b, c*t[0]]])
    return X

X应该是形状为[3, 3, 3]的张量。也就是说,我想定义一个函数,该函数需要四个张量作为输入:其中三个具有相同的形状,而第四个具有不同的形状。我希望函数为前三个输入(X)的每个值计算张量(a, b, c)。

使用此代码,TensorFlow会出现此错误:

TypeError: List of Tensors when single Tensor expected

根据此post,这是因为tf.constant不能采用张量作为输入,因此他们建议改用tf.Variable。但是我认为这不适合我,因为我以后必须使用X并且不想初始化它,等等。我也读过other post,但是找不到任何内容回答我的问题。

有什么办法可以做我想要的吗?我的代码对我的目的有意义吗?预先谢谢你。

更新:带有jdehesa答案

获取@jdehesa答案并使结果张量更简单:

def new_tensor(a, b, c, t):
    # Could also use tf.convert_to_tensor
    X = tf.stack([[a+t[1],   b*t[1],    c+t[1]],
                  [b*t[0],  t[5]+ c,  a+t[2]+b],
                  [a+t[4],      a+b,   c*t[0]]])
    return X

并带有张量:

a = tf.constant([1., 1., 1.]) # tensor with shape [3,]
b = tf.constant([2., 2., 2.])   # ""
c = tf.constant([3., 3., 3.])   # ""

t = tf.constant([1., 1., 1., 1., 1., 1., 1.]) # tensor with shape [7,]

我得到的是以下张量:

# When evaluating x = new_tensor(a,b,c,t)
[[[2. 2. 2.]
  [2. 2. 2.]
  [4. 4. 4.]]

 [[2. 2. 2.]
  [4. 4. 4.]
  [4. 4. 4.]]

 [[2. 2. 2.]
  [3. 3. 3.]
  [3. 3. 3.]]]

但是我期望的是以下内容:

[[[2. 2. 4.]
  [2. 4. 4.]
  [2. 3. 3.]]

 [[2. 2. 4.]
  [2. 4. 4.]
  [2. 3. 3.]]

 [[2. 2. 4.]
  [2. 4. 4.]
  [2. 3. 3.]]]

正如我希望它对输入张量的每个元素求值。

1 个答案:

答案 0 :(得分:4)

是的,您只能将Python或NumPy值传递给tf.constant,但可以使用tf.stack或(如果愿意)通常使用tf.convert_to_tensor来构建张量:

import tensorflow as tf

def new_tensor(a, b, c, t):
    # Could also use tf.convert_to_tensor
    X = tf.stack([[tf.sin(a*t[1]),            b*t[3],   c+t[4]],
                  [tf.cos(b*t[5]), tf.atan2(t[5], c), a+t[2]+b],
                  [        a+t[4],               a+b,   c*t[0]]])
    return X

with tf.Graph().as_default(), tf.Session() as sess:
    a = tf.constant([1., 1.5, 1.2]) # tensor with shape [3,]
    b = tf.constant([1., 2., 3.])   # ""
    c = tf.constant([3., 0., 6.])   # ""
    t = tf.constant([0.5, 0.6, 0.7, 2., 4., 5., 6.]) # tensor with shape [7,]
    x = new_tensor(a, b, c, t)
    print(sess.run(x))
    # [[[ 0.5646425   0.7833269   0.65938467]
    #   [ 2.          4.          6.        ]
    #   [ 7.          4.         10.        ]]
    # 
    #  [[ 0.2836622  -0.8390715  -0.7596879 ]
    #   [ 1.0303768   1.5707964   0.69473827]
    #   [ 2.7         4.2         4.9       ]]
    # 
    #  [[ 5.          5.5         5.2       ]
    #   [ 2.          3.5         4.2       ]
    #   [ 1.5         0.          3.        ]]]

编辑:对于第二个示例,要获得所需的结果,您需要使用tf.transpose来更改张量尺寸的顺序:

import tensorflow as tf

def new_tensor(a, b, c, t):
    # Could also use tf.convert_to_tensor
    X = tf.stack([[a+t[1],   b*t[1],    c+t[1]],
                  [b*t[0],  t[5]+ c,  a+t[2]+b],
                  [a+t[4],      a+b,   c*t[0]]])
    X = tf.transpose(X, (2, 0, 1))
    return X

with tf.Graph().as_default(), tf.Session() as sess:
    a = tf.constant([1., 1., 1.]) # tensor with shape [3,]
    b = tf.constant([2., 2., 2.])   # ""
    c = tf.constant([3., 3., 3.])   # ""
    t = tf.constant([1., 1., 1., 1., 1., 1., 1.]) # tensor with shape [7,]
    x = new_tensor(a, b, c, t)
    print(sess.run(x))
    # [[[2. 2. 4.]
    #   [2. 4. 4.]
    #   [2. 3. 3.]]
    # 
    #  [[2. 2. 4.]
    #   [2. 4. 4.]
    #   [2. 3. 3.]]
    # 
    #  [[2. 2. 4.]
    #   [2. 4. 4.]
    #   [2. 3. 3.]]]