Tensorflow调用model.fit时Keras符号值无法转numpy数组如何解决?
核心报错原因
该错误本质是自定义层/损失函数中存在张量与Numpy操作混用的情况,新的fit方法默认走图编译逻辑,不允许符号张量在静态图阶段转换为Numpy数组,而已废弃的fit_generator对动态操作兼容性更高,所以不会触发报错。
排查与解决步骤
第一步:修正自定义变分损失/层的运算逻辑
所有损失计算、层内运算必须使用TensorFlow/Keras后端算子,禁止使用任何Numpy运算操作。例如错误写法loss = np.mean(K.binary_crossentropy(y_true, y_pred))要改为loss = tf.reduce_mean(tf.keras.losses.binary_crossentropy(y_true, y_pred)),不允许在call方法、损失函数中调用np.array()、.numpy()等转换操作。第二步:统一数据集格式
你已经通过pad_sequences得到了固定长度序列,直接将训练、验证数据显式转换为float32类型的Numpy数组即可:import numpy as np training_data = np.asarray(training_data, dtype="float32") data_1_val = np.asarray(data_1_val, dtype="float32")训练时直接传入数组即可:
model.fit(x=training_data, y=training_data, validation_data=(data_1_val, data_1_val), epochs=10, batch_size=32)如果偏好生成器方案,优先使用
tf.data.Dataset构造数据集,兼容性远高于自定义Python生成器:import tensorflow as tf BATCH_SIZE = 32 # 构造训练集 train_ds = tf.data.Dataset.from_tensor_slices((training_data, training_data)) train_ds = train_ds.shuffle(10000).batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE) # 构造验证集 val_ds = tf.data.Dataset.from_tensor_slices((data_1_val, data_1_val)) val_ds = val_ds.batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE) # 训练 model.fit(train_ds, validation_data=val_ds, epochs=10)第三步:验证嵌入层初始化逻辑
预训练Glove权重传入嵌入层时需要套入列表、转换为float32格式,示例如下:from tensorflow.keras.layers import Embedding embedding_layer = Embedding( input_dim=词汇表大小, output_dim=Glove向量维度, weights=[np.asarray(glove_embedding_matrix, dtype="float32")], input_length=序列固定长度, trainable=False )第四步:临时开启Eager执行排查问题
如果以上修改后仍然报错,可以在模型编译前添加一行配置强制开启Eager执行,跳过静态图编译检查:tf.config.run_functions_eagerly(True)如果开启后可以正常训练,说明自定义层/损失中仍然存在未修正的Numpy操作,逐行排查自定义代码即可。
内容的提问来源于stack exchange,提问作者kiriloff

