使用预训练Xception生成图像块时tf.shape层触发TypeError错误
解决tf.shape调用时的TypeError错误
在基于预训练Xception模型提取图像块的代码中,调用tf.shape触发了TypeError,核心原因是对tf.shape的参数用法存在误解。
错误代码示例
# Load the pre-trained Xception model to be used as the base encoder. xception = keras.applications.Xception( include_top=False, weights="imagenet", pooling="avg" ) for layer in xception.layers: layer.trainable = trainable inputs = layers.Input(shape=(299, 299, 3), name="image_input") # Preprocess the input image. patches = tf.image.extract_patches(images=inputs, sizes=[1, 32, 32, 1], strides=[1, 32, 32, 1], rates=[1, 1, 1, 1], padding='VALID') patches = tf.shape(patches, (None, 73, 73, 1)) xception_input = tf.keras.applications.xception.preprocess_input(patches) embeddings = xception(xception_input) return keras.Model(inputs, embeddings, name="vision_encoder")
错误信息
TypeError: Exception encountered when calling layer "tf.shape" (type TFOpLambda). Expected DataType for argument 'out_type' not (None, 73, 73, 1). Call arguments received: • input=tf.Tensor(shape=(None, 9, 9, 3072), dtype=float32) • out_type=('None', '73', '73', '1') • name=None
错误原因
tf.shape的第二个参数out_type用于指定输出形状张量的数据类型(如tf.int32、tf.int64),而非设置张量的目标形状。代码中错误传入形状元组,导致参数类型不匹配,触发TypeError。
如果需要调整张量形状,应该使用tf.reshape而非tf.shape。另外需要注意:当前tf.image.extract_patches输出的张量形状为(None, 9, 9, 3072),元素总数为9×9×3072=2519424;而你指定的目标形状(None,73,73,1)元素总数为73×73×1=5329,两者不相等,直接reshape会报错,需要先确认目标形状的合理性。
修正后的代码示例
假设需求是对每个提取的图像块单独用Xception提取特征,正确的代码如下:
# Load the pre-trained Xception model to be used as the base encoder. xception = keras.applications.Xception( include_top=False, weights="imagenet", pooling="avg" ) for layer in xception.layers: layer.trainable = trainable inputs = layers.Input(shape=(299, 299, 3), name="image_input") # 提取图像块 patches = tf.image.extract_patches( images=inputs, sizes=[1, 32, 32, 1], strides=[1, 32, 32, 1], rates=[1, 1, 1, 1], padding='VALID' ) # 将patches reshape为 (batch_size, 总块数, 块高度, 块宽度, 通道数) patches = tf.reshape(patches, (-1, 9*9, 32, 32, 3)) # 对每个图像块单独进行预处理和特征提取 def process_single_patch(patch): patch_preprocessed = tf.keras.applications.xception.preprocess_input(patch) return xception(tf.expand_dims(patch_preprocessed, axis=0)) embeddings = tf.map_fn(process_single_patch, patches, fn_output_signature=tf.float32) # 调整输出形状为 (batch_size, 总块数, 特征维度) embeddings = tf.reshape(embeddings, (-1, 9*9, xception.output_shape[-1])) return keras.Model(inputs, embeddings, name="vision_encoder")
如果确实需要将张量调整为(None,73,73,1),请先调整图像块提取参数(如sizes、strides)或修改目标形状,确保元素总数一致后,使用tf.reshape(patches, (-1,73,73,1))完成形状调整。
内容的提问来源于stack exchange,提问作者user19686684
相关产品推荐
相关产品推荐

