使用网络图片URL训练TensorFlow.js时tf.browser.fromPixels报错如何解决
问题原因
- 你从
canvas包引入的Image是Node.js环境下的模拟实现,并非浏览器原生的HTMLImageElement类型,而tf.browser.fromPixels()是浏览器端专用API,无法识别该Node端实现的Image实例。 - 你同时引入了浏览器版TensorFlow.js包
@tensorflow/tfjs和Node.js版包@tensorflow/tfjs-node,环境依赖冲突,Node环境下应该使用tfjs-node提供的专用图片处理API,而非tf.browser命名空间下的API。
解决方案
你可以直接用tfjs-node自带的图片解码能力处理网络图片,不需要引入canvas包的Image对象,修改后的可运行代码如下:
首先安装缺失依赖:
npm install @tensorflow/tfjs-node @tensorflow-models/mobilenet @tensorflow-models/knn-classifier node-fetch@2
注:node-fetch用v2版本,v3版本仅支持ES模块导入,CommonJS项目用v2更适配。
修改后的代码:
const tf = require("@tensorflow/tfjs-node"); const mobilenetModule = require("@tensorflow-models/mobilenet"); const knnClassifier = require("@tensorflow-models/knn-classifier"); const fetch = require("node-fetch"); const classifier = knnClassifier.create(); const urls = ["https://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Solid_white.svg/2048px-Solid_white.svg.png", "https://stone.co.nz/wp-content/uploads/2020/06/Iconic-Black.jpg", "https://media.tarkett-image.com/large/TH_25094225_25187225_001.jpg"]; // 封装加载远程图片并转为tensor的方法 async function loadImage(url) { // 拉取图片二进制数据 const response = await fetch(url); const arrayBuffer = await response.arrayBuffer(); const uint8Array = new Uint8Array(arrayBuffer); // 解码图片为tensor,自动处理jpg、png等格式 return tf.node.decodeImage(uint8Array, 3); } async function start() { const mobilenet = await mobilenetModule.load(); // 加载并添加训练样本 const pic0 = await loadImage(urls[0]); const logits0 = mobilenet.infer(pic0, true); classifier.addExample(logits0, 0); pic0.dispose(); // 用完释放tensor内存,避免泄漏 const pic1 = await loadImage(urls[1]); const logits1 = mobilenet.infer(pic1, true); classifier.addExample(logits1, 1); pic1.dispose(); // 加载测试图片预测 const checkPic = await loadImage(urls[2]); const xlogits = mobilenet.infer(checkPic, true); const p = await classifier.predictClass(xlogits); console.log("预测结果:", p); checkPic.dispose(); } start();
代码修改说明:
- 移除了浏览器版tfjs和canvas包的依赖,仅保留Node.js版tfjs的相关依赖
- 用
node-fetch拉取远程图片的二进制数据,直接调用tf.node.decodeImage解码为TensorFlow可直接使用的张量,绕过Image类型不兼容的问题 - 把原来的回调式异步逻辑改成async/await写法,避免训练样本还没加载完成就执行预测的时序问题
- 增加了张量释放逻辑,避免Node进程内存泄漏
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

