TensorFlow 1.15中tf.while_loop内使用sess.run()与L-BFGS-B的报错解决
问题原因分析
你遇到的InaccessibleTensorError本质是计算图内循环与外部优化工具的上下文冲突:
tf.while_loop是TensorFlow计算图层面的循环构造,内部节点会被标记为不可直接获取;而ScipyOptimizerInterface是依赖Session.run()执行的外部优化工具,在图内循环的body函数里嵌套Session会彻底打乱张量的上下文关联,导致无法访问循环内部的节点。- 代码里还有变量管理的硬伤:
body函数内重复调用tf.get_variable获取同名变量,嵌套的Session还会重新初始化全局变量,完全破坏了外部计算图的状态。
解决方案:改用Python循环替代tf.while_loop
既然ScipyOptimizerInterface是基于Python会话的优化工具,直接用Python原生while循环替代图内循环是最稳妥的方案,彻底规避上下文冲突:
修改后的代码:
import tensorflow as tf import tensorflow_probability as tfp import numpy as np L = 2 E = tf.constant([[4.17022005e-01, 7.20324493e-01],[1.14374817e-04, 3.02332573e-01]], dtype=tf.float32) loss_type = 'l2' lambda1=0.0 rho = tf.constant(1.0, dtype=tf.float32) h = tf.constant(np.inf, tf.float32) w_new = tf.zeros(([2 * L * L]), dtype=tf.float32) h_new = tf.constant(0, dtype=tf.float32) alpha = tf.constant(0, dtype=tf.float32) # 初始化变量 w_est = tf.Variable(tf.random.uniform([2*L*L], dtype=tf.float32, name="fuck")) def _func(w): # 补全你的损失函数和约束定义,原代码里没实现 loss = tf.reduce_sum(tf.square(w - E)) + lambda1 * tf.norm(w, 1) return loss, [] # 统一管理Session,不要嵌套 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) itera = 0 while itera < 10: # 初始化优化器 optimizer = tf.contrib.opt.ScipyOptimizerInterface( _func(w_est)[0], constraints=_func(w_est)[1], options={'maxiter': 100}) # 执行优化 optimizer.minimize(sess) # 更新变量值 w_new_val = sess.run(w_est) # 将更新后的值赋值给w_est(可选,若需要迭代传递优化结果) sess.run(w_est.assign(w_new_val)) itera += 1 # 输出最终结果 print(sess.run(w_new_val))
改动说明:
- 去掉
tf.while_loop,改用Python原生while循环,把优化操作放在会话上下文内执行 - 统一维护一个
Session,避免嵌套会话导致的状态混乱 - 补全了原代码缺失的
_func函数(你需要替换成自己的实际损失和约束逻辑)
替代方案:用TensorFlow Probability的图内L-BFGS优化器
如果必须在tf.while_loop内实现L-BFGS-B优化,可以用tfp.optimizer.lbfgs_minimize——这是计算图层面的优化器,不需要依赖外部Session.run()调用,完美适配图内循环:
示例代码:
import tensorflow as tf import tensorflow_probability as tfp import numpy as np L = 2 E = tf.constant([[4.17022005e-01, 7.20324493e-01],[1.14374817e-04, 3.02332573e-01]], dtype=tf.float32) loss_type = 'l2' lambda1=0.0 rho = tf.constant(1.0, dtype=tf.float32) def _func(w): # 定义损失函数和梯度计算 loss = tf.reduce_sum(tf.square(w - E)) + lambda1 * tf.norm(w, 1) grads = tf.gradients(loss, w)[0] return loss, grads # 初始化优化变量 w_est = tf.Variable(tf.random.uniform([2*L*L], dtype=tf.float32)) itera = tf.Variable(0, dtype=tf.int32) def body(w_est, itera): # 用tfp的L-BFGS优化器执行一次优化 def loss_and_grad(w): return _func(w) # 执行优化,获取更新后的变量值 result = tfp.optimizer.lbfgs_minimize( loss_and_grad, initial_position=w_est, num_iterations=100, f_relative_tolerance=1e-6 ) # 更新变量和迭代次数 w_est_updated = result.position itera_updated = itera + 1 return w_est_updated, itera_updated def cond(w_est, itera): return itera < 10 # 图内循环执行优化 final_w, final_itera = tf.while_loop(cond, body, [w_est, itera]) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) print("最终优化结果:", sess.run(final_w)) print("迭代次数:", sess.run(final_itera))
说明:
tfp.optimizer.lbfgs_minimize直接在计算图内完成优化,返回更新后的变量位置,完全适配tf.while_loop的图内操作逻辑- 需要定义损失函数和对应的梯度(也可以用自动微分),优化参数可以根据需求调整
内容的提问来源于stack exchange,提问作者xavi
相关产品推荐
相关产品推荐

