想象你开了一家“浏览器快餐店”,正需要一位全能大厨。这位大厨师承国际顶级厨艺学校,在海量食材、菜单、顾客话语中反复历练过——他眼睛一扫就知道食材好坏,瞄一眼菜单就懂顾客口味,竖起耳朵就听得出客人在嘈杂中点了什么。这位大厨就是“预训练模型”:一个在海量数据上预先训练好的 AI 模型,身怀图像识别、文本理解、语音转录三种绝活。 但大厨远在云端数据中心,你不想让每道菜都经历“传菜到云端再等结果”的漫长往返。TensorFlow.js(简称 TF.js)就是连接大厨与浏览器窗口的“开放式传菜管道”——它让网页不依赖服务器,直接在用户的浏览器里加载模型、执行推理、返回结果。 这篇文章将跟你一起走一遍完整的“后厨开店流程”:如何把大厨请进网页(模型加载)、如何把三类食材切成他习惯的规格(图像 / 文本 / 语音的输入适配)、看他如何展示三种绝活(推理),以及如何把菜品精美装盘(后处理)并在午市高峰稳住出菜速度(轻量化部署)。读完你会发现,“浏览器里跑 AI”并没有想象中那么神秘。

岗位关联

掌握 TF.js 预训练模型的三模态接入与前后处理细节,前端工程师就能不依赖后端独立交付“浏览器即 AI”的智能应用,大幅降低 AI 功能的上线成本与部署门槛。

目录
  1. 可视化演示
  2. 模型加载:请大厨进店
  3. 图像输入:切配熟悉的食材
  4. 文本输入:大厨的私房词典
  5. 语音输入:竖起耳朵听波形
  6. 后处理:装盘、点缀、上桌
  7. 部署优化:后厨提速指南
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

演示TF.js在Web端加载预训练模型进行图像、文本与语音推理的完整流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

图像推理 输入 模型 Img→Cls 图像分类与检测

模型加载:请大厨进店

想象你开了一家快餐厅,重金请来一位在米其林三星后厨历练过的全能大厨。大厨答应来,但他得先从总店“调过来”——陪伴他多年的刀具、灶台布局、秘制香料,全都要搬到你的店里。对他而言,“换店”意味着重铺一套顺手的工作台;对预训练模型来说,这个“搬店”的过程就是模型加载。

在 TF.js 的世界里,tf.loadLayersModel 和 tf.loadGraphModel 是请大厨入店的“两条专用通道”。前者负责迎接“Keras 出身”的模型——也就是用 Python 的 Keras API 训练、导出为 JSON 加权重分片的组合;后者则迎接来自 TensorFlow 生态的 SavedModel / GraphDef 格式。你只需提供一个 URL,TF.js 就会先下载描述文件 model.json,再由它找到权重分片逐一拉取。除了 TF.js,ONNX.js 是另一条并行的“传菜管道”,但本文以 TF.js 为主角。

加载完成后,模型对象已“上岗”:你可以调用 model.predict(input) 让它干活。这个函数的底层是一条计算图——从输入张量出发,逐层做矩阵乘法、卷积、激活,最后在输出端给出预测。加载细节里藏着几个工程坑:模型文件大时要上 CDN;加载是异步的,要用 await 处理;若模型 URL 失效必须捕获异常并给出友好提示。

大厨就位,刀具齐整。接下来就该看看他如何面对形形色色的客人了——第一位客人端着一盘照片走了过来。

Model←tf.loadLayersModelmodel.json+weights.bin\displaystyle \text{Model} \xleftarrow{\texttt{tf.loadLayersModel}} \text{model.json} + \text{weights.bin}
这个公式描述了加载的本质:通过 URL 拿到配置清单和权重分片,在浏览器里组装出一个可推理的模型对象。
  1. Model加载完成后得到的模型对象,相当于大厨拿到“上岗证”
    Model\text{Model}
  2. tf.loadLayersModelTF.js 提供的加载函数,专为 Keras 层模型设计
    tf.loadLayersModel\texttt{tf.loadLayersModel}
  3. model.json描述层结构、权重文件名的配置清单
    model.json\text{model.json}
  4. weights.bin存放实际权重数值的二进制分片
    weights.bin\text{weights.bin}

图像输入:切配熟悉的食材

第一位客人递来的不是食材,而是手机里的照片。大厨不会把带着反光、滤镜的照片直接丢进炒锅,他会先切出自己习惯的规格。图像识别模型同样“挑剔”:它认识的食材是固定尺寸、经过标准化的数字矩阵,而不是浏览器里的 <img> 元素。

在 TF.js 中,tf.browser.fromPixels() 是第一个中转站,它把图像像素读取为 H×W×3 的张量(3 代表 R、G、B 三个通道)。随后通常要链式调用 resizeBilinear([224,224]) 统一尺寸,再 toFloat().div(255) 完成归一化。为什么是 224×224?因为 MobileNet 等主流预训练模型正是在这个分辨率上练就的“手艺”。

更严格的预处理还要求按通道减去均值、除以标准差——比如 ImageNet 数据集的 mean=[0.485, 0.456, 0.406]、std=[0.229, 0.224, 0.225]。这组数字是大厨食谱里的“火候刻度”,差一点都不香。若跳过预处理,模型相当于拿到一堆“没切过的整块猪肘”,输出自然离谱。若做目标检测,COCO-SSD 模型不仅要求同样的预处理,还会输出多个目标框坐标与类别,进一步加大“切配”的讲究。

食材按大厨的要求切成了均匀的“丁”,接下来的炒制顺理成章。

x^=x255.0,shape=(1, 224, 224, 3)\displaystyle \hat{x} = \frac{x}{255.0}, \qquad \text{shape} = (1,\, 224,\, 224,\, 3)
图像预处理的两件事:把像素值从 0~255 缩放到 0~1,再统一成模型期望的输入形状。
  1. x原始像素值,范围 [0, 255]
    xx
  2. 255.0归一化分母,把像素压到 [0, 1]
    255.0255.0
  3. (1, 224, 224, 3)批次 1、宽高 224、通道 3
    (1, 224, 224, 3)(1,\, 224,\, 224,\, 3)

文本输入:大厨的私房词典

第二位客人递来一张皱巴巴的菜单,写着“麻婆豆腐,微辣”。大厨读菜单时看到的不是笔画,而是脑子里浮现的“味觉向量”——花椒的麻、豆瓣酱的咸鲜、豆腐的嫩滑。文本模型也一样,它要通过一本“数字词典”把文字翻译成向量的语言。

第一步是分词(tokenize):句子被切成词或子词,每个 token 在词典里对应一个整数 id,比如“麻婆豆腐”映射为 [102, 15, 88]。社区封装好的 @tensorflow-models/universal-sentence-encoder 会把整句话一键编码为 512 维向量;BERT 类模型则需要更细致的 token 输入,还附带 attention mask。输入张量的形状通常是 (1, seq_len),类型为 int32。

得到 token 索引只是“识字”,真正“懂味”靠的是嵌入矩阵 E——一个 V×d 的查表,把每个整数 id 映射成稠密向量,这一步叫嵌入向量查找。预训练模型的“阅历”就藏在这些向量里。情感分析模型的输出端接一个分类头,能给出“好评 92%”这样的分数;GPT 类生成模型则输出下一个 token 的概率分布,每次采样拼接,实现逐字续写。

大厨的词典越厚,读菜单的“品味”就越准——预训练模型的嵌入向量越丰富,语义理解越细腻。

ei=E [ ti ],E∈RV×d\displaystyle e_i = E\,[\,t_i\,], \qquad E \in \mathbb{R}^{V \times d}
文本模型把离散的 token 编号映射为稠密向量,语义相近的词在向量空间中距离更近。
  1. t_i句子中第 i 个 token 的整数编号
    tit_i
  2. E嵌入矩阵,词典大小 V 行、嵌入维度 d 列
    E∈RV×dE \in \mathbb{R}^{V \times d}
  3. e_i第 i 个 token 对应的稠密语义向量
    eie_i

语音输入:竖起耳朵听波形

第三位客人隔着玻璃喊了一声“少辣,快一点!”,后厨噪音不小,大厨却能精准抓住关键词。他的秘诀不是听力超群,而是善于提取声线里的频谱特征——语调、共振峰、节奏,这些才是他听得懂的“语音纹理”。

浏览器里,麦克风经 AudioContext 解出的是一串原始采样点(比如每秒 16000 个)。直接把这上万个浮点塞给模型既不高效也不稳定,所以第一步是波形分帧:每 20~30 毫秒切一帧,帧与帧之间重叠,再对每帧加窗做短时傅里叶变换(STFT),得到一个二维频谱特征矩阵。这一步与大厨“听语气”如出一辙:放弃波形细节,抓住频率结构。

TF.js 社区包 @tensorflow-models/speech-commands 已封装好“录音→分帧→特征→分类”全链路,适合唤醒词识别(如"Hey Siri")。完整语音转录则需要更深模型配合 CTC 解码——模型输出每一帧的字符合成概率,通过解码策略合并成一句完整的话。

就像大厨听到的是语气和关键词,语音模型听到的是梅尔系数、频谱峰和语音纹理——特征对了,转录自然正确。

Xf=∑n=0N−1x[n] w[n] e−j2πfnN\displaystyle X_f = \sum_{n=0}^{N-1} x[n]\, w[n]\, e^{-j\frac{2\pi f n}{N}}
短时傅里叶变换的本质:把一段时域波形翻译成频率域特征,相当于大厨把“嗓音”翻译成“语气要素”。
  1. x[n]第 n 个采样点的幅值
    x[n]x[n]
  2. w[n]窗函数(如汉明窗),减弱截断效应
    w[n]w[n]
  3. N帧长,决定频率分辨率
    NN
  4. X_f该帧在频率 f 上的复数能量
    XfX_f

后处理:装盘、点缀、上桌

大厨炒完菜,不会连铁锅带油烟端给顾客。他会装盘、摆盘、确认温度、撒上葱花——这些收尾动作,对应到 AI 推理里就是后处理。

模型的裸输出是一个张量,里面的数值往往是 logits——可以理解为大厨刚出锅的“半成品”。分类模型最后一层有 K 个 logits,它们不是概率:加起来不等于 1,还可能出现负数。Softmax 就像“调味”步骤,把 logits 指数化再归一化,变成一组和为 1 的概率。拿到概率后还要做“质检”:置信度低于阈值(如 0.5)的结果直接丢弃,宁可不报也不能报错。

图像分类往往取 top-k 个标签并渲染成条形图,这是结果可视化;语音转录则用 CTC 贪心解码,把帧级概率合并成词句,这是解码策略。在 TF.js 中,所有输出都需要 await output.data() 把张量取成普通 JS 数组,才能在页面上绘制图表。

装盘既不能烫手也不能寡淡——后处理既保证准确性,又保证用户看得懂。

pi=ezi∑j=1Kezj,y^=arg⁡max⁡i pi\displaystyle p_i = \frac{e^{z_i}}{\sum_{j=1}^{K} e^{z_j}}, \qquad \hat{y} = \arg\max_i\, p_i
Softmax 把裸分数变成概率分布,argmax 决定最终预测类别——装盘的最后一步是“挑出最自信的那道菜”。
  1. z_i模型输出的第 i 类原始分数(logit)
    ziz_i
  2. 指数归一化指数放大分数差距,再除以总和使概率和为 1
    pi=ezi∑j=1Kezj\displaystyle p_i = \frac{e^{z_i}}{\sum_{j=1}^{K} e^{z_j}}
  3. argmax取概率最大的类别作为最终输出
    y^=arg⁡max⁡i pi\hat{y} = \arg\max_i\, p_i

部署优化:后厨提速指南

午市高峰来了,点单如山。大厨炒得再快,如果传菜道只有一条、锅具又大又沉,顾客照样等得不耐烦。让 AI 在浏览器里流畅运行,同样是一套“后厨工程”。

第一个瓶颈是模型体积。MobileNet 约 16MB,BERT 轻量模型约 25MB,更大的模型动辄数百 MB。int8 量化是最直接的“换小锅”:把 FP32 权重按比例缩放、取整、截断到 0~255 的整数,体积直接缩到四分之一。模型裁剪则是“砍掉冗余配菜”——删除贡献极低的网络通道。TF.js Converter 在模型转换时即可顺手完成两步。

第二个瓶颈是运行时性能。WebGL 后端让推理跑在 GPU 上;把推理放进 Web Worker 则避免阻塞 UI 主线程;模型文件用 HTTP 缓存或 IndexedDB 存下来,二次访问秒开。要评估效果,可以用 tf.engine().profile() 分析每一层耗时。一套组合拳下来,“首屏加载 3 秒内、单次推理 100 毫秒内”是现实的工程红线。

灶台规格统一、备料提前就位、高峰订单走独立窗口——轻量化部署就是一家“快而不乱”的后厨。

xq=clip⁡(⌊xs⌋+z,  0,  255)\displaystyle x_q = \operatorname{clip}\left(\left\lfloor \frac{x}{s} \right\rfloor + z,\; 0,\; 255\right)
量化公式:把浮点权重映射到 int8 的 256 个档位,用少量精度损失换来 4 倍体积压缩和更快访存。
  1. x原始的 FP32 权重或激活值
    xx
  2. s缩放因子,由训练后统计的 min/max 决定
    ss
  3. z零点偏移,让数值 0 能被精确表示
    zz
  4. clip截断到 [0, 255],即 int8 的完整表示范围
    clip⁡(⋅,  0,  255)\operatorname{clip}(\cdot,\; 0,\; 255)

AI 应用场景

电商实时拍照识物

阶段:模型加载 + 图像推理 + 后处理

解决的问题:传统方案需把图片上传到服务器识别,往返延迟高且产生服务器带宽成本;用 TF.js 在浏览器本地识别,图片不出本机,秒级出结果。

具体案例:某家居电商在商品详情页嵌入“拍照识别家具”入口,用户拍一张沙发照片,MobileNet 在浏览器内给出 top-3 类别和风格标签,并联动推荐搭配商品。

客服弹窗实时情感分析

阶段:文本推理 + 后处理可视化

解决的问题:人工监控客服对话情绪成本高且滞后;前端文本模型实时为每句话打“正面/负面”分,负面情绪出现时立刻触发安抚流程。

具体案例:SaaS 客服系统在输入框旁显示情绪色块,顾客连发三条负面消息时,页面自动弹出优惠券发放卡片,减少客诉升级。

浏览器内会议录音转写

阶段:语音推理 + CTC解码

解决的问题:会议录音传云端转写有隐私泄露和传输延迟风险;本地转录让音频数据完全不出浏览器,同时支持离线使用。

具体案例:在线会议室新增“实时字幕”按钮,点击后 speech-commands 模型识别语音活动,DeepSpeech 风格模型转写并渲染字幕,演讲者说话 0.5 秒内字幕上屏。

Python 演示

python72 行
# 模拟 TF.js 预训练模型的三模态加载、推理与后处理流程import numpy as npimport jsonfrom pathlib import Path  class PretrainedPipeline:    """模拟 TF.js 预训练模型在浏览器中的完整推理流程"""     def __init__(self, model_dir="models"):        self.model_dir = Path(model_dir)        self.model_dir.mkdir(exist_ok=True)        self.loaded_models = {}     def load_model(self, name):        """加载模型: 对应 tf.loadLayersModel 的异步过程"""        print(f"[加载] 正在加载 {name} ...")        self.loaded_models[name] = True        return self     @staticmethod    def softmax(logits):        """后处理: logits -> 概率分布"""        exp = np.exp(logits - np.max(logits))        return exp / exp.sum()     def predict_image(self, pixels):        """图像推理: 像素归一化 -> 模拟 logits -> softmax"""        x = np.array(pixels, dtype=np.float32) / 255.0        logits = np.array([2.1, 0.3, -1.2, 0.8])        prob = self.softmax(logits)        return {            "class_id": int(prob.argmax()),            "confidence": round(float(prob.max()), 3),            "distribution": prob.round(3).tolist(),        }     def predict_text(self, token_ids):        """文本推理: token 序列 -> 平均嵌入 -> 情感打分"""        emb = np.array(token_ids, dtype=np.float32)        score = float(np.tanh(emb.mean() * 0.5))        return {"sentiment": "positive" if score > 0 else "negative",                "score": round(score, 4)}     def predict_audio(self, frames):        """语音推理: 波形帧 -> 均方根能量 -> 转录结果"""        energy = float(np.sqrt(np.mean(np.square(frames))))        return {"transcript": "你好" if energy > 0.3 else "...",                "energy": round(energy, 4)}     def run_web_demo(self):        """综合演示: 加载三个模型并依次执行推理"""        self.load_model("mobilenet_v2")        self.load_model("bert_tiny")        self.load_model("deepspeech_tfjs")         image_out = self.predict_image([128, 64, 200, 15, 90, 230])        text_out = self.predict_text([102, 15, 88, 3, 204])        audio_out = self.predict_audio([0.1, -0.3, 0.4, -0.2, 0.5])        print("[图像]", image_out)        print("[文本]", text_out)        print("[语音]", audio_out)         return {"image": image_out, "text": text_out, "audio": audio_out}  if __name__ == "__main__":    pipe = PretrainedPipeline()    result = pipe.run_web_demo()    with open("demo_result.json", "w", encoding="utf-8") as f:        json.dump(result, f, ensure_ascii=False, indent=2)    print("结果已保存至 demo_result.json")
目的:用纯 Python 模拟 TF.js 在浏览器中加载三个预训练模型并依次完成图像、文本、语音推理的全流程,帮助你理解前后端 AI 推理的共性逻辑。
  1. self.loaded_models[name] = True记录已加载的模型,对应 TF.js 中模型对象的缓存复用。
  2. exp = np.exp(logits - np.max(logits))减去最大值防止指数溢出,这是数值稳定的 softmax 标准写法。
  3. x = np.array(pixels, dtype=np.float32) / 255.0模拟图像像素的 0~1 归一化预处理。
  4. prob = self.softmax(logits)后处理的关键一步:把裸 logits 转成概率分布。
  5. score = float(np.tanh(emb.mean() * 0.5))模拟文本 token 嵌入取平均后映射为情感分数。
  6. energy = float(np.sqrt(np.mean(np.square(frames))))模拟语音波形的均方根能量特征提取。
  7. pipe.run_web_demo()主入口:依次加载并推理三个模态模型,对应真实项目的初始化流程。

常见误区

误区“我用 `tf.loadLayersModel` 把模型加载出来了,应该可以直接用吧?为什么预测结果全是同一个类别?” 很多初学者以为加载等于万事大吉。

正解加载只是“大厨站在了灶台前”,输入适配才是“切配”。图像有没有归一化、尺寸是否匹配、文本有没有按词典编码、语音有没有分帧做频谱,任何一步与训练时不符,输出都是垃圾。前端 AI 的 80% 调试时间都花在输入管线上。

为何常见:看到模型对象返回就误以为“模型在跑了”,忽略了 AI 链路的前置工序和后置解码。

误区“BERT 有 3 亿参数,GPT-3 有 1750 亿参数,浏览器怎么可能跑得动?” 于是直接放弃了 Web 端 AI。

正解移动端 / Web 端有一条专门的轻量模型产品线:MobileNet(图像)、TinyBERT / DistilBERT(文本)、Speech Commands(语音)都是百万到千万参数级,经 int8 量化后普遍小于 10MB,WebGL 下推理耗时在几十毫秒量级,完全可实时。

为何常见:只听说过巨型模型的名号,没有意识到“为端侧而生的轻量模型”是另一片成熟的生态。

误区“我 Python 里训练的 `.h5` 文件,直接填进 `tf.loadLayersModel` 的 URL 不就行了?” 结果报错后一头雾水。

正解模型需要一个转换步骤:用 tensorflowjs_converter 把 Keras 模型转成 layer format,把 SavedModel 转成 graph format,转换时还可以顺手做量化。转换产物是一份 model.json 加若干权重分片,浏览器才能识别。

为何常见:误以为 TF.js 与 Python TensorFlow 共用同一套权重文件格式,其实它们是“不同厨房的刀法”。

误区“推理要几百毫秒,一跑页面就白了,这产品没法用。” 部分开发者把推理和页面渲染混在同一线程,自然卡顿。

正解用 WebGL 后端把矩阵运算交给 GPU,推理与 UI 并行;把推理移入 Web Worker 则彻底不阻塞主线程;再配合张量复用(tf.tidy),可以做到动画 60fps 不掉帧。之前提到的“加载大文件”和“推理耗时”是两码事,后者通过优化完全可以控制在毫秒级。

为何常见:把“浏览器性能”等同于“JS 主线程性能”,忽略了 WebGL 和 Worker 这两条重要的并行通道。

误区“图像、文本、语音各一个模型,每个都要单独加载,那网页岂不是要下三个大文件?”

正解TF.js 支持多模型共存并共享同一个 backend 上下文,可以按页面路由懒加载:进入图片页只加载视觉模型,进入聊天页只加载文本模型。部分多模态模型(如 CLIP 类)甚至一个模型同时吃图和文,输出统一的语义向量。

为何常见:对 TF.js 的 backend 上下文共享机制不熟悉,以为每次 loadLayersModel 都是“从零开新灶”。

面试题

Q1. TF.js 加载 Keras 模型应该调用哪个函数?

单选题 · easy

  • A.tf.loadLayersModel 方法← 正确答案
  • B.tf.loadGraphModel 方法
  • C.tf.loadWeights 方法
  • D.tf.loadTensor 方法

答案:A。tf.loadLayersModel 专门加载 Keras 层模型,tf.loadGraphModel 负责 GraphDef/SavedModel 图模型。C 和 D 是生造的干扰项,TF.js 没有这两个加载入口。类比大厨的“两条入店通道”,Keras 走层模型通道。

Q2. MobileNet 的图像输入尺寸通常是?

单选题 · easy

  • A.224x224 像素← 正确答案
  • B.512x512 像素
  • C.28x28 像素
  • D.1024x1024 像素

答案:A。MobileNet 预训练权重在 224×224 分辨率上训练,输入必须与训练一致,否则特征分布漂移。28×28 是 MNIST 手写数字的尺寸,512 和 1024 也不是 MobileNet 的标准输入。

Q3. 下面哪项是文本模型的输入形式?

单选题 · easy

  • A.整数组成的 token 序列← 正确答案
  • B.音频波形一维数据
  • C.像素颜色值三维数组
  • D.视频图像的灰度矩阵

答案:A。文本模型输入是分词后的 token 整数序列;音频波形是语音模型输入;像素三维数组是图像模型输入。三种模态对应三种完全不同的张量形态,就像大厨读菜单、看食材、听招呼用的是三种感知方式。

Q4. softmax 函数的主要作用是?

单选题 · mid

  • A.输出值转换成正概率分布← 正确答案
  • B.压缩模型到四分之一体积
  • C.将文字转换成词向量集合
  • D.提升音频采样的帧频率

答案:A。softmax 把 logits 指数化并归一化,使输出非负且和为 1,成为概率分布。模型体积压缩靠量化剪枝,文字转向量靠嵌入层,音频帧率提升靠重采样。softmax 是“装盘上桌”的调味步骤。

Q5. TF.js 中图像预处理为何要归一化?

单选题 · mid

  • A.匹配训练时的数据分布规律← 正确答案
  • B.让浏览器渲染图片速度更快
  • C.减少图片上传的网络流量需求
  • D.把彩色图片转换成黑白灰度图

答案:A。预训练模型学到的权重是在特定归一化分布下收敛的,输入必须按同样的 mean/std 或 0~1 缩放处理,模型才能正确推理。其余选项都是对“归一化”概念的想当然。

Q6. 语音模型通常的输入特征是什么?

单选题 · mid

  • A.频谱图或波形特征张量← 正确答案
  • B.用户语言的文字拼音串
  • C.麦克风音量大小的整型数
  • D.浏览器窗口的音频播放列表

答案:A。语音模型输入是分帧加窗后得到的频谱特征或原始波形张量。拼音串是定义层的输出格式,音量和播放列表更是概念错位。大厨听的是“语气频谱”,不是分贝数值。

Q7. 模型加载成功但所有图片分类结果相同,最可能原因?

单选题 · mid

  • A.输入图像的标准化配置不一致← 正确答案
  • B.CDN 缓存了过期的权重分片
  • C.浏览器禁用了 WebGL 加速
  • D.模型预测函数被重复调用

答案:A。所有输入都落到同一类别,最常见原因是预处理与训练不一致——忘了归一化、通道顺序 BGR/RGB 颠倒等。权重分片损坏会在加载阶段报错而非输出错误;WebGL 禁用只会变慢;重复调用不会导致类别坍缩。

Q8. 浏览器端提升 TF.js 推理速度的常用手段有?

多选题 · mid

  • A.采用 WebGL 后端 GPU 加速计算← 正确答案
  • B.将推理流程放到 Web Worker 中← 正确答案
  • C.对权重进行 int8 量化压缩体积← 正确答案
  • D.把全部模型代码写在 HTML 页面中

答案:ABC。WebGL 走 GPU 并行、Worker 避免阻塞主线程、int8 量化减少计算量,三者都是标准提速手段。把所有代码写进 HTML 与提速无关,且工程上不可维护。就像后厨提速靠换小锅、加传菜口,而不是把菜单贴满墙。

Q9. 下列关于 TF.js 模型后处理的描述正确的是?

多选题 · mid

  • A.softmax 将 logits 转为概率分布← 正确答案
  • B.阈值过滤可剔除低置信度结果← 正确答案
  • C.语音转录需要 CTC 解码出文本← 正确答案
  • D.图像结果只能显示英文标签

答案:ABC。A、B、C 分别对应概率归一、质检过滤、解码策略三个后处理环节。标签语言完全取决于前端代码映射,D 是错误常识。“装盘上桌”的工序可以自己定。

Q10. 关于 TF.js 加载预训练模型,说法正确的是?

多选题 · hard

  • A.Keras 模型经转换后对应 loadLayersModel← 正确答案
  • B.GraphDef 模型对应 loadGraphModel 加载← 正确答案
  • C.同一后端上下文可同时运行多个模型← 正确答案
  • D.模型权重只能用 HTTP 协议下载缓存

答案:ABC。Keras 层模型走 loadLayersModel,GraphDef 图模型走 loadGraphModel,二者是 TF.js 的两条加载通道。多模型可共享 WebGL 上下文。D 错在“只能”,模型也能用 IndexedDB 持久化缓存,实现二次访问秒开。