认识
一、认识
TensorFlow.js 是一个开源的 JavaScript
实现的机器学习库(深度学习框架),允许在浏览器和 Node.js
环境中运行机器学习模型,执行训练和推理。Tensorflow
的核心是 计算图 Computational Graph
。计算图将复杂的数学运算拆解成一系列节点和边: 节点(Node/Op
), 代表具体的操作, 比如矩阵乘法、卷积、激活函数等; 边(Edge/Tensor
), 代表在操作之间传递的数据,即张量。计算图的优势在于: 可以并行计算, 图中的各个节点间的依赖关系明确,便于调度到不同设备(如 CPU
、GPU
、TPU
)并行计算; 可以优化执行, TensorFlow
可以对整个计算图进行静态优化(如常量折叠、操作融合),从而减少冗余计算和内存消耗; 可以跨平台部署, 构建好的计算图可以保存为 SavedModel
,方便部署到不同平台(服务器、移动端、Web
)。Tensorflow
执行模式为: Eager Execution
(动态图模式) 和 Graph Execution
静态图模式, TensorFlow 2.x
默认启用了 Eager Execution
,这种模式下,操作在调用时立即执行,便于调试和开发。静态图模式下,先构建整个计算图,然后通过 Session
或 tf.function
来执行。静态图便于在部署前进行全局优化。而且, 静态图模式可在训练时实现更高效的优化和并行调度,适合大规模数据训练。
Tensorflow
模型训练工作流:
-
数据加载与预处理: 1. 数据输入流水线, 利用
tf.data API
构建高效的数据流水线,从磁盘、数据库或其他数据源中加载数据; 2. 预处理操作, 包括数据清洗、归一化、数据增强(如图像旋转、翻转)、分割等,保证数据质量和模型泛化能力; 3. 批处理与预取, 通过 .batch()、.cache()、.prefetch() 等方法,减少 I/O 瓶颈,提升训练效率; 数据加载后转换成Tensor
,Tensor
是TensorFlow
的基本数据结构(多维数组),它们在后续计算图中流动,成为各个节点的输入和输出。数据加载后以Tensor
形式存在,贯穿整个计算图,确保数据在各层间顺畅传递。 -
初始化权重 和偏置 : 权重(
Weights
) 是连接不同神经元的参数, 决定输入数据的重要性, 训练过程中不断优化, 以最小化误差, 表示连接强度, 是训练过程中优化的关键参数; 偏置(Bias
), 额外的可训练参数,提高模型的灵活性, 调整激活函数的输入, 提高灵活性。使用随机初始化(如Xavier/Glorot
或He
初始化)、常数初始化等方法,这些参数以Tensor
形式存储,并被定义为可训练变量。权重 和 偏置 作为计算图中的变量节点, 参与前向传播和反向传播, 并在训练过程中不断更新。 -
模型构建: 使用
tf.keras
构建模型,常见方式有Sequential API
或函数式API
,构建包含全连接层、卷积层、池化层等的神经网络。模型的每一层都会在底层生成对应的计算图节点(Operation
),各层之间的运算通过边(Tensor
)连接,构成一个完整且优化的计算图。此外,可以利用模块化设计、共享权重等手段提高代码复用性和结构清晰度。 -
前向传播(
Forward Propagation
): 输入的Tensor
依次通过每一层的运算(如矩阵乘法、加偏置、激活函数等),最终生成输出Tensor
。每个运算步骤都对应计算图中的一个节点,Tensor
从图的一端传递到另一端,完成前向传播计算。激活函数(如Sigmoid
、ReLU
、Softmax
等)引入非线性,使神经网络能够学习复杂的特征表示。(模型构建、前向传播、损失计算和反向传播等所有计算步骤均在计算图中进行,充分利用了图优化和自动微分机制) -
计算损失(
Loss Function
): 将模型输出的预测Tensor
与真实标签Tensor
进行比较,计算误差。损失值也是以Tensor
形式存在,并构成计算图的一部分。损失反映了模型预测结果与真实值之间的偏差,越小表示模型性能越好。损失函数有: 均方误差(MSE
)(用于回归)、交叉熵损失(Cross-Entropy Loss
)(用于分类)(模型构建、前向传播、损失计算和反向传播等所有计算步骤均在计算图中进行,充分利用了图优化和自动微分机制) -
反向传播(
Backpropagation
)与更新参数: 利用 自动微分(Automatic Differentiation
) 机制,TensorFlow
通过tf.GradientTape
自动记录前向传播过程,并利用链式法则计算各参数的梯度。每个参数(权重、偏置)的梯度均为Tensor
,表示该参数对损失函数的敏感度。根据计算出的梯度,通过优化器(如 梯度下降(GD
)、随机梯度下降(SGD
)、Adam
)更新参数。在反向传播过程中,计算图会反向遍历,沿着各个边(Tensor
)传递梯度,从而更新图中的变量节点。 -
重复训练直至模型收敛: 通过多个
Epoch
重复执行前向传播、损失计算和反向传播,每个Epoch
中模型参数不断更新,损失逐渐降低 (通过不断迭代前向和反向传播,利用梯度下降类算法更新参数,最终使模型收敛到较优解)。动态图与静态图模式:Eager Execution
(动态图模式):TensorFlow 2.x
默认开启,操作在调用时即时执行,便于调试和快速迭代; 静态图(tf.function
):可以使用@tf.function
装饰器将关键函数转换为静态计算图,TensorFlow
会对整个图进行全局优化,从而大幅提升运行效率。因此, 在开发过程中利用Eager Execution
快速验证想法,而在正式训练中切换到静态图模式(tf.function
)实现高性能训练。因此, 动态图与静态图模式 让开发既具备调试灵活性,又能达到高性能训练效果。 -
分布式训练与多设备支持:
TensorFlow
提供了tf.distribute.Strategy
, 支持多设备(如GPU
、TPU
)和多机分布式训练。常用策略包括:MirroredStrategy
, 适用于单机多GPU
情况,将模型副本复制到每个GPU
,并在每个批次后同步更新;MultiWorkerMirroredStrategy
, 适用于多机训练,协调各个机器上的设备进行同步更新。通过数据并行或模型并行,TensorFlow
能充分利用硬件资源,显著加速训练过程。分布式训练与多设备支持 则展示了TensorFlow
在大规模训练场景下的扩展能力,为工业级应用提供了强有力的支撑。 -
模型评估与保存: 在训练结束后,使用测试集或验证集评估模型性能,计算准确率、精度、召回率等指标。将训练好的模型及其计算图和参数(
Tensors
)保存为SavedModel
格式,方便后续部署到生产环境或跨平台应用(如Web
、移动端等)。保存的模型可用于在线推理或离线批量处理,利用TensorFlow Serving
等工具实现高效部署。
Tensorflow
模型预测工作流:
-
模型部署与格式转换: 在训练完成后,我们通常会将模型保存为
SavedModel
格式,该格式不仅包含模型结构和参数,还保存了计算图,便于跨平台部署。然后转换为Web
端支持的格式: 层级模型Layers Model
: 通过tf.loadLayersModel(pathOrIOHandler, options?)
来加载。模型一般为:model.json
用于存储模型结构,.bin
用于存储模型权重; 计算图模型Graph Model
:TensorFlow.js
加载TensorFlow(Python)
导出的模型。通过tf.loadGraphModel(modelUrl, options?)
来加载, 模型一般为:model.json
用于存储模型结构,.bin
用于存储模型权重。加载后的model
通过model.predict
来进行推理。其中,Graph Model
模型 通常会加快浏览器和Node.js
的推理速度,这要归功于生成Graph Model
的图形优化。转换后的Graph Model
不支持进一步训练。 -
模型加载: 使用
TensorFlow.js
提供的加载方法,如tf.loadGraphModel
(加载Graph
模型)或tf.loadLayersModel
(加载Keras
模型) -
数据采集与预处理: 数据可以来自用户上传、摄像头、文件输入或
API
接口。为了与训练时一致,需要对输入数据做归一化、尺寸调整、色彩空间转换等预处理操作。 -
模型推理: 将预处理后的
Tensor
作为输入传递给模型的predict
方法,获取输出Tensor
-
后处理与结果展示: 根据模型输出进行进一步处理,如阈值判断、分类标签映射或回归结果的反归一化; 将推理结果更新到页面上或通过其他方式反馈给用户。
-
性能优化与资源管理: 1. 模型加载, 基于
Service Worker
缓存TensorFlow
模型文件和相关的JavaScript
库,并控制缓存的版本, 可以保证在首次加载时从网络加载资源,并在后续加载时优先使用缓存资源,减少网络请求,提升性能和离线可用性,同时通过版本号控制确保更新后的资源被正确加载。2. 模型量化, 指将模型的权重和激活函数从浮点数(通常是32
位浮点数)转换为较低精度的数值(如8
位整数),以减少模型的大小和提高推理速度。通过TensorFlow.js
支持的 模型量化(Quantization
) 技术,将模型大小压缩50%-70%
,降低推理计算负载。3. 模型分片, 将model.json
中的group1-shard1.bin
二进制权重文件分为多个小片,利用浏览器的并发请求能力,更快的加载模型, 这种方式减少单个文件的大小,提高并行加载能力和缓存效率。4. 采用WebGL
后端加速,TensorFlow.js
利用WebGL
后端,在浏览器中实现GPU
加速,提升推理速度。5. 内存管理, 在推理过程中注意释放不再使用的Tensor
,避免内存泄露
二、语法
2.1 NPM
import * as tf from '@tensorflow/tfjs';
// Define a model for linear regression.
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
// Prepare the model for training: Specify the loss and the optimizer.
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
// Generate some synthetic data for training.
const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);
// Train the model using the data.
model.fit(xs, ys).then(() => {
// Use the model to do inference on a data point the model hasn't seen before:
model.predict(tf.tensor2d([5], [1, 1])).print();
});
2.2 Script Tag
<html>
<head>
<!-- Load TensorFlow.js -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js"> </script>
<!-- Place your code in the script tag below. You can also use an external .js file -->
<script>
// Notice there is no 'import' statement. 'tf' is available on the index-page
// because of the script tag above.
// Define a model for linear regression.
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
// Prepare the model for training: Specify the loss and the optimizer.
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
// Generate some synthetic data for training.
const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);
// Train the model using the data.
model.fit(xs, ys).then(() => {
// Use the model to do inference on a data point the model hasn't seen before:
// Open the browser devtools to see the output
model.predict(tf.tensor2d([5], [1, 1])).print();
});
</script>
</head>
<body>
</body>
</html>