React+TensorFlow.js中LSTM手语识别模型预测报错求助
React + TensorFlow.js LSTM手语翻译预测错误排查
核心错误分析
你遇到的Expected 1 tensor(s), but got 0报错,本质是调用model.predict()时传入的输入张量为空,或者张量构建过程完全失败。结合你的LSTM输入层形状[null,15,1662](即[batch_size, time_steps=15, features=1662]),问题大概率出在关键点序列构建或Ndarray转TensorFlow张量的环节。
逐步排查与修复
1. 验证单帧关键点特征数是否正确
MediaPipe Holistic的关键点总特征数需严格等于1662,先检查提取逻辑:
function extractKeypoints(results) { // 每个关键点取x/y/z三个值,补零处理未检测到的部位 const face = results.faceLandmarks ? nj.array(results.faceLandmarks.flat()) : nj.zeros([468*3]); const leftHand = results.leftHandLandmarks ? nj.array(results.leftHandLandmarks.flat()) : nj.zeros([21*3]); const rightHand = results.rightHandLandmarks ? nj.array(results.rightHandLandmarks.flat()) : nj.zeros([21*3]); const pose = results.poseLandmarks ? nj.array(results.poseLandmarks.flat()) : nj.zeros([33*3]); const combined = nj.concatenate([face, leftHand, rightHand, pose]); console.log('单帧特征数:', combined.shape); // 必须输出 [1662] return combined; }
如果输出不是[1662],说明补零的维度错误(比如把468*3写成468),需修正对应部位的补零长度。
2. 确保序列长度严格为15
LSTM需要固定15帧的序列输入,检查序列收集逻辑:
let sequence = []; function onResults(results) { const keypoints = extractKeypoints(results); sequence.push(keypoints); // 保持序列长度最多15帧 if (sequence.length > 15) sequence.shift(); // 仅当序列满15帧时才预测 if (sequence.length === 15) { console.log('当前序列长度:', sequence.length); // 必须输出 15 // 继续后续张量构建与预测 } }
如果提前调用predict(比如序列长度不足15),会导致输入张量为空。
3. 正确将Ndarray序列转为TensorFlow张量
@d4c/numjs的Ndarray转TF张量时,需注意维度匹配,用nj.stack保留序列的时间维度:
if (sequence.length === 15) { // 将15个[1662]的Ndarray堆叠为[15,1662]的二维数组 const sequenceNdarray = nj.stack(sequence); console.log('序列Ndarray形状:', sequenceNdarray.shape); // 输出 [15,1662] // 转为TF张量,添加batch维度(对应输入层的null),最终形状为[1,15,1662] const inputTensor = tf.tensor(sequenceNdarray.data, [1, 15, 1662], 'float32'); console.log('输入张量形状:', inputTensor.shape); // 必须匹配模型输入层 [1,15,1662] // 执行预测并处理结果 model.predict(inputTensor).then(prediction => { prediction.data().then(predData => { console.log('预测结果:', predData); // 释放张量避免内存泄漏 inputTensor.dispose(); prediction.dispose(); }); }); }
避免直接用nj.concatenate(会把序列展平为一维数组),否则需要额外reshape,增加出错概率。
4. 确认模型输入层匹配
模型加载完成后,验证输入层形状是否符合预期:
model.load().then(() => { console.log('模型输入层形状:', model.inputs[0].shape); // 输出 [null,15,1662] });
如果输出不符,说明模型导出时的输入形状设置错误,需要重新导出正确的LSTM模型。
常见错误总结
- 单帧关键点补零维度错误,导致总特征数不等于1662
- 序列未收集满15帧就调用预测,输入张量为空
- Ndarray转Tensor时未保留时间维度,形状不匹配模型输入层
- 未释放张量导致内存泄漏,间接引发张量处理错误
内容的提问来源于stack exchange,提问作者Bastian Castillo
相关产品推荐
相关产品推荐

