深入理解 TensorFlow2 五层层次结构:硬件层、内核层与低/中/高阶 API 的建模实践
2026/9/24 20:26:32 网站建设 项目流程
  • 教程
  • 深度学习
  • 机器学习

【免费下载链接】eat_tensorflow2_in_30_days

Tensorflow2.0 🍎🍊 is delicious, just eat it! 😋😋

项目地址:https://gitcode.com/gh_mirrors/ea/eat_tensorflow2_in_30_days
点击查看免费下载

本章导读:本文以开源教程仓库 eat_tensorflow2_in_30_days 的 Chapter 3: Hierarchy of TensorFlow 为骨架,系统讲解 TensorFlow 自底向上的五层结构——硬件层、C++ 内核层、低阶 API、中阶 API、高阶 API,并分别用线性回归与 DNN 二分类两个模型,直观对比同一任务在不同层级下的实现方式。读完本文,你将掌握各层 API 的定位、核心接口清单(tf.Variabletf.GradientTapetf.data.Datasettf.keras.layerstf.keras.models等),并能根据场景选择适合自己的建模层级。

TensorFlow 的层次结构从低到高可以分成五层。如果把模型比作一栋房子,那么低阶 API 是【模型之砖】,中阶 API 是【模型之墙】,高阶 API 就是【模型之屋】本身。

一、五层结构的全景图

层级名称实现语言主要内容类比
第 1 层硬件层——CPU、GPU、TPU 加入计算资源池地基
第 2 层内核层C++跨平台分布的 kernel 算子建材
第 3 层低阶 APIPython张量操作算子、计算图、自动微分模型之砖
第 4 层中阶 APIPython模型层、损失函数、优化器、数据管道、特征列模型之墙
第 5 层高阶 APIPythontf.keras.models提供的模型类接口模型之屋

1. 第 1 层:硬件层

最底层为硬件层。TensorFlow 支持将 CPU、GPU 或 TPU 加入计算资源池,同一份代码可以通过设备指定在不同硬件上运行。这一层是性能的基础——项目在 第 6 章 中分别演示了单 GPU(6-3)、多 GPU(6-4)与 TPU(6-5)三种训练方式,正是对硬件层能力的直接使用。

2. 第 2 层:C++ 内核层

第二层为 C++ 实现的内核(kernel)。这些内核可以跨平台分布运行,是真正执行数值计算的部分。TensorFlow 的计算模型是数据流图:图中的节点代表算子,边代表节点间依赖关系(实线表示带张量数据传递的数据依赖,虚线表示控制依赖)。从源码结构看,Python 侧 API 最终都会落到这一层的 C++ 算子上执行。

3. 第 3 层:低阶 API(模型之砖)

第三层为 Python 实现的操作符,对 C++ 内核做了封装,提供低阶 API 指令,主要包括:

  • 各种张量操作算子:tf.Variabletf.constant
  • 计算图:tf.function
  • 自动微分:tf.GradientTape
  • 各类算子:tf.nn.softmax

如果把模型比作一个房子,那么第三层 API 就是【模型之砖】——所有更高层的组件都由它们拼装而来。低阶 API 的核心能力(张量结构操作、数学运算、AutoGraph、自动微分)在 第 4 章 的 4-1、4-2、4-3、4-4、4-5 中有详细展开。

4. 第 4 层:中阶 API(模型之墙)

第四层为 Python 实现的模型组件,对低阶 API 进行了函数封装,主要包括:

  • 模型层:tf.keras.layers
  • 损失函数:tf.keras.losses
  • 评估指标:tf.keras.metrics
  • 优化器:tf.keras.optimizers
  • 数据管道:tf.data.Dataset
  • 特征列:tf.feature_column

如果把模型比作一个房子,那么第四层 API 就是【模型之墙】。这一层的 8 大组件(数据管道、特征列、激活函数、模型层、损失函数、评估指标、优化器、回调函数)在 第 5 章 的 5-1 至 5-8 中逐一讲解。

5. 第 5 层:高阶 API(模型之屋)

第五层为 Python 实现的模型成品,一般是按照 OOP(面向对象)方式封装的高级 API,主要为tf.keras.models提供的模型类接口。tf.keras.models.Modeltf.keras.layers.Layer实际上都继承自tf.Module(可通过issubclass(tf.keras.Model, tf.Module)验证,返回 True),它们统一管理变量与子模块。如果说前三层提供的是砖和墙,这一层交付的就是可以直接居住的【模型之屋】。

二、同一个线性回归模型,三种层级的写法对比

Chapter3-1、Chapter3-2、Chapter3-3 三篇子章节使用完全相同的数据生成方式同一个线性回归任务,分别用低阶、中阶、高阶 API 实现。这是理解层级差异的最佳素材。

数据准备(三篇共用):

import tensorflow as tf n = 400 X = tf.random.uniform([n,2],minval=-10,maxval=10) w0 = tf.constant([[2.0],[-3.0]]) b0 = tf.constant([[3.0]]) Y = X@w0 + b0 + tf.random.normal([n,1],mean = 0.0,stddev= 2.0) # @ 为矩阵乘法,并叠加高斯噪声

真实模型为Y = X·w0 + b0(w0 = [2, -3],b0 = 3),加噪声后用于回归训练。

1. 低阶 API:手写参数与梯度更新

低阶方案在 3-1 中,需要手工定义变量、模型、损失函数与更新规则:

# 手工初始化可训练变量 w = tf.Variable(tf.random.normal(w0.shape)) b = tf.Variable(tf.zeros_like(b0,dtype = tf.float32)) # 用类封装模型的前向计算与损失 class LinearRegression: def __call__(self,x): return x@w + b def loss_func(self,y_true,y_pred): return tf.reduce_mean((y_true - y_pred)**2/2) model = LinearRegression() # 手写一步训练:自动微分 + 梯度下降 def train_step(model, features, labels): with tf.GradientTape() as tape: predictions = model(features) loss = model.loss_func(labels, predictions) dloss_dw,dloss_db = tape.gradient(loss,[w,b]) # 反向传播求梯度 w.assign(w - 0.001*dloss_dw) # 手工实现梯度下降(学习率 0.001) b.assign(b - 0.001*dloss_db) return loss

注意这里没有使用任何优化器,学习率、参数更新全部手工完成;数据读取也是用生成器data_iter手工 shuffle 与 batch。训练 200 轮后,w 收敛到约 [1.98, -2.98],b 收敛到约 3.01,接近真实值。

在动态图下调试通过后,可以给train_step加上@tf.function装饰器,由 AutoGraph 将动态图转换为静态图获得加速(详见 2-2 三种计算图)。

2. 中阶 API:引入数据管道与优化器

中阶方案在 3-2 中,数据读取交给tf.data.Dataset,损失与优化交给现成函数:

from tensorflow.keras import layers,losses,metrics,optimizers # 数据管道:切片 → 打乱 → 分批 → 预取 ds = tf.data.Dataset.from_tensor_slices((X,Y)) \ .shuffle(buffer_size = 100).batch(10) \ .prefetch(tf.data.experimental.AUTOTUNE) # 直接使用 Dense 层(自动创建 w、b 变量) model = layers.Dense(units = 1) model.build(input_shape = (2,)) # 用 build 创建变量 model.loss_func = losses.mean_squared_error model.optimizer = optimizers.SGD(learning_rate=0.001) @tf.function def train_step(model, features, labels): with tf.GradientTape() as tape: predictions = model(features) loss = model.loss_func(tf.reshape(labels,[-1]), tf.reshape(predictions,[-1])) grads = tape.gradient(loss,model.variables) model.optimizer.apply_gradients(zip(grads,model.variables)) # 优化器代劳参数更新 return loss

与低阶版相比:tf.data.Dataset用声明式管道替代手写生成器;layers.Dense替代手工变量;optimizers.SGDapply_gradients替代w.assign(...)。梯度计算仍显式保留(tf.GradientTape),这是中阶与低阶共享的"砖"。

3. 高阶 API:一行 fit 完成训练

高阶方案在 3-3 中,建模与训练全部封装进 Keras 高层接口:

from tensorflow.keras import models,layers tf.keras.backend.clear_session() model = models.Sequential() model.add(layers.Dense(1,input_shape =(2,))) model.summary() # 输出: dense (Dense) Output Shape (None, 1) Param # 3 model.compile(optimizer="adam",loss="mse",metrics=["mae"]) model.fit(X,Y,batch_size = 10,epochs = 200)

200 轮训练后w = [[1.99339032], [-3.00866461]]b = [2.67018795],与低阶、中阶结果一致——三种层级殊途同归。区别在于:低阶版需要理解梯度、变量、自动微分;中阶版需要理解数据管道与优化器;高阶版只需要声明式地compile+fit,学习门槛最低。

三、DNN 二分类:从低阶到高阶的复杂度迁移

三篇子章节还用同一个"双环"二分类数据集(内环半径 5、外环半径 8 的 4000 个样本,用tf.random.truncated_normal加噪声、tf.cos/tf.sin生成)实现了 DNN 二分类,网络结构统一为 2→4→8→1,激活函数为 relu + sigmoid。

1. 低阶版:用 tf.Module 手工组织 6 个变量

低阶版在 3-1 中直接用tf.Module组织参数(tf.Module的用法详见 4-5 AutoGraph 和 tf.Module):

class DNNModel(tf.Module): def __init__(self,name = None): super(DNNModel, self).__init__(name=name) self.w1 = tf.Variable(tf.random.truncated_normal([2,4]),dtype = tf.float32) self.b1 = tf.Variable(tf.zeros([1,4]),dtype = tf.float32) self.w2 = tf.Variable(tf.random.truncated_normal([4,8]),dtype = tf.float32) self.b2 = tf.Variable(tf.zeros([1,8]),dtype = tf.float32) self.w3 = tf.Variable(tf.random.truncated_normal([8,1]),dtype = tf.float32) self.b3 = tf.Variable(tf.zeros([1,1]),dtype = tf.float32) @tf.function(input_signature=[tf.TensorSpec(shape = [None,2], dtype = tf.float32)]) def __call__(self,x): x = tf.nn.relu(x@self.w1 + self.b1) x = tf.nn.relu(x@self.w2 + self.b2) y = tf.nn.sigmoid(x@self.w3 + self.b3) return y # 二分类交叉熵(手工实现,并用 clip 防止 log(0)) @tf.function(input_signature=[tf.TensorSpec(shape = [None,1], dtype = tf.float32), tf.TensorSpec(shape = [None,1], dtype = tf.float32)]) def loss_func(self,y_true,y_pred): eps = 1e-7 y_pred = tf.clip_by_value(y_pred,eps,1.0-eps) bce = - y_true*tf.math.log(y_pred) - (1-y_true)*tf.math.log(1-y_pred) return tf.reduce_mean(bce) @tf.function(input_signature=[tf.TensorSpec(shape = [None,1], dtype = tf.float32), tf.TensorSpec(shape = [None,1], dtype = tf.float32)]) def metric_func(self,y_true,y_pred): y_pred = tf.where(y_pred>0.5,tf.ones_like(y_pred,dtype = tf.float32), tf.zeros_like(y_pred,dtype = tf.float32)) acc = tf.reduce_mean(1-tf.abs(y_true-y_pred)) return acc

由于继承tf.Module,模型可通过model.trainable_variables自动收集全部 6 个可训练变量,训练循环用tape.gradient(loss, model.trainable_variables)一次性求梯度、再逐个p.assign(p - 0.001*dloss_dp)更新。600 轮后准确率约 0.96。

2. 中阶版:Dense 层替代手工矩阵

中阶版在 3-2 中网络结构不变,但三组手工w/b变量被三个layers.Dense层替代,激活函数、损失、指标全部改用现成接口:

class DNNModel(tf.Module): def __init__(self,name = None): super(DNNModel, self).__init__(name=name) self.dense1 = layers.Dense(4,activation = "relu") self.dense2 = layers.Dense(8,activation = "relu") self.dense3 = layers.Dense(1,activation = "sigmoid") @tf.function(input_signature=[tf.TensorSpec(shape = [None,2], dtype = tf.float32)]) def __call__(self,x): x = self.dense1(x) x = self.dense2(x) y = self.dense3(x) return y model = DNNModel() model.loss_func = losses.binary_crossentropy model.metric_func = metrics.binary_accuracy model.optimizer = optimizers.Adam(learning_rate=0.001)

训练时model.optimizer.apply_gradients(zip(grads,model.trainable_variables))完成更新,数据管道改为tf.data.Dataset.from_tensor_slices((X,Y)).shuffle(4000).batch(100).prefetch(AUTOTUNE)。仅 60 轮就达到 0.95 准确率(Adam 优化器 + 更成熟的封装带来的收敛效率差异)。

3. 高阶版:继承 Model + 自定义训练循环

高阶版在 3-3 中采用两种 Keras 风格:线性回归用Sequential+fit(入门用法),DNN 用继承models.Model的类 + 自定义训练循环(进阶用法),并引入了tf.keras.metrics.Meantf.keras.metrics.BinaryAccuracy这类有状态指标(用update_state/result/reset_states管理),同时把数据集划分为训练集与验证集(ds_train/ds_valid)。1000 轮后训练准确率约 0.959、验证准确率约 0.935。

四、三种层级的选型对照

维度低阶 API(第 3 层)中阶 API(第 4 层)高阶 API(第 5 层)
典型接口tf.Variabletf.GradientTapetf.functiontf.data.Datasettf.keras.layerstf.keras.optimizerstf.keras.modelsmodel.fit
参数管理手工定义并维护层对象自动管理Model 自动管理
梯度更新手工assign优化器apply_gradientscompile后由fit完成
训练循环完全手写手写但组件化fit一行 / 自定义循环
灵活度最高低(但可用子类化 Model 保留灵活性)
适用人群框架研究者、自定义算子/训练逻辑常规工业项目快速原型、标准建模流程

从源码结构看,三层是层层包裹的关系:高阶 API 内部依赖中阶组件,中阶组件内部由低阶算子与tf.Module拼装而成。因此,掌握低阶 API 并不是"过时"的学习——它决定了你能在多大程度上驾驭tf.functiontf.GradientTapetf.Module这些整个框架的地基。

五、五层结构与教程章节地图

本仓库按五层结构组织教程(见 SUMMARY_eng.md 的目录树),各层对应的深入学习入口:

  • 第 1 层 硬件层:Chapter 6 → 6-3 单 GPU、6-4 多 GPU、6-5 TPU
  • 第 2 层 内核层:贯穿各章的算子执行,可通过 2-2 三种计算图 了解图执行模型
  • 第 3 层 低阶 API:Chapter 4 → 4-1 张量结构操作、4-2 张量数学运算、4-3 AutoGraph 使用规范、4-4 AutoGraph 机制原理、4-5 AutoGraph 和 tf.Module
  • 第 4 层 中阶 API:Chapter 5 → 5-1 数据管道 Dataset、5-2 特征列、5-3 激活函数、5-4 模型层、5-5 损失函数、5-6 评估指标、5-7 优化器、5-8 回调函数
  • 第 5 层 高阶 API:Chapter 6 → 6-1 构建模型的 3 种方法、6-2 训练模型的 3 种方法

需要说明的是:教程全部代码在 TensorFlow 2.1 环境下测试通过(见 README_eng.md 的环境说明),不同小版本间的 API 细节可能略有差异,运行示例时请以本机 TensorFlow 版本的实际行为为准。

结语

TensorFlow 的五层结构是一个"由地基到成品"的完整技术栈:硬件层提供算力,C++ 内核层提供跨平台算子,Python 低阶 API 提供砖块,中阶 API 砌成墙,高阶 API 交付房屋。通过线性回归与 DNN 二分类这两个贯穿全文的示例,可以直观体会到:任务不变,变的是封装程度与学习曲线。日常开发中建议以中阶/高阶 API 为默认选择、以低阶 API 为疑难场景的兜底手段,而理解五层结构本身,正是驾驭 TensorFlow2 的关键一步。

  • 教程
  • 深度学习
  • 机器学习

【免费下载链接】eat_tensorflow2_in_30_days

Tensorflow2.0 🍎🍊 is delicious, just eat it! 😋😋

项目地址:https://gitcode.com/gh_mirrors/ea/eat_tensorflow2_in_30_days
点击查看免费下载

相关推荐

上一篇:AduSkin WPF美化控件库:5分钟搞定现代化界面设计终极指南
下一篇:如何为OPNsense开源项目做贡献:新手入门终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询