Graph执行报错:无法将符号tf.Tensor作为Python bool使用,求解决
修复TensorFlow中OperatorNotAllowedInGraphError错误
问题重现
模型代码
learning_rate = 0.1 momentum = 0.9 lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay( initial_learning_rate=learning_rate, decay_steps=EPOCH_SIZE, decay_rate=0.1 ) optimizer = tf.keras.optimizers.SGD(learning_rate=lr_schedule, momentum=momentum, nesterov=True) input_correct_responses = tf.keras.Input(shape=(26,), name='input_correct_responses') pe = tf.keras.losses.categorical_crossentropy(input_correct_responses, z) ce = tf.keras.metrics.CategoricalAccuracy()(input_correct_responses, z) model = Model(inputs=[input_obscured_word_seen, input_letters_guessed_previously, input_correct_responses], outputs=z) model.compile(optimizer=optimizer, loss=pe, metrics=[ce]) progress_printer = tf.keras.callbacks.LambdaCallback( on_epoch_end=lambda epoch, logs: print(f"Training - epoch: {epoch + 1}, loss: {logs['loss']}, accuracy: {logs['categorical_accuracy']}"), on_train_end=lambda logs: print("Training completed.") )
错误信息
--------------------------------------------------------------------------- OperatorNotAllowedInGraphError Traceback (most recent call last) Cell In[83], line 17 14 ce = tf.keras.metrics.CategoricalAccuracy()(input_correct_responses, z) 16 model = Model(inputs=[input_obscured_word_seen, input_letters_guessed_previously, input_correct_responses], outputs=z) ---> 17 model.compile(optimizer=optimizer, loss=pe, metrics=[ce]) 19 progress_printer = tf.keras.callbacks.LambdaCallback( 20 on_epoch_end=lambda epoch, logs: print(f"Training - epoch: {epoch + 1}, loss: {logs['loss']}, accuracy: {logs['categorical_accuracy']}"), 21 on_train_end=lambda logs: print("Training completed.") 22 ) File ~/anaconda3/lib/python3.10/site-packages/tensorflow/python/trackable/base.py:205, in no_automatic_dependency_tracking.._method_wrapper(self, *args, **kwargs) 203 self._self_setattr_tracking = False # pylint: disable=protected-access 204 try: --> 205 result = method(self, *args, **kwargs) 206 finally: 207 self._self_setattr_tracking = previous_value # pylint: disable=protected-access File ~/anaconda3/lib/python3.10/site-packages/keras/engine/training_v1.py:406, in Model.compile(self, optimizer, loss, metrics, loss_weights, sample_weight_mode, weighted_metrics, target_tensors, distribute, **kwargs) 402 if isinstance(self.optimizer, tf.__internal__.tracking.Trackable): 403 self._track_trackable( 404 self.optimizer, name="optimizer", overwrite=True 405 ) --> 406 self.loss = loss or {} 407 self.loss_weights = loss_weights ... --> 544 raise errors.OperatorNotAllowedInGraphError( 545 f"{task} is not allowed in Graph execution. Use Eager execution or" 546 " decorate this function with @tf.function.") OperatorNotAllowedInGraphError: Using a symbolic `tf.Tensor` as a Python `bool` is not allowed in Graph execution. Use Eager execution or decorate this function with @tf.function.
问题根源
你提前调用了tf.keras.losses.categorical_crossentropy和tf.keras.metrics.CategoricalAccuracy()(),得到的是符号张量,但model.compile的loss和metrics参数需要的是损失/指标的可调用对象或名称,而非已经计算好的张量。当代码执行loss=pe时,TensorFlow在图模式下尝试将该张量当作Python布尔值处理(如loss or {}逻辑),直接触发了错误。
修复方案
修改model.compile的参数传递方式,直接传入损失函数和指标的实例或名称字符串,而非提前计算的张量:
修改后的完整代码
learning_rate = 0.1 momentum = 0.9 lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay( initial_learning_rate=learning_rate, decay_steps=EPOCH_SIZE, decay_rate=0.1 ) optimizer = tf.keras.optimizers.SGD(learning_rate=lr_schedule, momentum=momentum, nesterov=True) input_correct_responses = tf.keras.Input(shape=(26,), name='input_correct_responses') # 移除提前计算的损失和指标张量 # pe = tf.keras.losses.categorical_crossentropy(input_correct_responses, z) # ce = tf.keras.metrics.CategoricalAccuracy()(input_correct_responses, z) model = tf.keras.Model(inputs=[input_obscured_word_seen, input_letters_guessed_previously, input_correct_responses], outputs=z) # 直接传递损失函数实例和指标实例 model.compile( optimizer=optimizer, loss=tf.keras.losses.CategoricalCrossentropy(), # 也可以用字符串'categorical_crossentropy' metrics=[tf.keras.metrics.CategoricalAccuracy()] # 也可以用字符串'categorical_accuracy' ) progress_printer = tf.keras.callbacks.LambdaCallback( on_epoch_end=lambda epoch, logs: print(f"Training - epoch: {epoch + 1}, loss: {logs['loss']}, accuracy: {logs['categorical_accuracy']}"), on_train_end=lambda logs: print("Training completed.") )
关键说明
loss参数:接受内置损失名称字符串、损失函数类实例,或自定义可调用函数,TensorFlow会在训练过程中自动计算每一步的损失值。metrics参数:同理,需要传入指标类实例或内置指标名称字符串,框架会自动处理指标的更新和结果统计。
内容的提问来源于stack exchange,提问作者Anwesh saha
相关产品推荐
相关产品推荐

