使用Brain.js开发英文理解AI遇NaN输出问题求助
问题分析与修复方案
核心问题
返回全NaN的Float32Array有两个关键诱因:
- 输入输出维度不匹配:Brain.js的前馈神经网络要求训练样本的输入、输出数组长度必须一致。你训练时用长度为5的
hello数组对应长度为2的hi数组,网络无法构建合理映射关系,最终导致预测异常。 - 未做数据归一化:Brain.js的神经网络默认期望输入输出是0到1之间的数值,你直接使用0-25的字母索引值,超出模型预期范围,引发计算错误。
修复后的代码
const network = new brain.NeuralNetwork(); const letters = Array.from({ length: 26 }, (_, i) => String.fromCharCode(97 + i)); const MAX_LENGTH = 5; // 设定统一的输入输出最大长度,可按需调整 const AI = { // 将字符串转为归一化的数字数组,统一长度为MAX_LENGTH strToNormalizedNum: (string) => { const strArr = string.toLowerCase().split(''); const numArr = strArr.map(char => { const index = letters.indexOf(char); return index === -1 ? 0 : index / 25; // 归一化到0-1区间,未知字符设为0 }); // 补全或截断到固定长度 while (numArr.length < MAX_LENGTH) { numArr.push(0); } return numArr.slice(0, MAX_LENGTH); }, // 将归一化的数组转回字符串 normalizedNumToStr: (numArr) => { return numArr.map(num => { const index = Math.round(num * 25); // 反归一化到0-25索引 return index >= 0 && index < 26 ? letters[index] : ''; }).join('').trim(); }, ask: (txt) => { const normalizedInput = AI.strToNormalizedNum(txt); const result = network.run(normalizedInput); return AI.normalizedNumToStr(result); }, train: (samples) => { network.train(samples); } }; // 准备训练样本,确保输入输出长度一致 const trainingSamples = [ { input: AI.strToNormalizedNum('hello'), output: AI.strToNormalizedNum('hi ') // 补空格到固定长度,匹配输入维度 }, { input: AI.strToNormalizedNum('hi'), output: AI.strToNormalizedNum('hello') } ]; network.train(trainingSamples); // 测试示例 console.log(AI.ask('hello')); // 应返回近似'hi'的结果 console.log(AI.ask('hi')); // 应返回近似'hello'的结果
关键调整说明
- 统一维度:设定
MAX_LENGTH固定输入输出的数组长度,不足部分补0,确保训练和预测时维度一致。 - 数据归一化:将字母索引(0-25)除以25转换为0-1之间的数值,符合Brain.js的输入要求;解码时再乘以25取整转回索引。
- 鲁棒性优化:处理未知字符时默认设为0,避免因字符不在字母表中导致的异常。
内容的提问来源于stack exchange,提问作者VirusterDev
相关产品推荐
相关产品推荐

