为了账号安全,请及时绑定邮箱和手机立即绑定

在 Tensorflow 中训练 while 循环

在 Tensorflow 中训练 while 循环

HUWWW 2022-01-11 16:46:23
我尝试将 Python 端的训练循环转换为 Tensorflow,以(假设)使代码运行得更快——不必不断地将控制权交给 cpu。但是,我无法使用tf.while_loop.这是有效的代码:import numpy as npimport tensorflow as tffrom tqdm import tqdmfrom sklearn.datasets import load_irisfrom sklearn.preprocessing import RobustScalerx, y = load_iris(True)x = RobustScaler().fit_transform(x)shape = (10, 10)max_epochs = 1000graph = tf.Graph()sess = tf.Session(graph=graph)x = x.astype(np.float64)# Construct graphwith 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。可以做些什么来正确地进行训练循环?
查看完整描述

2 回答

?
智慧大石

TA贡献1946条经验 获得超3个赞

事实证明,正如弗拉德所指出的那样,所缺少的只是一个不能在循环内分配变量的事实。相反,可以返回变量的新值。


def make_update_op(w):

    return w + 0.001


new_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, d


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

update_op = weights.assign(new_w)


查看完整回答
反对 回复 2022-01-11
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

您尝试在 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 tf


v1 = 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:

    sess.run(tf.global_variables_initializer())

    print('before update:')

    print(v1.eval(), v2.eval())

    print('after update:')

    sess.run(update_op) # <-- update your variables

    print(v1.eval(), v2.eval())


    # before update:

    # [[1. 1.]] [[2. 2. 2.]]

    # after update:

    # [[1.001 1.001]] [[2.001 2.001 2.001]]


查看完整回答
反对 回复 2022-01-11
  • 2 回答
  • 0 关注
  • 263 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号