TF1转TF2时Shapes (None,8631)与(8631,)不兼容问题求助
问题描述
将TensorFlow 1.14版本的LaVAN对抗补丁生成代码转换为TensorFlow 2.10.0版本时,通过替换tf为tf.compat.v1实现兼容,但调用categorical_crossentropy()时触发形状不兼容错误。
转换后的关键代码片段:
target = tf.compat.v1.keras.utils.to_categorical(target_idx, 8631) target_variable = tf.compat.v1.keras.backend.variable(target, dtype=tf.float32) source = tf.compat.v1.keras.utils.to_categorical(source_idx, 8631) source_variable = tf.compat.v1.Variable(source, dtype=tf.float32) init_new_vars_op = tf.compat.v1.variables_initializer([target_variable, source_variable]) sess.run(init_new_vars_op) class_variable_t = target_variable loss_func_t = tf.compat.v1.keras.metrics.categorical_crossentropy(model.output.op.inputs[0], class_variable_t) # 触发错误 get_grad_values_t = tf.compat.v1.keras.backend.function([model.input], tf.compat.v1.keras.backend.gradients(loss_func_t, model.input))
触发的错误信息:
File "d:\...\attacks\laVAN.py", line 230, in <module> perturb_one(VGGModel(vggface.ARCHITECTURE_RESNET50), "D:/BA-Python-Code/VGGFace2/n842_0056_01.jpg", 151, 500, save_to_disk=True, image_domain=True) File "d:\...\attacks\laVAN.py", line 196, in perturb_one preprocessed_array = generate_adversarial_examples(vggmodel, img_path, epsilon, src_idx, tar_idx, iterations, image_domain) File "d:\...\attacks\laVAN.py", line 90, in generate_adversarial_examples loss_func_t = tf.compat.v1.keras.metrics.categorical_crossentropy(model.output.op.inputs[0], class_variable_t) File "D:\...\miniconda3\envs\tf-gpu210\lib\site-packages\tensorflow\python\util\traceback_utils.py", line 153, in error_handler raise e.with_traceback(filtered_tb) from None File "D:\...\miniconda3\envs\tf-gpu210\lib\site-packages\keras\losses.py", line 1990, in categorical_crossentropy return backend.categorical_crossentropy( File "D:\...\miniconda3\envs\tf-gpu210\lib\site-packages\keras\backend.py", line 5529, in categorical_crossentropy target.shape.assert_is_compatible_with(output.shape) ValueError: Shapes (None, 8631) and (8631,) are incompatible
原TensorFlow 1.14版本代码(无.compat.v1.修饰)可正常运行,当时对应张量形状为(?, 8631)和(8631,)。运行环境为Windows系统下的GPU版TensorFlow 2.10.0。
修复方案
核心原因是TensorFlow 2.x版本的categorical_crossentropy对输入张量的形状校验比TF1.x更严格,要求目标张量与模型输出张量的维度完全匹配(均需包含批量维度)。以下是两种可行的修复方法:
方法一:初始化变量时添加批量维度
在创建target_variable和source_variable前,通过tf.expand_dims为独热编码后的张量添加批量维度(从(8631,)变为(1, 8631)):target = tf.compat.v1.keras.utils.to_categorical(target_idx, 8631) # 插入批量维度 target = tf.expand_dims(target, axis=0) target_variable = tf.compat.v1.keras.backend.variable(target, dtype=tf.float32) source = tf.compat.v1.keras.utils.to_categorical(source_idx, 8631) # 插入批量维度 source = tf.expand_dims(source, axis=0) source_variable = tf.compat.v1.Variable(source, dtype=tf.float32)方法二:计算损失时扩展目标变量维度
若不想修改变量初始化逻辑,可在调用categorical_crossentropy时,临时为class_variable_t添加批量维度:loss_func_t = tf.compat.v1.keras.metrics.categorical_crossentropy( model.output.op.inputs[0], tf.expand_dims(class_variable_t, axis=0) )验证修复效果
修改后可打印两个张量的形状确认兼容性:print("模型输出形状:", model.output.op.inputs[0].shape) print("目标变量形状:", class_variable_t.shape)确保两者形状均为
(None, 8631)或(1, 8631)(批量维度一致)。
内容的提问来源于stack exchange,提问作者cloudmanager
相关产品推荐
相关产品推荐

