TensorFlow启动队列运行器后Eval仍无限挂起问题求助
TensorFlow Session挂起在
eval()调用时 我最近在运行TensorFlow代码时碰到了一个棘手的问题——当执行下面这段代码时,程序直接挂起,没有任何输出也不报错:
print('Beginning Eval...') feed_dict_train = { img_data: images_batch.eval(session=session), img_labels: labels_batch.eval(session=session) }
我试过单独对单个样本和批量样本执行eval()操作,但都出现了同样的挂起情况。下面是我的相关代码细节,麻烦帮忙排查一下:
单个样本读取函数
def read_single_example(filename): # Mini-init image_size = 256 filenames = tf.train.string_input_producer([filename], num_epochs = None) reader = tf.TFRecordReader() _, serialized_example = reader.read(filenames) features = tf.parse_single_example( serialized_example, features={ 'label':tf.FixedLenFeature([], tf.float32), 'image':tf.FixedLenFeature([image_size*image_size*3], tf.float32) }) label = features['label'] # label = tf.get_default_session().run(label) image_data = features['image'] # image_data = tf.get_default_session().run(image_data) image = tf.reshape(image_data,(256,256,3)) return label, image
读取单个样本
label_train, image_train = read_single_example(path)
训练循环内的批量处理
print('Getting Batch') images_batch, labels_batch = tf.train.shuffle_batch( [image_train, label_train], batch_size=batch_size, capacity=2000, min_after_dequeue=1000)
TensorFlow会话初始化
session = tf.Session() init = tf.global_variables_initializer() session.run(init) tf.train.start_queue_runners(sess=session)
补充说明:磁盘上的TFRecord文件是用一段生成代码创建的,内容是一批256x256x3的图像和1x41的标签张量,我暂时认为问题不在数据文件本身。完整的网络代码我也有整理好,不过先贴出和数据读取相关的核心部分。
排查思路和建议
结合你的代码情况,我觉得可以从这几个方向入手排查:
- 确保队列线程正确启动
虽然你调用了tf.train.start_queue_runners(sess=session),但有时候在复杂环境下,队列线程可能没有完全启动。建议用Coordinator来管理线程,这样能更稳妥地控制队列的生命周期:
session = tf.Session() init = tf.global_variables_initializer() session.run(init) # 新增Coordinator管理线程 coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(sess=session, coord=coord) # 你的训练逻辑代码... # 训练结束后记得停止线程 coord.request_stop() coord.join(threads) session.close()
- 合并
eval()调用为一次run()
你现在分别对images_batch和labels_batch调用eval(),这会触发两次独立的队列读取操作,不仅效率低,还可能导致死锁。改成一次run()获取两个张量会更安全:
print('Beginning Eval...') images_eval, labels_eval = session.run([images_batch, labels_batch]) feed_dict_train = {img_data: images_eval, img_labels: labels_eval}
检查队列参数是否合理
tf.train.shuffle_batch的min_after_dequeue参数要求队列里至少保留这么多样本才能打乱。如果你的TFRecord文件里的总样本数少于min_after_dequeue(比如只有几百个),队列永远凑不齐足够的样本,就会一直挂起等待。可以先把min_after_dequeue调小到100左右,测试是否能正常运行。验证TFRecord文件的有效性
虽然你觉得数据没问题,但还是建议用小脚本读取几个样本确认一下,避免数据损坏或者格式不匹配:
import tensorflow as tf def check_tfrecord(filename): image_size = 256 filenames = tf.train.string_input_producer([filename], num_epochs=1) reader = tf.TFRecordReader() _, serialized_example = reader.read(filenames) features = tf.parse_single_example( serialized_example, features={ 'label':tf.FixedLenFeature([], tf.float32), 'image':tf.FixedLenFeature([image_size*image_size*3], tf.float32) }) label = features['label'] image = tf.reshape(features['image'], (256,256,3)) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) sess.run(tf.local_variables_initializer()) # num_epochs依赖局部变量,必须初始化 coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(coord=coord) try: for _ in range(5): l, img = sess.run([label, image]) print(f"Label shape: {l.shape}, Image shape: {img.shape}") except tf.errors.OutOfRangeError: print("已读取完所有样本") finally: coord.request_stop() coord.join(threads) # 替换成你的TFRecord路径 check_tfrecord("your_tfrecord_file.tfrecord")
- 不要遗漏局部变量初始化
如果你的代码里用到了num_epochs这类依赖局部变量的组件,只初始化全局变量是不够的,需要加上session.run(tf.local_variables_initializer()),否则队列可能无法正常工作。
内容的提问来源于stack exchange,提问作者Xander May
相关产品推荐
相关产品推荐

