视频封面

视频元信息

  • 课程来源:吴恩达深度学习专项课程(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