实用指南:TensorFlow2 Python深度学习 - TensorFlow2框架入门 - 自动微分和梯度

news/2025/11/9 18:10:23/文章来源:https://www.cnblogs.com/ljbguanli/p/19204628

实用指南:TensorFlow2 Python深度学习 - TensorFlow2框架入门 - 自动微分和梯度

锋哥原创的TensorFlow2 Python深度学习视频教程:

https://www.bilibili.com/video/BV1X5xVz6E4w/

课程介绍

本课程主要讲解基于TensorFlow2的Python深度学习知识,包括深度学习概述,TensorFlow2框架入门知识,以及卷积神经网络(CNN),循环神经网络(RNN),生成对抗网络(GAN),模型保存与加载等。

TensorFlow2 Python深度学习 - TensorFlow2框架入门 - 自动微分和梯度

学习这节课之前,大家要会基本的微积分知识。

TensorFlow 2 中,自动微分(automatic differentiation)是计算梯度的一种技术,它用于优化模型参数,比如在训练神经网络时通过梯度下降法更新参数。

自动微分(Autodiff)和梯度的定义和关系
  1. 梯度 是指函数对其输入变量的导数,它描述了函数在某点的变化速率。在机器学习中,梯度通常指的是损失函数对模型参数(如权重)的导数。

  2. 自动微分 是一种通过计算图来自动求取梯度的技术。TensorFlow 2 通过 tf.GradientTape 来实现自动微分,它可以追踪操作并计算梯度。使用这种方式,可以高效地进行反向传播,进而计算损失函数对每个参数的梯度。

如何理解这个过程:
  • 正向传播:在训练过程中,首先会通过模型的前向计算(正向传播)得到预测输出和损失。

  • 自动微分:然后,TensorFlow 2 使用 tf.GradientTape 跟踪这个过程,以便在反向传播时可以自动计算每个参数的梯度。

  • 反向传播:通过反向传播算法(backpropagation),自动微分计算损失函数相对于模型参数的梯度(即每个参数的偏导数)。

一个简单的示例:
import tensorflow as tf
​
# 定义一个简单的函数
def f(x):   return x ** 2
​
# 使用 GradientTape 自动计算梯度
x = tf.Variable(3.0)
with tf.GradientTape() as tape:   y = f(x)  # 正向计算 f(x) = x^2
​
# 计算 f(x) 对 x 的梯度
grad = tape.gradient(y, x)
print(grad)

运行结果:

tf.Tensor(6.0, shape=(), dtype=float32)

开发一个简单线性模型:

解决一个机器学习问题通常包含以下步骤:

  • 获得训练数据。

  • 定义模型。

  • 定义损失函数。

  • 遍历训练数据,从目标值计算损失。

  • 计算该损失的梯度,并使用optimizer调整变量以适合数据。

  • 计算结果。

为了便于说明,在本指南中,您将开发一个简单的线性模型, f(x)=x∗W+b, 其中包含两个变量: W (权重) 和 b (偏差)。

这是最基本的机器学习问题:给定 x 和 y,尝试通过简单的线性回归来找到直线的斜率和偏移量。

这里用到数据可视化,我们先安装下matplotlib库

pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple

以及jupyter notebook

pip install jupyter -i https://pypi.tuna.tsinghua.edu.cn/simple

1,数据准备
from matplotlib import pyplot as plt
import tensorflow as tf
​
# 设置matplotlib使用黑体显示中文
matplotlib.rcParams['font.family'] = 'Microsoft YaHei'
​
# 正确的权重和偏置
TRUE_W = 3.0
TRUE_B = 2.0
​
NUM_EXAMPLES = 201
​
# 在区间[-2, 2]内生成NUM_EXAMPLES个均匀分布的数值点
x = tf.linspace(-2, 2, NUM_EXAMPLES)
x = tf.cast(x, tf.float32)
​
​
def f(x):   return x * TRUE_W + TRUE_B
​
​
# 生成随机噪声数据
noise = tf.random.normal(shape=[NUM_EXAMPLES])
​
# 计算y
y = f(x) + noise
​
plt.plot(x, y, '.')
plt.show()

运行结果:

2,定义模型
class MyModel(tf.Module):   def __init__(self, **kwargs):       super().__init__(**kwargs)       # 将权重初始化为5.0,偏置初始化为0.0       # 在实际应用中,这些参数应该被随机初始化       self.w = tf.Variable(5.0)       self.b = tf.Variable(0.0)
​   def __call__(self, x):       return self.w * x + self.b
​
​
model = MyModel()
​
# 输出模型参数
print("Variables:", model.variables)

运行输出:

Variables: (, )

3,定义损失函数

损失函数衡量给定输入的模型输出与目标输出的匹配程度。目的是在训练过程中尽量减少这种差异。定义标准的L2损失,也称为“均方误差”:

# 定义损失函数(均方误差)
def loss(target_y, predicted_y):   return tf.reduce_mean(tf.square(target_y - predicted_y))
​
plt.plot(x, y, '.', label="数据")
plt.plot(x, f(x), label="真实值")
plt.plot(x, model(x), label="预测值")
plt.legend()
plt.show()
​
print("当前损失值: %1.6f" % loss(y, model(x)).numpy())

在训练模型之前,您可以可视化损失值。使用橙色绘制模型的训练数据真实值,使用蓝色绘制模型预测数据。

4,定义训练循环

训练循环按顺序重复执行以下任务:

  • 发送一批输入值,通过模型生成输出值

  • 通过比较输出值与输出(标签),来计算损失值

  • 使用梯度带(GradientTape)找到梯度值

  • 使用这些梯度优化变量

定义训练模型:

# 定义训练模型,参数是一个可调用的模型、输入、输出和学习率。..
def train(model, x, y, learning_rate):   with tf.GradientTape() as t:       # GradientTape自动跟踪可训练变量       current_loss = loss(y, model(x))
​   # 使用GradientTape计算关于权重W和偏置b   dw, db = t.gradient(current_loss, [model.w, model.b])
​   # 减去按学习率缩放的梯度   model.w.assign_sub(learning_rate * dw)   model.b.assign_sub(learning_rate * db)

tape.gradient 方法用于计算某个张量相对于另一个张量的梯度。

tape.gradient(target, sources, unconnected_gradients=tf.UnconnectedGradients.NONE)

参数说明:

  1. target:

    • 目标张量,即你想要计算梯度的结果张量,通常是一个标量(如损失函数值)。

  2. sources:

    • 来源张量,通常是你希望对其求梯度的变量(如模型的权重)。它可以是一个张量、一个张量列表或一个张量的集合。

  3. unconnected_gradients (可选):

    • 用于处理图中没有连接的变量的方式。可以有三个选项:

      • tf.UnconnectedGradients.NONE(默认值):忽略没有连接的梯度。

      • tf.UnconnectedGradients.ZERO: 将未连接的梯度视为零。

      • tf.UnconnectedGradients.WARNING: 如果存在未连接的梯度,则会抛出警告。

返回值:

  • tape.gradient 返回一个张量或张量列表,表示对应来源张量的梯度。如果 sources 是多个张量,它将返回一个梯度列表。

要查看训练,您可以通过训练循环发送同一批次的 xy,并观察 Wb 如何变化。

# 实例化一个模型
model = MyModel()
​
# 定义变量,收集W值和b值的历史数据,以便后续绘图
weights = []
biases = []
# 训练10轮
epochs = range(10)
​
​
# 定义一个报告函数
def report(model, loss):   return f"W = {model.w.numpy():1.2f}, b = {model.b.numpy():1.2f}, loss={loss:2.5f}"
​
​
# 定义一个训练循环
def training_loop(model, x, y):   for epoch in epochs:       # 使用单个大批次更新模型       train(model, x, y, learning_rate=0.1)
​       # 在我更新之前追踪权重和偏置       weights.append(model.w.numpy())       biases.append(model.b.numpy())       current_loss = loss(y, model(x))
​       print(f"第{epoch + 1:2d}轮:")       print("    ", report(model, current_loss))

5,进行训练
current_loss = loss(y, model(x))
​
print(f"开始:")
print("    ", report(model, current_loss))
​
training_loop(model, x, y)

运行输出:

开始:    W = 5.00, b = 0.00, loss=10.10720
第 1轮:    W = 4.46, b = 0.38, loss=6.28441
第 2轮:    W = 4.07, b = 0.69, loss=4.10408
第 3轮:    W = 3.78, b = 0.93, loss=2.85083
第 4轮:    W = 3.57, b = 1.13, loss=2.12463
第 5轮:    W = 3.42, b = 1.28, loss=1.70038
第 6轮:    W = 3.30, b = 1.41, loss=1.45049
第 7轮:    W = 3.22, b = 1.51, loss=1.30211
第 8轮:    W = 3.16, b = 1.59, loss=1.21331
第 9轮:    W = 3.12, b = 1.65, loss=1.15977
第10轮:    W = 3.09, b = 1.71, loss=1.12726

6,权重和偏置演变可视化
plt.plot(epochs, weights, label='模型演变权重', color='blue')
plt.plot(epochs, [TRUE_W] * len(epochs), '--',        label="真实权重", color='blue')
​
plt.plot(epochs, biases, label='模型演变偏置', color='red')
plt.plot(epochs, [TRUE_B] * len(epochs), "--",        label="真实偏置", color='red')
​
plt.legend()
plt.show()

运行结果:

7,模型性能可视化
plt.plot(x, y, '.', label="数据")
plt.plot(x, f(x), label="真实值")
plt.plot(x, model(x), label="预测值")
plt.legend()
plt.show()
​
print("当前损失值: %1.6f" % loss(model(x), y).numpy())

经过训练,明显接近真实值。只要进行足够的训练,就越接近真实值。

总结:
  • 梯度 是损失函数对模型参数的导数。

  • 自动微分 是一种计算梯度的技术,TensorFlow 2 通过 tf.GradientTape 来实现这一点。

  • 通过 tf.GradientTape,你可以很方便地计算出任何函数(如神经网络损失函数)相对于其参数的梯度,这样可以直接用于优化算法(如梯度下降法)来训练模型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/960629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浏览器Blockstack.org全名字段输入限制缺失漏洞分析

本文详细分析了Blockstack浏览器端全名字段缺乏输入长度限制导致的服务中断风险,包括漏洞发现过程、安全影响评估以及开发团队与安全研究员的讨论过程。漏洞报告 #304073 - browser.blockstack.org 全名字段字符串大小…

2025年维修厂家推荐排行榜单:行业权威解析

摘要 随着制冷行业在2025年的快速发展,维修厂家在保障设备高效运行中扮演关键角色。本文基于行业数据和用户口碑,解析2025年维修厂家排行榜单,重点推荐优质服务商,并提供详细表单供参考,帮助用户选择可靠的合作伙…

2025年维修厂家口碑排行榜:专业制冷服务首选

摘要 2025年维修厂家行业正迎来技术革新与市场需求增长,制冷设备维修服务成为关键领域。本文基于行业数据与用户反馈,推出维修厂家推荐排行榜单,旨在帮助用户选择靠谱的合作伙伴。榜单涵盖口碑、实力、服务等多维度…

行业内专业的维修厂家功能亮点

摘要 随着制冷行业的快速发展,2025年维修厂家市场呈现出技术升级和服务多元化的趋势。本文基于行业数据和用户口碑,解析维修厂家的核心功能亮点,并提供一份权威的维修厂家推荐排行榜单,供用户参考选择。表单排名综…

Dask-权威指南-全-

Dask 权威指南(全)原文:annas-archive.org/md5/4f64056c14690c5478291f8391f41fa7 译者:飞龙 协议:CC BY-NC-SA 4.0第一章:理解 Dask DataFrames 的架构 Dask DataFrames 允许您扩展您的 pandas 工作流。Dask Da…

DevOps-文化中的协作指南-全-

DevOps 文化中的协作指南(全)原文:zh.annas-archive.org/md5/747ac673186de3c38ee667bd2f54b035 译者:飞龙 协议:CC BY-NC-SA 4.0序言 本书面向已经建立起领导地位以及正在走向领导地位的人士。它专注于有效协作—…

WGCLOUD磁盘告警有没有恢复通知

有的 WGCLOUD磁盘告警后,如果我们处理后,系统也会发送恢复通知

疑似 CSP-SB、CSP-JB、NOSb 考题泄露

每日一题,防止变蠢[!] NOSb 考题。 [?] CSP-JB 考题。 [.] CSP-SB 考题。 这种代码难度很低的清新小题还是很有意思的。[?] \(\text{mex}\times \min\)。[?] 树的边双连通分量。[?] 对于 \(n\le 10^5\) 的点 \(11…

人工智能团队的技术工具

人工智能团队的技术工具

C++之开始学习C++(二) - Invinc

本文记录了初步学习C++时容易遗忘的一些知识。本文记录了初步学习C++时容易遗忘的一些知识。“没有”main() 的例外程序在 Windows 编程中,可以编写一个动态链接库 (DLL) 模块,这是其他 Windows程序可以使用的代码。…

如何禁止谷歌浏览器更新提示

在快捷方式的目标中加入 --disable-background-networking重启浏览器即可

Azure-Arc-支持的面向多云的-Kubernetes-指南-全-

Azure Arc 支持的面向多云的 Kubernetes 指南(全)原文:zh.annas-archive.org/md5/d59529b1ef4e2848b60fd4981536534c 译者:飞龙 协议:CC BY-NC-SA 4.0前言 在科技和云计算领域,包括多云、容器、Kubernetes 和 De…

拓扑 AC 2025 线上 NOIP 联测 #2

100 + 25 + 10 + 0 = 135, Rank 7/19.久违的罚坐。[2025线上NOIP联测第三阶段] 模拟赛 2 链接:link 题解:暂无 时间:4.5h (2025.11.08 13:00~17:30) 题目数:4 难度:A B C D\(\color{#FFC116} 黄\)*1300估分:100 …

04--CSS基础(3) - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

P14462 【MX-S10-T3】『FeOI-4』寻宝游戏

P14462 【MX-S10-T3】『FeOI-4』寻宝游戏 P14462 【MX-S10-T3】『FeOI-4』寻宝游戏 - 洛谷 (luogu.com.cn) 分类讨论。\(len\ge 3\)。 找到一个目标桶 \(x\),把剩下的都扔进去。 设剩下的桶之中,个数和为 \(sum\),最…

完整教程:FocusAny 发布v1.1.0 插件搜索过滤,FAD文件优化,插件显示MCP服务

完整教程:FocusAny 发布v1.1.0 插件搜索过滤,FAD文件优化,插件显示MCP服务pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fam…

11.9 模拟赛 T3

题意:将 \(n\) 个线段分成恰好 \(m\) 组,每个线段需要且只能分进一组。求这 \(m\) 组线段合法的得分之和最大是多少。一组线段的得分定义为它们的交的长度(区间长度为右端点减左端点)。一个方案合法,当且仅当每组…

CSP2025游记

早上到考场发现那一层两个考场一共就看到两种校服。今年好像不是按姓名字典序排的 J组 挺水的 T1 简单切了 T2 简单切了 T3 想了一会,切了 T4 想了一会,以为自己切了 赛后发现没开滚动数组好像会爆空间($512 \times…

深入解析:从零构建鸿蒙高效数据恢复工具:完整实战教程与可运行Demo

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …