企业网站建设的主要步骤网站域名归属权
企业网站建设的主要步骤,网站域名归属权,中国建设银行邢台分行网站,建培网自动微分机制介绍
PaddlePaddle 的神经网络核心是自动微分#xff0c;本篇文章主要为你介绍如何使用飞桨的自动微分#xff0c;以及飞桨的自动微分机制#xff0c;帮助你更好的使用飞桨进行训练。
一、背景
神经网络是由节点和节点间的相互连接组成的。网络中每层的每个节…自动微分机制介绍PaddlePaddle 的神经网络核心是自动微分本篇文章主要为你介绍如何使用飞桨的自动微分以及飞桨的自动微分机制帮助你更好的使用飞桨进行训练。一、背景神经网络是由节点和节点间的相互连接组成的。网络中每层的每个节点代表一种特定的函数来对输入进行计算。每个函数都是由不同参数权重w和偏置b组成。神经网络训练的过程就是不断让这些函数的参数进行学习、优化以能够更好的处理后面输入的过程。为了让神经网络的判断更加准确首先需要有衡量效果的工具于是损失函数应运而生。如果你想要神经网络的效果好那么就要让损失函数尽可能的小于是深度学习引入了能够有效计算函数最小值的算法–梯度下降等优化算法以及参数优化更新过程–反向传播。前向传播是输入通过每一层节点计算后得到每层输出上层输出又作为下一层的输入最终达到输出层。然后通过损失函数计算得到 loss 值。反向传播是通过 loss 值来指导前向节点中的函数参数如何改变并更新每层中每个节点的参数来让整个神经网络达到更小的 loss 值。自动微分机制就是让你只关注组网中的前向传播过程然后飞桨框架来自动完成反向传播过程从而来让你从繁琐的求导、求梯度的过程中解放出来。二、如何使用飞桨的自动微分机制本文通过一个比较简单的模型来还原飞桨的自动微分过程。 本示例基于 Paddle2.0 编写。#加载飞桨和相关类库 import paddle from paddle.vision.models import vgg11 import paddle.nn.functional as F import numpy as np print(paddle.__version__)2.2.0本案例首先定义网络。因为本示例着重展示如何使用飞桨进行自动微分故组网部分不过多展开直接使用高层 API 中封装好的模型 paddle.vision.models.vgg11 。然后随机初始化一个输入x和对应标签label。model vgg11() x paddle.rand([1,3,224,224]) label paddle.randint(0,1000)然后将输入传入到模型中进行前向传播过程。# 前向传播 predicts model(x)前向传播结束后你就得到模型的预测结果predicts这时可以使用飞桨中的对应损失函数 API 进行损失函数的计算。该例子中使用cross_entropy来计算损失函数来衡量模型的预测情况。# 计算损失 loss F.cross_entropy(predicts, label)随后进行反向传播在飞桨中你只需要调用backward()即可自动化展开反向传播过程。各梯度保存在grad属性中。# 开始进行反向传播 loss.backward()然后来定义优化器本例子中使用Adam优化器设置learning_rate为0.001并把该模型的所有参数传入优化器中。# 设置优化器 optim paddle.optimizer.Adam(learning_rate0.001, parametersmodel.parameters())最后通过step来开始执行优化器并进行模型参数的更新# 更新参数 optim.step()通过以上步骤你已经完成了一个神经网络前向传播、反向传播的所有过程。快自己动手试试吧三、飞桨中自动微分相关所有的使用方法说明此章主要介绍飞桨中所有自动微分过程中会使用到的方法、属性等。属于第二部分的扩展阅读。1、飞桨中的Tensor有stop_gradient属性这个属性可以查看一个Tensor是否计算并传播梯度。如果为True则该Tensor不会计算梯度并会阻绝 Autograd 的梯度传播。反之则会计算梯度并传播梯度。用户自行创建的的Tensor默认stop_gradient为True即默认不计算梯度模型参数的stop_gradient默认都为False即默认计算梯度。import paddle a paddle.to_tensor([1.0, 2.0, 3.0]) b paddle.to_tensor([1.0, 2.0, 3.0], stop_gradientFalse) # 将 b 设置为需要计算梯度的属性 print(a.stop_gradient) print(b.stop_gradient)True Falsea.stop_gradient False print(a.stop_gradient)False2、接下来本文用一个简单的计算图来了解如何调用backward()函数。开始从当前Tensor开始计算反向的神经网络传导并计算计算图中Tensor的梯度。import paddle x paddle.to_tensor([1.0, 2.0, 3.0], stop_gradientFalse) y paddle.to_tensor([4.0, 5.0, 6.0], stop_gradientFalse) z x ** 2 4 * y假设上面创建的x和y分别是神经网络中的参数z为神经网络的损失值loss。对 z 调用backward()飞桨即可以自动计算x和y的梯度并且将他们存进grad属性中。z.backward() print(Tensor xs grad is: {}.format(x.grad)) print(Tensor ys grad is: {}.format(y.grad))Tensor xs grad is: [2. 4. 6.] Tensor ys grad is: [4. 4. 4.]此外飞桨默认会释放反向计算图。如果在backward()之后继续添加 OP需要将backward()中的retain_graph参数设置为True此时之前的反向计算图会保留。温馨小提示将其设置为False会更加节省内存。因为他的默认值是False所以也可以直接不设置此参数。import paddle x paddle.to_tensor([1.0, 2.0, 3.0], stop_gradientFalse) y x 3 y.backward(retain_graphTrue) # 设置 retain_graph 为 True保留反向计算图 print(Tensor xs grad is: {}.format(x.grad))Tensor xs grad is: [1. 1. 1.]3、因为backward()会累积梯度所以飞桨还提供了clear_grad()函数来清除当前Tensor的梯度。import paddle import numpy as np x np.ones([2, 2], np.float32) inputs2 [] for _ in range(10): tmp paddle.to_tensor(x) tmp.stop_gradient False inputs2.append(tmp) ret2 paddle.add_n(inputs2) loss2 paddle.sum(ret2) loss2.backward() print(Before clear {}.format(loss2.gradient())) loss2.clear_grad() print(After clear {}.format(loss2.gradient()))Before clear [1.] After clear [0.]四、飞桨自动微分运行机制本章主要介绍飞桨在实现反向传播进行自动微分计算时内部是如何运行工作的。此部分为选读部分更多是介绍飞桨内部实现机制可以选择跳过跳过不会影响你的正常使用。飞桨的自动微分是通过trace的方式记录前向 OP的执行并自动创建反向 var和添加相应的反向 OP然后来实现反向梯度计算的。下面本文用一些的例子来模拟这个过程。例子一首先用一个比较简单的例子来让你了解整个过程。import paddle a paddle.to_tensor(2.0, stop_gradientFalse) b paddle.to_tensor(5.0, stop_gradientTrue) c a * b c.backward() print(Tensor as grad is: {}.format(a.grad)) print(Tensor bs grad is: {}.format(b.grad))Tensor as grad is: Tensor(shape[1], dtypefloat32, placePlace(cpu), stop_gradientFalse, [5.]) Tensor bs grad is: None在上面代码中c.backward()执行前你可以理解整个计算图是这样的当创建TensorTensor的stop_gradFalse时会自动为此Tensor创建一个反向 Tensor。在此例子中a 的反向 Tensor 就是a_grad。在a_grad中会记录他的反向 OP因为 a 没有作为任何反向 op 的输入所以它的grad_op为None。当执行 OP 时会自动创建反向 OP不同的 OP 创建反向 OP 的方法不同传的内容也不同。本文以这个乘法 OP 为例-乘法 OP 的反向 OP即MulBackward的输入是正向 OP 的两个输入以及正向 OP 的输出 Tensor 的反向 Tensor。在此例子中就是a、b、c_grad-乘法 OP 的反向 OP即MulBackward的输出是正向 OP 的两个输入的反向 Tensor如果输入是 stop_gradientTrue则即为 None。在此例子中就是a_grad、Noneb_grad-乘法 OP 的反向 OP即MulBackward的grad_pending_ops是自动构建反向网络的时候让这个反向 op 知道它下一个可以执行的反向 op 是哪一个可以理解为反向网络中一个反向 op 指向下一个反向 op 的边。当 c 通过乘法 OP 被创建后c 会创建一个反向 Tensorc_grad,他的grad_op为该乘法 OP 的反向 OP即MulBackward。调用backward()后正式开始进行反向传播过程开始自动计算微分。例子二用一个稍微复杂一点的例子让你深入了解这个过程。import paddle a paddle.to_tensor(2.0, stop_gradientFalse) b paddle.to_tensor(5.0, stop_gradientFalse) c a * b d paddle.to_tensor(4.0, stop_gradientFalse) e c * d e.backward() print(Tensor as grad is: {}.format(a.grad)) print(Tensor bs grad is: {}.format(b.grad)) print(Tensor cs grad is: {}.format(c.grad)) print(Tensor ds grad is: {}.format(d.grad))Tensor as grad is: [20.] Tensor bs grad is: [8.] Tensor cs grad is: [4.] Tensor ds grad is: [10.]该例子的正向和反向图构建过程即五、基于自动微分基础算子的新自动微分机制在科学计算领域的深度学习任务中由于引入偏微分方程组往往需要使用到高阶导数。一些其他复杂的深度学习任务中有时也会使用到高阶导数。为了更好地支持这些应用场景飞桨在静态图模式下实现了一套基于自动微分基础算子的新自动微分机制目前已经支持全联接网络模型详细介绍可以参考 paddle.incubate.autograd 。六、总结本文章主要介绍了如何使用飞桨的自动微分以及飞桨的自动微分机制。