Tensorflow,更改占位符和传递值

时间:2018-09-20 16:34:51

标签: python tensorflow

我想这样做:

我有2D张量,矩阵的形状是=(None,4),所以N个例子有4个元素, [x,y,a,b]。

X = tf.placeholder(tf.float32, shape=(None, 4))

下一步,我要在坐标(x,y)处具有值为b的矩阵m x n

还给出了Y的形状。例如shapeY =(5,5)

示例:

输入:

X = np.array([[0, 0, 10, 10], 
              [1, 1, 20, 20], 
              [2, 2, 30, 30], 
              [3, 3, 40, 40], 
              [4, 4, 50, 50]])

输出:

Y = [[10, 0, 0, 0, 0],
     [0, 20, 0, 0, 0],
     [0, 0, 30, 0, 0],
     [0, 0, 0, 40, 0],
     [0, 0, 0, 0, 50]]

此示例包含实际值,但是在传递真实值之前,我需要使用占位符作为张量流图的一部分。结果必须是这样。

2 个答案:

答案 0 :(得分:2)

您可以为此使用tf.scatter_nd

import numpy as np
import tensorflow as tf

X = tf.placeholder(tf.float32, shape=(None, 4))

Y = tf.scatter_nd(tf.cast(X[:, :2], tf.int32),
                  X[:, 3],
                  [tf.shape(X)[0], tf.shape(X)[0]])

with tf.Session() as sess:
    print(sess.run(Y, feed_dict={X: np.array([[0, 0, 10, 10],
              [1, 1, 20, 20],
              [2, 2, 30, 30],
              [3, 3, 40, 40],
              [4, 4, 50, 50]])}))

此打印

[[10.  0.  0.  0.  0.]
 [ 0. 20.  0.  0.  0.]
 [ 0.  0. 30.  0.  0.]
 [ 0.  0.  0. 40.  0.]
 [ 0.  0.  0.  0. 50.]]

答案 1 :(得分:1)

我了解您希望X和'Y都是动态的。如果是这样,那么此代码应该起作用。

我通过在init上再添加一行,并在行中添加一行和一列来对其进行测试。

    sess.run(op,{  ph : np.zeros((7,7))})

此代码中的变量ax主要是动态的,并且是通过这两行实现的

ph = tf.placeholder(dtype=tf.int32)
op = tf.assign(ax, ph, validate_shape=False)

该想法是从git issue中获得的。代码中的axinit都被输入。

还有关于一些用于更新zeros张量的自定义逻辑的评论。这可能是正确的TensorFlow API调用。不知道哪一个可以做到。

import tensorflow as tf
import numpy as np

init = np.array([[0, 0, 10, 10],
                  [1, 1, 20, 20],
                  [2, 2, 30, 30],
                  [3, 3, 40, 40],
                  [4, 4, 50, 50],
                  [5, 5, 60, 60],
                  [6, 6, 70, 70]])

X = tf.placeholder( tf.int32, shape=(None, 4))

with tf.variable_scope("foo", reuse=tf.AUTO_REUSE):
    ax = tf.get_variable("ax", dtype=tf.int32, initializer=tf.zeros((5,5),tf.int32), validate_shape=False)

ph = tf.placeholder(dtype=tf.int32)
op = tf.assign(ax, ph, validate_shape=False)


def cond(i , size):
    return tf.less(i,size)

def body(i, size):
    with tf.variable_scope("foo", reuse=tf.AUTO_REUSE):
        #Just split each row, put the value
        #and stitch it back and update the row.
        ax = tf.get_variable("ax", dtype=tf.int32)
        oldrow = tf.gather(ax, i)

        begin = oldrow[: X[i, 0]]
        end = oldrow[X[i, 1]: ( size - 1 )]
        g = tf.gather(tf.gather(X, i), 3)
        newrow = tf.concat([begin, [g], end], axis=0)

        ax = tf.scatter_update(ax, i, newrow)


        with tf.control_dependencies([ax]):
            return ( i+1, size)


with tf.Session() as sess :

    _,i = tf.while_loop(cond,
                          body,
                          [0,tf.shape(X)[0]])

    with tf.variable_scope("foo", reuse=tf.AUTO_REUSE):
        ax = tf.get_variable("ax",dtype=tf.int32)

        sess.run( tf.global_variables_initializer() )
        sess.run(op,{  ph : np.zeros((7,7))})
        print( sess.run( [tf.shape(ax),  ax,i] , {  X: init }  ))

因此对于此代码中的值,输出为this。

[array([7, 7]), array([
       [10,  0,  0,  0,  0,  0,  0],
       [ 0, 20,  0,  0,  0,  0,  0],
       [ 0,  0, 30,  0,  0,  0,  0],
       [ 0,  0,  0, 40,  0,  0,  0],
       [ 0,  0,  0,  0, 50,  0,  0],
       [ 0,  0,  0,  0,  0, 60,  0],
       [ 0,  0,  0,  0,  0,  0, 70]]), 7]