MoveNet姿态估计模型推理时出现维度不匹配错误求解决方案
问题:姿态分类模型推理时维度不匹配错误
我用TensorFlow官方姿态分类Notebook训练并通过model.save('model.keras')保存了MoveNet姿态估计模型,编写推理代码加载模型、预处理图像后执行预测时出现维度不匹配错误。
推理代码:
import numpy as np import tensorflow as tf import matplotlib.pyplot as plt # Load the model filepath = "C:\\Users\\golut\\OneDrive\\Documents\\PoseEstimation\\model.keras" new_model = tf.keras.models.load_model(filepath) # Read and preprocess the image image_path = "C:\\Users\\golut\\OneDrive\\Documents\\PoseEstimation\\test_pos.jpg" image = tf.io.read_file(image_path) image = tf.image.decode_image(image, channels=3) image = tf.image.convert_image_dtype(image, tf.float32) image = tf.image.resize(image, (256, 256)) # Resize if necessary image = np.expand_dims(image, axis=0) # Add batch dimension # Perform inference predictions = new_model.predict(image) # Process predictions as needed # For example, print the predictions print(predictions) # Optionally, visualize the image and predictions plt.imshow(image[0]) # Assuming only one image in the batch plt.show()
错误提示:
Traceback (most recent call last): File "c:\Users\golut\OneDrive\Documents\PoseEstimation\app.py", line 18, in <module> predictions = new_model.predict(image) File "C:\ProgramData\anaconda3\envs\pose_est\lib\site-packages\keras\src\utils\traceback_utils.py", line 70, in error_handler raise e.with_traceback(filtered_tb) from None File "C:\Users\golut\AppData\Local\Temp\__autograph_generated_filepea7q91y.py", line 15, in tf__predict_function retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope) ValueError: in user code: File "C:\ProgramData\anaconda3\envs\pose_est\lib\site-packages\keras\src\engine\training.py", line 2440, in predict_function * return step_function(self, iterator) File "C:\ProgramData\anaconda3\envs\pose_est\lib\site-packages\keras\src\engine\training.py", line 2425, in step_function ** outputs = model.distribute_strategy.run(run_step, args=(data,)) File "C:\ProgramData\anaconda3\envs\pose_est\lib\site-packages\keras\src\engine\training.py", line 2413, in run_step ** outputs = model.predict_step(data) File "C:\ProgramData\anaconda3\envs\pose_est\lib\site-packages\keras\src\engine\training.py", line 2381, in predict_step return self(x, training=False) File "C:\ProgramData\anaconda3\envs\pose_est\lib\site-packages\keras\src\utils\traceback_utils.py", line 70, in error_handler raise e.with_traceback(filtered_tb) from None File "C:\ProgramData\anaconda3\envs\pose_est\lib\site-packages\keras\src\engine\input_spec.py", line 298, in assert_input_compatibility raise ValueError( ValueError: Input 0 of layer "model" is incompatible with the layer: expected shape=(None, 51), found shape=(None, 256, 256, 3)
问题根源
你保存的不是MoveNet姿态估计模型,而是Notebook里最后训练的姿态分类模型。这个分类模型的输入不是原始图像,而是MoveNet输出的17个关键点的坐标+置信度(每个关键点包含x/y/置信度三个值,17×3=51维),所以模型期望输入形状是(None,51),但你传入的是(None,256,256,3)的图像,直接导致维度不匹配。
解决办法
情况1:你需要的是姿态分类(判断动作类别,比如坐下/站立)
你需要先通过MoveNet模型提取图像的姿态关键点,再把关键点数据输入到你保存的分类模型中做预测:
import numpy as np import tensorflow as tf import matplotlib.pyplot as plt # 加载你的姿态分类模型 classifier_model = tf.keras.models.load_model("C:\\Users\\golut\\OneDrive\\Documents\\PoseEstimation\\model.keras") # 加载预训练的MoveNet姿态估计模型(以Lightning版本为例) movenet = tf.keras.models.load_model("movenet_singlepose_lightning") def preprocess_image(image_path, input_size=192): # MoveNet Lightning版本要求输入尺寸为192×192 image = tf.io.read_file(image_path) image = tf.image.decode_jpeg(image, channels=3) image = tf.image.resize_with_pad(image, input_size, input_size) image = tf.cast(image, dtype=tf.int32) return tf.expand_dims(image, axis=0) def extract_keypoints(movenet_model, image): outputs = movenet_model.predict(image) # 提取关键点坐标和置信度,展平为51维向量 keypoints = outputs['output_0'].numpy().flatten()[:51] return np.expand_dims(keypoints, axis=0) # 处理测试图像 image_path = "C:\\Users\\golut\\OneDrive\\Documents\\PoseEstimation\\test_pos.jpg" input_image = preprocess_image(image_path) keypoints = extract_keypoints(movenet, input_image) # 用分类模型执行预测 predictions = classifier_model.predict(keypoints) print("分类预测结果:", predictions) # 可视化图像 plt.imshow(tf.squeeze(input_image).numpy().astype(np.uint8)) plt.show()
情况2:你需要的是姿态估计(提取人体关键点)
如果你想保存的是MoveNet姿态估计模型,说明你在Notebook里保存错了对象。回到训练Notebook,找到加载MoveNet的代码,直接保存该模型即可,示例代码:
# 加载MoveNet后保存模型 movenet = tf.keras.models.load_model("movenet_singlepose_lightning") movenet.save("movenet_model.keras")
后续推理时,直接传入符合MoveNet输入尺寸(比如192×192)的预处理图像即可。
内容的提问来源于stack exchange,提问作者Maaz Shahid
相关产品推荐
相关产品推荐

