TFJS调用Keras转换模型时model.predict()返回undefined如何解决
错误原因
你代码中的问题集中在异步逻辑、模型调用方式、参数格式三个方面,具体如下:
- 模型加载是异步操作,
tf.loadLayersModel返回Promise对象,你同步调用loadModel()拿到的不是可用模型实例,自然不存在predict方法 - 用
const声明的prediction、model变量不可二次赋值,会触发语法错误打断逻辑执行 - 你写的
model().predict是把模型实例当成函数调用,正确用法是直接调用实例方法model.predict,不需要加括号 - 定义的async异步预测函数没有被实际调用,预测逻辑根本不会运行
predict方法要求传入匹配输入形状的tensor对象,不能直接传原生数组,你的模型输入要求形状为[batch, 34],需要对应构造2维tensor- 在同步代码中打印异步逻辑才会赋值的
prediction,此时异步逻辑还未执行,输出自然是undefined
修复方案
建议先预加载模型到全局变量,避免每次预测重复加载浪费性能,修正后代码如下:
1. 模型预加载逻辑
// 全局存储已加载的模型实例 let trainedModel = null; // 异步加载模型 const loadTrainedModel = async () => { try { // 替换成你实际的model.json存放路径 trainedModel = await tf.loadLayersModel('./model.json'); // 验证模型加载成功 trainedModel.summary(); } catch (err) { console.error('模型加载失败: ', err); } }; // 页面初始化时调用加载模型 loadTrainedModel();
2. 修正后的预测函数
const predictPose = async (arr) => { // 校验模型加载状态 if (!trainedModel) { console.warn('模型加载中,请稍后重试'); return; } // 校验输入长度 if (arr.length !== 34) { console.error('输入数组长度必须为34位'); return; } // 构造符合模型要求的输入tensor,形状[1, 34],类型匹配模型输入的float32 const inputTensor = tf.tensor2d([arr], [1, 34], 'float32'); try { // 执行预测 const predictionTensor = trainedModel.predict(inputTensor); // 读取预测结果,你的模型输出是1000类的softmax结果,返回长度为1000的数组 const predictionResult = predictionTensor.dataSync(); // 可选:取置信度最高的类别索引 const predictedClass = predictionResult.indexOf(Math.max(...predictionResult)); console.log('预测置信度数组:', predictionResult); console.log('预测类别:', predictedClass); // 释放tensor内存,避免内存泄漏 inputTensor.dispose(); predictionTensor.dispose(); return { predictionResult, predictedClass }; } catch (err) { console.error('预测出错:', err); inputTensor.dispose(); } };
3. 调用示例
预测函数是异步方法,调用时需要用await或者.then接收结果:
// 你的34位输入数组 const testInput = [/* 34个数值元素 */]; // 调用方式1:await (需要放在async函数内) const res = await predictPose(testInput); // 调用方式2:.then predictPose(testInput).then(res => { if (res) { // 处理预测结果 } });
内容的提问来源于stack exchange,提问作者sna0e
相关产品推荐
相关产品推荐

