tensorflow基础之——自定义求导
目录
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基础之——自定义求导相关推荐
- AI基础:矩阵求导,你一定要收藏
不得不说,向量和矩阵真的是一门高深而又通用的学问,应用十分广泛,不信你可以往回看,前面有关线性代数的文章,哪一篇没个矩阵或者向量.所以呢,我们今天就来看一下向量的导数(矩阵求导)相关内容. 1.定义和 ...
- 【PyTorch】PyTorch基础知识——自动求导
1 Autograd简介 PyTorch 中,所有神经网络的核心是 autograd 包.autograd包为张量上的所有操作提供了自动求导机制.它是一个在运行时定义 ( define-by-run ...
- Lesson 2.矩阵运算基础、矩阵求导与最小二乘法
在Lesson 1中,我们介绍了关于机器学习的一般建模流程,并且在基本没有数学公式和代码的情况下,简单介绍了关于线性回归的一般实现形式.不过这只是在初学阶段.为了不增加基础概念理解难度所采取的方法,但 ...
- pytorch如何计算导数_Pytorch的自动求导机制与使用方法(一)
本文以线性模型为例,讲解线性模型的求解的pytorch梯度实现方法. 要注意几个问题:在PyTorch 0.4.0版本之后,Variable类已经被禁用了,所有的torch.Tensor与torch. ...
- 矩阵求导公式的数学推导四部曲
矩阵在线求导 矩阵求导--本质篇 矩阵求导--基础篇 矩阵求导--进阶篇 矩阵求导--补充篇
- TensorFlow基础5-可训练变量和自动求导机制
记录TensorFlow听课笔记 文章目录 记录TensorFlow听课笔记 一,可训练变量 二,TensorFlow的自动求导 一,可训练变量 Variable对象 : 对Tensor对象的进一步封 ...
- 深度学习框架 TensorFlow:张量、自动求导机制、tf.keras模块(Model、layers、losses、optimizer、metrics)、多层感知机(即多层全连接神经网络 MLP)
日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) 安装 TensorFlow2.CUDA10.cuDNN7.6. ...
- tensorflow with求导_3.4tensorflow2.x自动求导原理函数详解
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: 1.1 tensorflow2.x自动求导 1.1.1 自动求导GradientTape类 GradientT ...
- PyTorch基础(二)-----自动求导Autograd
一.前言 上一篇文章中提到PyTorch提供了两个重要的高级功能,分别是: 具有强大的GPU加速的张量计算(如NumPy) 包含自动求导系统的的深度神经网络 第一个特性我们会在之后的学习中用到,这里暂 ...
最新文章
- js css3实现tab,div+css+js实现tab页
- spring5新特性的介绍
- A summary of the post “How I explained OOD to my wife
- 锁定机制和数据并发管理(笔记)
- 主成份分析(PCA)详解
- [vue] watch和计算属性有什么区别?
- python爬虫有几种方法_python爬虫-----Python访问http的几种方式
- 移动HS8545M光猫密码
- web前端工程师等级分布
- 机器学习之------信号处理(入门原理)
- matlab 逐日 变逐月,100多年的逐日数据在EXCEL里用VBA程序求月平均和月求和 - 信息科学 - 小木虫 - 学术 科研 互动社区...
- 少有人走的路:心智成熟的旅程
- JavaScript九宫格数独生成算法
- INFO:ProjectMgmt - The selected process was not run because a prior process failed.的解决方案
- Python日报0507 - PyQt5实现打卡登记系统
- 【pyqt5】自定义控件 实现能够保持长宽比地缩放子控件
- 4个顶级CAD制图软件,对照职业入手哦~
- sql语句中as的意思是什么
- 面试必备:高频算法题汇总「图文解析 + 教学视频 + 范例代码」必知必会 排序 + 二叉树 部分!
- python爬取王者荣耀高清图
热门文章
- 为啥我的APP功能引导设计这么low?如何做好功能引导设计?
- 【编程实践】第二章 C++面向对象编程《C++程序设计语言》 / By 禅与计算机程序设计艺术ChatGPT
- 二进制位运算---左移(<<)右移(>>)
- 路由器 FTP 连接异常
- 报告合集 | “Cloud XR” 行业报告精选,看这10篇就够了(打包下载)
- 计算机网络 期末论文,优秀计算机期末论文选题 计算机期末论文题目怎么拟
- js代码中实现页面跳转的几种方式
- 怀旧服显示服务器已满,魔兽世界:怀旧服运营满一个月,为什么大部分服务器还是满负载?...
- 上海海事大学自动化专业C语言课程代码参考(第七周)
- 电子科学和计算机哪个好,计算机科学与技术专业和电子科学与技术专业,哪个好些?...