目录

1. 导数/梯度的理论知识

2. 手撕求导函数

2.1 一元方程

2.2 二元方程

3. 用tensorflow中的库函数完成求导

3.1 一阶函数求导/梯度

3.2 二阶函数求导

4. 梯度下降算法的实现

4.1 手撕梯度下降算法

4.2  使用keras.optimizers.SGD() 中的 apply_gradient特性,完成梯度下降算法


1. 导数/梯度的理论知识

详见博客:梯度下降法(GD,SGD,Mini-Batch GD)在线性回归中的使用_zhao_crystal的博客-CSDN博客_sgd 线性回归本文代码见点击打开链接https://github.com/crystal30/SGDLinrearRegression一.梯度下降法(Batch Gradient Descent)1.梯度下降法的原理(1)梯度下降法是一种基于搜索的最优化方法,不是一个机器学习算法。(2)作用:最小化一个损失函数.扩展:梯度上升法与梯度下降法相反,是最大化一个效用函数。如下图eta太大,得不到最优...https://blog.csdn.net/zhao_crystal/article/details/80472720

相关代码详见:ML2/Gradient-Descent at main · crystal30/ML2 · GitHubhttps://github.com/crystal30/ML2/tree/main/Gradient-Descent

2. 手撕求导函数

2.1 一元方程

def f(x):return 3. * x ** 2 + 2. * x - 1def approximae_derivative(f, x, eps=1e-3):return (f(x + eps) - f(x - eps)) / (2. * eps)print(approximae_derivative(f, 1.))

2.2 二元方程

# 定义二元方程
def g(x1, x2):return (x1 + 5) * (x2 ** 2)# 正确的对二元方程进行求导
def approximae_gradient(g, x1, x2, eps=1e-3):# 使用一元方程的求导函数approximae_derivativedg_x1 = approximae_derivative(lambda x: g(x, x2), x1, eps)dg_x2 = approximae_derivative(lambda x: g(x1, x), x2, eps)return dg_x1, dg_x2print(approximae_gradient(g, 2., 3.))

3. 用tensorflow中的库函数完成求导

3.1 一阶函数求导/梯度

x1 = tf.Variable(2.0)
x2 = tf.Variable(3.0)with tf.GradientTape() as tape:z = g(x1, x2) # g(x1, x2) 在前面定义过dz_x1 = tape.gradient(z, x1)# note:tape执行完一遍之后就会被释放,所以再调用tape就会报错
try:dz_x2 = tape.gradient(z, x2)
except RuntimeError as ex:print(ex)

tape执行完一遍之后就会被释放,遇到n元函数,难道要定义n次tape?

———— 设置tf.GradientTape中的参数 persistent=True

x1 = tf.Variable(2.0)
x2 = tf.Variable(3.0)with tf.GradientTape(persistent=True) as tape:z = g(x1, x2) # g(x1, x2) 在前面定义过dz_x1 = tape.gradient(z, x1)
dz_x2 = tape.gradient(z, x2)
print(dz_x1, dz_x2) # 输出结果和我们手动求导得到的结果一样哦# 手动释放掉 tape
del tape

———— 在求梯度时,一次将所有的变量都传入

x1 = tf.Variable(2.0)
x2 = tf.Variable(3.0)with tf.GradientTape() as tape: # 不设置 persistent=Truez = g(x1, x2) # g(x1, x2) 在前面定义过dz_x1_x2 = tape.gradient(z, [x1, x2]) # 求偏导时,将变量一次性传入
print(dz_x1_x2) # 输出结果和我们手动求导得到的结果一样哦

若函数的变量被赋予具体的数值,被定义为常量————需要使用watch,关注一下该常量

x1 = tf.constant(2.0)
x2 = tf.constant(3.0)with tf.GradientTape() as tape: # 不设置 persistent=True# 和将变量定义为Variable不同的是,需要watchtape.watch(x1)tape.watch(x2)z = g(x1, x2) # g(x1, x2) 在前面定义过dz_x1_x2 = tape.gradient(z, [x1, x2]) # 求偏导时,将变量一次性传入
print(dz_x1_x2) # 输出结果和我们手动求导得到的结果一样哦

对多个函数同时求导

x = tf.Variable(5.0)
with tf.GradientTape() as tape:z1 = 3 * xz2 = x ** 2d_z1_z2 = tape.gradient([z1, z2], x) # 得到 dz1 + dz2
print(d_z1_z2)

3.2 二阶函数求导

x1 = tf.Variable(2.0)
x2 = tf.Variable(3.0)with tf.GradientTape(persistent=True) as outer_tape:with tf.GradientTape(persistent=True) as inner_tape:z = g(x1, x2)inner_grads = inner_tape.gradient(z, [x1, x2])
outer_grads = [outer_tape.gradient(inner_gradient, [x1, x2]) \for inner_gradient in inner_grads]print(outer_grads)del inner_tape
del outer_tape

outer_grads 的输出为[[dz / d(x1)d(x1), dz / d(x1)d(x2)], [dz / d(x2)d(x1), dz / d(x2)d(x2)]]

4. 梯度下降算法的实现

4.1 手撕梯度下降算法

learning_rate = 0.1
x = tf.Variable(0.0)for _ in range(100):with tf.GradientTape() as tape:z = f(x) # f(x) 前面有定义过,为:3. * x ** 2 + 2. * x - 1dz_x = tape.gradient(z, x)x.assign_sub(learning_rate * dz_x) # 梯度下降:x = x - learning_rate - dz_xprint(x)

4.2  使用keras.optimizers.SGD() 中的 apply_gradient特性,完成梯度下降算法

learning_rate = 0.1
x = tf.Variable(0.0)optimizer = tf.optimizers.SGD(learning_rate = learning_rate)for _ in range(100):with tf.GradientTape() as tape:z = f(x) # f(x) 前面有定义过,为:3. * x ** 2 + 2. * x - 1dz_x = tape.gradient(z, x)optimizer.apply_gradients([(dz_x, x)]) # 达到x = x - learning_rate - dz_x的效果print(x)

相关代码详见:

5. 自定义求导在回归问题中的实践

(1)搭建好模型结构之后,batch遍历训练集metric

自动求导,更新参数

(2)每个epoch结束,得到验证集metric

自定义获得批量数据的函数

# 定义自动得到批量数据的函数
def random_batch(x, y, batch_size=32):idx = np.random.randint(0, len(x), size = batch_size)return x[idx], y[idx]

训练模型

epochs = 100
batch_size = 32
steps_per_epoch = len(x_train_scaled) // batch_size
optimizer = keras.optimizers.SGD()
metric = keras.metrics.MeanSquaredError()for epoch in range(epochs):metric.reset_states()# batch 遍历训练集,得到训练集的 metricfor i in range(steps_per_epoch):x_batch, y_batch = random_batch(x_train_scaled, y_train, batch_size=batch_size)with tf.GradientTape() as tape:y_predict = model(x_batch)loss = tf.reduce_mean(keras.losses.mean_squared_error(y_batch, y_predict))metric(y_batch, y_predict)# 自定义求导grads = tape.gradient(loss, model.variables)grads_and_vars = zip(grads, model.variables)# 更新参数optimizer.apply_gradients(grads_and_vars)print("\rEpoch", epoch, " train mse:", metric.result().numpy(), end="")# 每个epoch结束,用验证集合进行验证y_valid_predict = model.predict(x_valid_scaled)valid_loss = tf.reduce_mean(keras.losses.mean_squared_error(y_valid, y_valid_predict))print("\t valid mse:", valid_loss.numpy())

代码详见:

tensorflow基础之——自定义求导相关推荐

  1. AI基础:矩阵求导,你一定要收藏

    不得不说,向量和矩阵真的是一门高深而又通用的学问,应用十分广泛,不信你可以往回看,前面有关线性代数的文章,哪一篇没个矩阵或者向量.所以呢,我们今天就来看一下向量的导数(矩阵求导)相关内容. 1.定义和 ...

  2. 【PyTorch】PyTorch基础知识——自动求导

    1 Autograd简介 PyTorch 中,所有神经网络的核心是 autograd 包.autograd包为张量上的所有操作提供了自动求导机制.它是一个在运行时定义 ( define-by-run ...

  3. Lesson 2.矩阵运算基础、矩阵求导与最小二乘法

    在Lesson 1中,我们介绍了关于机器学习的一般建模流程,并且在基本没有数学公式和代码的情况下,简单介绍了关于线性回归的一般实现形式.不过这只是在初学阶段.为了不增加基础概念理解难度所采取的方法,但 ...

  4. pytorch如何计算导数_Pytorch的自动求导机制与使用方法(一)

    本文以线性模型为例,讲解线性模型的求解的pytorch梯度实现方法. 要注意几个问题:在PyTorch 0.4.0版本之后,Variable类已经被禁用了,所有的torch.Tensor与torch. ...

  5. 矩阵求导公式的数学推导四部曲

    矩阵在线求导 矩阵求导--本质篇 矩阵求导--基础篇 矩阵求导--进阶篇 矩阵求导--补充篇

  6. TensorFlow基础5-可训练变量和自动求导机制

    记录TensorFlow听课笔记 文章目录 记录TensorFlow听课笔记 一,可训练变量 二,TensorFlow的自动求导 一,可训练变量 Variable对象 : 对Tensor对象的进一步封 ...

  7. 深度学习框架 TensorFlow:张量、自动求导机制、tf.keras模块(Model、layers、losses、optimizer、metrics)、多层感知机(即多层全连接神经网络 MLP)

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) 安装 TensorFlow2.CUDA10.cuDNN7.6. ...

  8. tensorflow with求导_3.4tensorflow2.x自动求导原理函数详解

    自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: 1.1  tensorflow2.x自动求导 1.1.1         自动求导GradientTape类 GradientT ...

  9. PyTorch基础(二)-----自动求导Autograd

    一.前言 上一篇文章中提到PyTorch提供了两个重要的高级功能,分别是: 具有强大的GPU加速的张量计算(如NumPy) 包含自动求导系统的的深度神经网络 第一个特性我们会在之后的学习中用到,这里暂 ...

最新文章

  1. js css3实现tab,div+css+js实现tab页
  2. spring5新特性的介绍
  3. A summary of the post “How I explained OOD to my wife
  4. 锁定机制和数据并发管理(笔记)
  5. 主成份分析(PCA)详解
  6. [vue] watch和计算属性有什么区别?
  7. python爬虫有几种方法_python爬虫-----Python访问http的几种方式
  8. 移动HS8545M光猫密码
  9. web前端工程师等级分布
  10. 机器学习之------信号处理(入门原理)
  11. matlab 逐日 变逐月,100多年的逐日数据在EXCEL里用VBA程序求月平均和月求和 - 信息科学 - 小木虫 - 学术 科研 互动社区...
  12. 少有人走的路:心智成熟的旅程
  13. JavaScript九宫格数独生成算法
  14. INFO:ProjectMgmt - The selected process was not run because a prior process failed.的解决方案
  15. Python日报0507 - PyQt5实现打卡登记系统
  16. 【pyqt5】自定义控件 实现能够保持长宽比地缩放子控件
  17. 4个顶级CAD制图软件,对照职业入手哦~
  18. sql语句中as的意思是什么
  19. 面试必备:高频算法题汇总「图文解析 + 教学视频 + 范例代码」必知必会 排序 + 二叉树 部分!
  20. python爬取王者荣耀高清图

热门文章

  1. 为啥我的APP功能引导设计这么low?如何做好功能引导设计?
  2. 【编程实践】第二章 C++面向对象编程《C++程序设计语言》 / By 禅与计算机程序设计艺术ChatGPT
  3. 二进制位运算---左移(<<)右移(>>)
  4. 路由器 FTP 连接异常
  5. 报告合集 | “Cloud XR” 行业报告精选,看这10篇就够了(打包下载)
  6. 计算机网络 期末论文,优秀计算机期末论文选题 计算机期末论文题目怎么拟
  7. js代码中实现页面跳转的几种方式
  8. 怀旧服显示服务器已满,魔兽世界:怀旧服运营满一个月,为什么大部分服务器还是满负载?...
  9. 上海海事大学自动化专业C语言课程代码参考(第七周)
  10. 电子科学和计算机哪个好,计算机科学与技术专业和电子科学与技术专业,哪个好些?...