在 Tensorflow 中训练 while 循环

我尝试将 Python 端的训练循环转换为 Tensorflow,以(假设)使代码运行得更快——不必不断地将控制权交给 cpu。但是,我无法使用tf.while_loop.


这是有效的代码:


import numpy as np

import tensorflow as tf


from tqdm import tqdm

from sklearn.datasets import load_iris

from sklearn.preprocessing import RobustScaler


x, y = load_iris(True)

x = RobustScaler().fit_transform(x)


shape = (10, 10)

max_epochs = 1000



graph = tf.Graph()

sess = tf.Session(graph=graph)


x = x.astype(np.float64)



# Construct graph

with graph.as_default():

    weights = tf.get_variable(

        'weights', shape, initializer=tf.constant_initializer, dtype=tf.float64

    )

    curr_epoch = tf.placeholder(dtype=tf.int64, shape=())


    with tf.name_scope('data'):

        data = tf.data.Dataset.from_tensor_slices(x)

        data = data.shuffle(buffer_size=10000)

        data = data.repeat(max_epochs)

        data = data.batch(1)

        data = data.make_one_shot_iterator().get_next()


    with tf.name_scope('update'):

        update_op = make_update_op(weights)


    init = tf.global_variables_initializer()



sess.run(init)


for i in tqdm(range(max_epochs)):

    for _ in range(x.shape[0]):

        sess.run(update_op, feed_dict={

            curr_epoch: i

        })


np_weights = sess.run(weights)

print(np_weights) # Correctly prints an array of 150's.

现在,如果我创建一个更新函数来传递tf.while_loop,则会引发错误。


def make_update_op(w):

    return w.assign(

        w + 0.001

    )


# In the code above:

update_op = tf.while_loop(lambda _: True, make_update_op, (weights,), maximum_iterations=x.shape[0])


# No inner loop:

for i in tqdm(range(max_epochs)):

    sess.run(update_op, feed_dict={

        curr_epoch: i

    })

第 22 行,在 make_update_op return w.assign( AttributeError: 'Tensor' object has no attribute 'assign'


即使在阅读文档后,我也不太明白发生了什么。毕竟weights是一个Variable。可以做些什么来正确地进行训练循环?


HUWWW
浏览 264回答 2
2回答

智慧大石

事实证明,正如弗拉德所指出的那样,所缺少的只是一个不能在循环内分配变量的事实。相反,可以返回变量的新值。def make_update_op(w):    return w + 0.001new_w = tf.while_loop(lambda _: True, make_update_op, (weights,), maximum_iterations=x.shape[0])update_op = weights.assign(new_w)要使用更多变量,需要从函数返回相同数量并在 Python 中解压缩它们,但原理是相同的。def make_update_op(w, d):    return w + 0.001, dnew_w, _ = tf.while_loop(lambda *_: True, make_update_op, (weights, data), maximum_iterations=x.shape[0])update_op = weights.assign(new_w)

犯罪嫌疑人X

您尝试在 while 循环中分配新值的张量是多个操作张量序列的结果(操作是图中的节点,而张量是有向边)。特别是,while 循环将产生:Variable/Read-->while/Enter-->while/Merge-->while/Switch-->while/Identity您要在这里分配的是一个 tensor while/Identity。tf.while_loop通常用于迭代张量的维度(也在 None- 未知维度上)。您正在尝试迭代完全定义的变量。你不需要为此创建一个tf.while_loop。只需创建更新每个变量的操作并将这些操作组合在一起:update_ops = [w.assign(w + 0.001) for w in weights]update_op = tf.group(update_ops)现在,当您执行update_opwithtf.Session()接口时,它将更新所有变量。例子:import tensorflow as tfv1 = tf.Variable(tf.ones((1, 2), dtype=tf.float32))v2 = tf.Variable(2*tf.ones((1, 3), dtype=tf.float32))update_ops = [w.assign(w + 0.001) for w in [v1, v2]]update_op = tf.group(update_ops)with tf.Session() as sess:&nbsp; &nbsp; sess.run(tf.global_variables_initializer())&nbsp; &nbsp; print('before update:')&nbsp; &nbsp; print(v1.eval(), v2.eval())&nbsp; &nbsp; print('after update:')&nbsp; &nbsp; sess.run(update_op) # <-- update your variables&nbsp; &nbsp; print(v1.eval(), v2.eval())&nbsp; &nbsp; # before update:&nbsp; &nbsp; # [[1. 1.]] [[2. 2. 2.]]&nbsp; &nbsp; # after update:&nbsp; &nbsp; # [[1.001 1.001]] [[2.001 2.001 2.001]]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python