
视频元信息
- 课程来源:吴恩达深度学习专项课程(Deep Learning Specialization)
- 所属章节:Professionalization of Deep Learning - 3.11 TensorFlow
- 语言:英文讲解,中英字幕
内容摘要(TL;DR)
本视频通过一个极简的二次代价函数 J(w) = w² - 10w + 25 的最小化实例,系统讲解 TensorFlow 程序的基本结构。核心要点包括:使用 tf.Variable 定义可训练参数、使用 tf.GradientTape 自动记录前向计算并自动求导、使用优化器(如 Adam)自动更新参数。视频还介绍了如何将训练数据引入计算图,以及 optimizer.minimize() 的简化写法。最终目标是让学习者理解 TensorFlow 的核心优势——只需实现前向传播,框架自动完成反向传播。
一、课程引入与动机 [00:00]
- 深度学习编程框架可以大幅提升开发和部署深度学习算法的效率。
- TensorFlow 是其中一个主流框架。
- 本视频目标:逐步讲解 TensorFlow 程序的基本结构,帮助学习者自己实现神经网络。
- 本周编程练习需要额外时间,建议提前规划。
重点:本周编程练习所需时间较多,请合理安排时间完成。
二、动机问题:最小化简单代价函数 [00:47]
2.1 问题定义
选取一个高度简化的代价函数作为示例:
J(w) = w² - 10w + 25
理解:这个函数实际上可以因式分解为 (w - 5)²,因此最小值为 w = 5。
2.2 为什么用这个例子
- 推导:该二次函数展开后为 w² - 10w + 25 = (w - 5)²,当 w = 5 时取最小值 0。
- 考点:虽然我们知道答案是 w = 5,但重点是演示 TensorFlow 如何自动找到这个最小值。
- 类似的程序结构可以推广到训练神经网络——代价函数 J(w, b) 依赖于神经网络的所有参数,TensorFlow 可以自动找到使代价函数最小的 w 和 b。
三、TensorFlow 基本程序结构(第一部分) [01:55]
3.1 导入库
import numpy as np
import tensorflow as tf
- 考点:
import tensorflow as tf是业界惯用写法,几乎所有 TensorFlow 代码都这样导入。
3.2 定义可训练参数
w = tf.Variable(0, dtype=tf.float32)
- 使用
tf.Variable()声明这是一个可训练变量。 - 初始值为 0,类型为 float32。
- 重点:w 是你要优化的参数,所以必须声明为 Variable。
3.3 定义优化算法
optimizer = tf.keras.optimizers.Adam(learning_rate=0.1)
- 使用 Adam 优化算法,学习率设为 0.1。
- 拓展:Adam(Adaptive Moment Estimation)是一种自适应学习率优化算法,结合了动量法和 RMSProp 的优点,在实际深度学习任务中非常常用。
3.4 定义代价函数
def cost_fn():
return w**2 - 10*w + 25
- 重点:TensorFlow 的核心优势——你只需要实现计算代价函数的前向传播代码,TensorFlow 会自动计算梯度(反向传播)。
四、GradientTape 自动求导机制 [03:42]
4.1 语法结构
with tf.GradientTape() as tape:
cost = w**2 - 10*w + 25
grads = tape.gradient(cost, [w])
4.2 工作原理(磁带类比)
- 理解:GradientTape 的直觉来源于老式盒式磁带。
- 前向传播时:磁带记录计算代价函数的所有操作序列。
- 反向播放时:磁带倒序回放操作序列,沿途自动计算反向传播和梯度。
- 考点:这就是为什么 TensorFlow 中只需实现前向传播(forward prop),框架自动完成反向传播(backprop)。
4.3 定义训练步骤
trainable_variables = [w]
def train_step():
with tf.GradientTape() as tape:
cost = w**2 - 10*w + 25
grads = tape.gradient(cost, trainable_variables)
optimizer.apply_gradients(zip(grads, trainable_variables))
trainable_variables是一个包含 w 的列表。tape.gradient(cost, trainable_variables)计算代价函数对可训练变量的梯度。optimizer.apply_gradients()应用梯度更新参数。- 重点:
zip()是 Python 内置函数,将梯度列表和可训练变量列表对应元素配对。
易错点:
zip(grads, trainable_variables)中两个列表的元素必须一一对应,顺序不能错。
五、运行训练与结果验证 [05:28]
5.1 初始状态
- 打印 w 的初始值:0(与初始化一致)。
5.2 运行一步训练
train_step()
print(w)
- 运行一步后,w 从 0 变为约 0.1。
- 理解:因为梯度方向指向减小代价函数的方向,学习率为 0.1,所以 w 增加了约 0.1。
5.3 运行 1000 次迭代
for i in range(1000):
train_step()
print(w)
- 结果:w 接近 5,正是该代价函数的最小值点。
- 考点:我们只指定了代价函数,没有手动计算导数,TensorFlow 自动完成了最小化。
六、引入训练数据的 TensorFlow 程序 [07:25]
6.1 问题场景
- 之前的代价函数只依赖于参数 w。
- 实际中,代价函数还依赖于训练数据 (x, y)。
- 问题:如何将训练数据传入 TensorFlow 程序?
6.2 定义数据
x = np.array([1.0, -10.0, 25.0], dtype=np.float32)
- 这三个数 [1, -10, 25] 作为二次代价函数的系数。
- 理解:可以认为 x 是控制二次代价函数系数的"数据"。
6.3 数据驱动的代价函数
def cost_fn():
return x[0]*w**2 + x[1]*w + x[2]
- 与之前的代价函数完全相同,只是系数现在由数据 x 控制。
- 重点:这种结构可以推广到神经网络——代价函数依赖训练数据 (x, y) 和参数 w。
6.4 简化写法:optimizer.minimize()
optimizer.minimize(cost_fn, var_list=[w])
- 考点:
optimizer.minimize()是更简洁的替代写法,等价于 GradientTape + apply_gradients 的组合。 - 一行代码完成梯度计算和参数更新。
6.5 完整训练循环
for i in range(1000):
train_step()
print(w)
- 结果:w 接近 5,与之前一致。
七、计算图与自动微分原理 [12:14]
7.1 计算图(Computation Graph)
- TensorFlow 构建计算图来追踪所有计算操作。
- 以 x[0]w² + x[1]w + x[2] 为例:
- 取 x[0] 和 w
- w 平方 → w²
- x[0] 和 w² 相乘 → x[0]*w²
- 逐步构建,最终计算代价函数
理解:计算图是一种有向无环图(DAG),节点表示操作,边表示数据流动。
7.2 自动反向传播
- 重点:只需实现前向传播(for prop)通过计算图,TensorFlow 自动计算所有必要的反向计算步骤。
- 这就是为什么不需要显式实现反向传播——TensorFlow 自动完成。
- 拓展:这种技术称为自动微分(Automatic Differentiation) ,是深度学习框架的核心能力之一。它不同于符号微分和数值微分,能够高效且精确地计算梯度。
7.3 一行代码切换优化器
# 从 Adam 切换到其他优化器
optimizer = tf.keras.optimizers.SGD(learning_rate=0.1)
- 考点:只需修改一行代码即可快速切换不同的优化算法。
- 所有主流现代深度学习框架都支持这种灵活性。
八、本周课程回顾 [14:25]
- 超参数搜索:系统化组织超参数搜索过程。
- 归一化:使用归一化加速神经网络训练。
- 深度学习编程框架:介绍 TensorFlow 及其基本用法。
- 鼓励完成本周编程练习,加深对这些概念的理解。
九、核心知识点总结
| 概念 | 说明 | 代码 |
|---|---|---|
| 可训练变量 | 需要优化的参数 | tf.Variable(0, dtype=tf.float32) |
| 优化器 | 更新参数的算法 | tf.keras.optimizers.Adam(0.1) |
| 梯度带 | 自动记录计算并求导 | with tf.GradientTape() as tape |
| 梯度计算 | 计算代价对变量的梯度 | tape.gradient(cost, [w]) |
| 应用梯度 | 用优化器更新参数 | optimizer.apply_gradients(zip(grads, vars)) |
| 简化写法 | 一步完成梯度+更新 | optimizer.minimize(cost_fn, var_list=[w]) |
| 计算图 | 记录操作序列的结构 | TensorFlow 自动构建 |
十、注意事项与常见踩坑点
易错点 1:
tf.Variable必须指定dtype,否则可能默认为 float32 但在某些环境下出现类型不匹配。易错点 2:
GradientTape默认只记录一次,如果需要多次求导需设置persistent=True。易错点 3:
zip(grads, trainable_variables)中两个列表顺序必须对应,否则梯度会应用到错误的变量上。易错点 4:学习率设置过大可能导致不收敛,过小则收敛太慢。本例中 0.1 是合适的选择。
十一、拓展补充
【拓展】TensorFlow 与 PyTorch 的对比:
- TensorFlow 使用静态/动态计算图(Eager Execution 后默认动态),PyTorch 使用动态计算图。
- TensorFlow 的 GradientTape 类似于 PyTorch 的
autograd机制。 - 两者都支持自动微分,核心思想一致。
【拓展】Adam 优化器原理:
- 结合了动量(一阶矩估计)和 RMSProp(二阶矩估计)。
- 对学习率进行自适应调整,不同参数有不同的有效学习率。
- 通常默认参数即可取得不错效果,是深度学习中最常用的优化器之一。
【拓展】计算图在神经网络训练中的角色:
- 前向传播:数据从输入层流经隐藏层到输出层,构建计算图。
- 反向传播:沿计算图反向计算梯度,链式法则自动应用。
- 参数更新:优化器根据梯度更新可训练变量。
关键标签/关键词
TensorFlow 自动微分 GradientTape 计算图 优化器 Adam 代价函数 反向传播 前向传播 tf.Variable 深度学习框架 吴恩达 神经网络训练 梯度下降
生成时间:2026-10-10 22:22:33 生成平台:VideoNote www.xygy.top