Skip to main content
 首页 » 编程设计

python之在 tensorflow 中更新张量

2025年05月04日23mengfanrong

我在 tensorflow 中定义了一个无监督问题,我需要在每次迭代时更新我的​​ B 和我的 tfZ,但我不知道如何使用 tensorflow session 更新我的 tfZ。

tfY = tf.placeholder(shape=(15, 15), dtype=tf.float32) 
 
with tf.variable_scope('test'): 
    B = tf.Variable(tf.zeros([])) 
    tfZ = tf.convert_to_tensor(Z, dtype=tf.float32) 
 
def loss(tfY): 
    r = tf.reduce_sum(tfZ*tfZ, 1) 
    r = tf.reshape(r, [-1, 1]) 
    D = tf.sqrt(r - 2*tf.matmul(tfZ, tf.transpose(tfZ)) + tf.transpose(r) + 1e-9) 
    return tf.reduce_sum(tfY*tf.log(tf.sigmoid(D+B))+(1-tfY)*tf.log(1-tf.sigmoid(D+B))) 
 
LOSS = loss(Y) 
GRADIENT = tf.gradients(LOSS, [B, tfZ]) 
 
sess = tf.Session() 
sess.run(tf.global_variables_initializer()) 
 
tot_loss = sess.run(LOSS, feed_dict={tfY: Y}) 
 
loss_grad = sess.run(GRADIENT, feed_dict={tfY: Y}) 
 
learning_rate = 1e-4 
for i in range(1000): 
    sess.run(B.assign(B - learning_rate * loss_grad[0])) 
    print(tfZ) 
    sess.run(tfZ.assign(tfZ - learning_rate * loss_grad[1])) 
 
    tot_loss = sess.run(LOSS, feed_dict={tfY: Y}) 
    if i%10==0: 
        print(tot_loss) 

此代码打印以下内容:

Tensor("test_18/Const:0", shape=(15, 2), dtype=float32) 
--------------------------------------------------------------------------- 
AttributeError                            Traceback (most recent call last) 
<ipython-input-35-74ddafc0bf3a> in <module>() 
     25     sess.run(B.assign(B - learning_rate * loss_grad[0])) 
     26     print(tfZ) 
---> 27     sess.run(tfZ.assign(tfZ - learning_rate * loss_grad[1])) 
     28  
     29     tot_loss = sess.run(LOSS, feed_dict={tfY: Y}) 
 
AttributeError: 'Tensor' object has no attribute 'assign' 

张量对象正确地没有赋值属性,但我找不到附加到该对象的任何其他函数可以做到这一点。如何正确更新我的张量?

请您参考如下方法:

不同于tf.Variable , tf.Tensor不提供 assign 方法;如果张量是可变的,你必须调用tf.assign显式函数:

tf.assign(tfZ, tfZ - learning_rate * loss_grad[1]) 

更新:并非所有张量都是可变的,例如你的 tfZ 不是。截至目前,可变张量只是那些对应于变量的张量,如 this answer 中所述。 (至少在 tensorflow 1.x 中,这可以在未来扩展)。普通张量是操作结果的句柄,即它们绑定(bind)到该操作及其输入。要更改不可变张量值,必须更改源张量(占位符或变量)。在您的特定情况下,将 tfZ 也设为变量会更容易。

顺便说一下,tf.Variable.assign()只是 tf.assign 的包装器,必须在 session 中运行结果操作才能实际执行分配。

请注意,在这两种情况下,图表中都会创建一个新节点。如果您在循环中调用它(就像在您的代码片段中一样),则该图将膨胀一千个节点。在实际生产代码中这样做是一种不好的做法,因为它很容易导致 OOM。