必须用 HTTP 服务(如 npx http-server 或 Live Server)运行 HTML,因 file:// 协议触发跨域拦截致 NotFoundError;模型须转为 tf.js 格式(model.json+shard 文件),loadLayersModel()只认 model.json;需 await model.ready()再 predict;输入 tensor 须严格匹配 shape 与 dtype。

HTML 里直接加载 tf.js 模型会报NotFoundError: Request failed
这是因为浏览器不允许跨域读取本地 .json 或.bin文件——你双击打开 HTML,地址是 file:// 协议,而 TensorFlow.js 默认用 fetch() 拉模型,现代浏览器直接拦截。
必须用 HTTP 服务起页面。最简单方法:
– 项目根目录下运行 npx http-server(需先npm install -g http-server)
– 或用 VS Code 插件“Live Server”右键启动
– 别用open index.html 或拖进浏览器
否则哪怕路径写对了,控制台也只显示NotFoundError: Request failed,根本不会提示“跨域”二字,非常误导。
tf.loadLayersModel()的 URL 必须指向 model.json,不是.h5 或.pb
TensorFlow.js 不认 Keras 原生 .h5 或 SavedModel 的.pb——这些得先用 Python 转成 tf.js 格式:
- 用
tensorflowjs_converter --input_format=keras my_model.h5 web_model/ - 输出是
web_model/model.json+ 若干web_model/group1-shard*.bin -
tf.loadLayersModel()只接受model.json的 URL,自动按 JSON 里描述的路径拉 shard 文件
常见错误:把 my_model.h5 直接丢进loadLayersModel(),报Unexpected token {in JSON at position 0——因为 h5 是二进制,开头不是 JSON 大括号。
立即学习 “ 前端免费学习笔记(深入)”;
推理前必须 await model.ready(),否则model.predict() 返回空 tensor
模型加载是异步的,但 loadLayersModel() 返回的是一个 Promise,很多人写成:
const model = await tf.loadLayersModel('web_model/model.json'); model.predict(……); // ❌ 这里 model 还没真正 ready
正确做法:
const model = await tf.loadLayersModel('web_model/model.json'); await model.ready(); // ✅ 等权重实际加载完毕 const result = model.predict(inputTensor);
漏掉 ready() 会导致 predict() 静默失败,输出 shape 可能是 [0] 或null,debug 时很难联想到是加载没完成。
输入 tensor 维度和 dtype 要严格匹配训练时的tf.inputShape
比如模型输入是[1, 224, 224, 3](batch=1、RGB 图),你就不能传[224, 224, 3];如果训练时用了tf.float32,也不能传Uint8Array。
典型处理链:
- 用
tf.browser.fromPixels(img)读图像 → 得到uint8类型 - 立刻
.resizeNearestNeighbor([224, 224])+.expandDims(0)补 batch 维 - 再
.cast('float32')+.div(255.0)归一化
少一步就可能输出全零、NaN,或维度不匹配报错Input tensor should have rank 4 but has rank 3。
模型转换和加载那几步环环相扣,哪一环路径写错、协议用错、等待漏掉、张量搞错,都会让推理在静默中失败——而浏览器控制台往往只给个模糊错误,得靠检查每一步的输出 shape 和 type 来定位。