Keras模型拟合触发AssertionError问题技术求助
问题描述
基于Alibi的CEM鸢尾花示例在自有数据集上复现模型时触发AssertionError,环境为TensorFlow 2.8.2、Keras 2.8.0,数据集含59个特征列,目标变量为3分类。
复现代码
import pandas as pd from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from tensorflow.keras.utils import to_categorical from tensorflow.keras.layers import Input, Dense from tensorflow.keras.models import Model df=pd.read_csv('file.csv') df= df.dropna(subset=['column names']) # 需替换为实际列名 X = df.drop(columns=['target'], axis = 1) y = df['target'] num_pipeline = Pipeline([ ('std_scaler', StandardScaler()) ]) X = num_pipeline.fit_transform(X) idx = 1000 x_train,y_train = X[:idx,:], y[:idx] x_test, y_test = X[idx+1:,:], y[idx+1:] y_train = to_categorical(y_train) y_test = to_categorical(y_test) def lr_model(): x_in = Input(shape=(59,)) x_out = Dense(3, activation='softmax')(x_in) lr = Model(inputs=x_in, outputs=x_out) lr.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy']) return lr lr = lr_model() lr.summary() lr.fit(x_train, y_train, batch_size=180, epochs=500, verbose=0)
错误回溯
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_37 (InputLayer) [(None, 59)] 0 dense_36 (Dense) (None, 3) 180 ================================================================= Total params: 180 Trainable params: 180 Non-trainable params: 0 _________________________________________________________________ --------------------------------------------------------------------------- AssertionError Traceback (most recent call last) <ipython-input-123-0216109227fb> in <module> 15 lr = lr_model() 16 lr.summary() ---> 17 lr.fit(x_train, y_train, batch_size=181, epochs=500, verbose=0) 7 frames /usr/local/lib/python3.7/dist-packages/keras/engine/training_v1.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs) 794 max_queue_size=max_queue_size, 795 workers=workers, ---> 796 use_multiprocessing=use_multiprocessing) 797 798 def evaluate(self, /usr/local/lib/python3.7/dist-packages/keras/engine/training_generator_v1.py in fit(self, model, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, **kwargs) 775 shuffle=shuffle, 776 initial_epoch=initial_epoch, ---> 777 steps_name='steps_per_epoch') 778 779 def evaluate(self, /usr/local/lib/python3.7/dist-packages/keras/engine/training_generator_v1.py in model_iteration(model, data, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, validation_freq, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch, mode, batch_size, steps_name, **kwargs) 250 251 is_deferred = not model._is_compiled ---> 252 batch_outs = batch_function(*batch_data) 253 if not isinstance(batch_outs, list): 254 batch_outs = [batch_outs] /usr/local/lib/python3.7/dist-packages/keras/engine/training_v1.py in train_on_batch(self, x, y, sample_weight, class_weight, reset_metrics) 1061 y, 1062 sample_weights=sample_weights, -> 1063 output_loss_metrics=self._output_loss_metrics) 1064 outputs = (output_dict['total_loss'] + output_dict['output_losses'] 1065 + output_dict['metrics']) /usr/local/lib/python3.7/dist-packages/keras/engine/training_eager_v1.py in train_on_batch(model, inputs, targets, sample_weights, output_loss_metrics) 310 sample_weights=sample_weights, 311 training=True, -> 312 output_loss_metrics=output_loss_metrics)) 313 if not isinstance(outs, list): 314 outs = [outs] /usr/local/lib/python3.7/dist-packages/keras/engine/training_eager_v1.py in _process_single_batch(model, inputs, targets, output_loss_metrics, sample_weights, training) 245 ValueError: If the model has no loss to optimize. 246 """ -> 247 with backend.eager_learning_phase_scope(1 if training else 0), \ 248 training_utils.RespectCompiledTrainableState(model): 249 with GradientTape() as tape: /usr/lib/python3.7/contextlib.py in __enter__(self) 110 del self.args, self.kwds, self.func 111 try: -> 112 return next(self.gen) 113 except StopIteration: 114 raise RuntimeError("generator didn't yield") from None /usr/local/lib/python3.7/dist-packages/keras/backend.py in eager_learning_phase_scope(value) 590 global _GRAPH_LEARNING_PHASES # pylint: disable=global-variable-not-assigned 591 assert value in {0, 1} -> 592 assert tf.compat.v1.executing_eagerly_outside_functions() 593 global_learning_phase_was_set = global_learning_phase_is_set() 594 if global_learning_phase_was_set:
解决方案
该错误源于Keras后端的eager_learning_phase_scope函数断言失败,说明当前执行环境未处于Eager模式,或存在Graph与Eager模式的冲突,可尝试以下解决方法:
强制启用Eager模式:在代码开头添加语句,确保TensorFlow以Eager模式运行:
import tensorflow as tf tf.compat.v1.enable_eager_execution()改用TensorFlow原生训练循环:替代Keras的
fit方法,避免旧版训练逻辑的兼容性问题:import tensorflow as tf # 定义损失函数、优化器和指标 loss_fn = tf.keras.losses.CategoricalCrossentropy() optimizer = tf.keras.optimizers.RMSprop() train_acc_metric = tf.keras.metrics.CategoricalAccuracy() # 构建训练数据集 epochs = 500 batch_size = 180 train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)).shuffle(1024).batch(batch_size) # 自定义训练循环 for epoch in range(epochs): train_acc_metric.reset_states() for x_batch, y_batch in train_dataset: with tf.GradientTape() as tape: logits = lr(x_batch, training=True) loss_value = loss_fn(y_batch, logits) # 计算梯度并更新权重 grads = tape.gradient(loss_value, lr.trainable_weights) optimizer.apply_gradients(zip(grads, lr.trainable_weights)) # 更新精度指标 train_acc_metric.update_state(y_batch, logits) # 定期打印训练进度 if epoch % 50 == 0: print(f"Epoch {epoch}, 训练精度: {train_acc_metric.result():.4f}")修复依赖版本冲突:若在托管环境中运行,可能存在隐藏版本问题,重新安装匹配依赖:
pip install tensorflow==2.8.2 keras==2.8.0 --force-reinstall统一API使用:全程使用
tf.keras下的API,避免混合导入独立Keras库,确保代码风格一致。
内容的提问来源于stack exchange,提问作者prof31
相关产品推荐
相关产品推荐

