阿里巴巴怎么做企业网站,怎么做短链接网站,git主题wordpress,图片上传 网站建设教学视频在前面的章节中#xff0c;我们学会了如何用nn.Cell搭建一个网络骨架。但这就像造出了一辆只有油门没有方向盘的汽车#xff0c;它能跑#xff0c;却不知道该往哪儿跑。为了让模型“学得会”#xff0c;我们需要给它装上“方向盘”和“导航系统”#xff0c;让它在犯错时知…在前面的章节中我们学会了如何用nn.Cell搭建一个网络骨架。但这就像造出了一辆只有油门没有方向盘的汽车它能跑却不知道该往哪儿跑。为了让模型“学得会”我们需要给它装上“方向盘”和“导航系统”让它在犯错时知道如何修正自己。这个核心系统就是自动微分。1. 学习的本质如何衡量“错误”并修正一个AI模型的学习过程本质上是一个“猜谜-反馈-修正”的循环。猜谜 (前向传播): 模型接收输入数据如一张图片根据其内部的参数权重W和偏置b给出一个预测结果比如“这是一只猫”。反馈 (计算损失): 我们将模型的预测结果与真实的标签“这确实是一只猫”进行比较。两者之间的“差距”我们用一个叫做损失函数 (Loss Function)的东西来量化。差距越大损失值就越高。修正 (反向传播与优化): 这是最关键的一步。模型需要弄清楚“我这次错得有多离谱我的每一个内部参数应该如何调整才能让下次的预测结果更接近真相”“如何调整”这个问题的答案就藏在梯度 (Gradient)之中。2. 梯度参数的“调整指南针”梯度是一个数学概念听起来很深奥但它的直观意义非常简单它指出了函数值增长最快的方向。在我们的场景中损失函数是关于模型所有参数的函数Loss f(W, b)。我们计算出的损失函数关于某个参数比如某个权重W_i的梯度就告诉我们如果我将参数W_i稍微增加一点点我的总损失值会增加多少。如果梯度是一个大的正数意味着稍微增加这个参数损失就会急剧增大。那么为了减小损失我们应该减小这个参数。如果梯度是一个大的负数意味着稍微增加这个参数损失就会急剧减小。那么为了减小损失我们应该增加这个参数。如果梯度接近于0意味着调整这个参数对损失影响不大说明它可能已经处于一个比较理想的值了。因此梯度就像一个指南针为我们模型中成千上万的参数一一指明了“应该朝哪个方向调整才能让总损失变小”。这个根据梯度调整参数的过程就是梯度下降 (Gradient Descent)。3. 自动微分解放生产力的“魔法”一个现代神经网络的参数动辄数百万、上千万。手动去计算每一个参数对于最终损失的梯度是完全不现实的。而自动微分 (Automatic Differentiation, AD)就是一个能自动完成这个庞大工程的绝妙机制。MindSpore的自动微分正是构建在我们之前学习的计算图之上的。前向传播时: MindSpore记录下从输入Tensor到最终损失值的所有计算步骤形成一张计算图。反向传播时: MindSpore从最终的损失值开始沿着计算图反向追溯利用微积分中的链式法则一步步地计算出损失对每一个中间变量、直至最源头的模型参数的梯度。这个过程精确、高效并且对用户来说几乎是透明的。我们只需要搭建好前向网络剩下的求导工作交给MindSpore就好。4. 实战mindspore.grad的使用MindSpore提供了强大的mindspore.grad函数让我们能亲身体验自动微分的威力。4.1 对普通函数求导我们先从一个简单的数学函数f(x) 3x^2 4x开始。我们知道它的导数是f(x) 6x 4。让我们看看MindSpore是如何计算的。importmindsporefrommindsporeimportgrad,Tensor# 1. 定义我们的函数deff(x):return3*x**24*x# 2. 使用 grad 生成一个用于求导的新函数# grad_position0 表示对函数的第0个输入求导grad_fngrad(f,grad_position0)# 3. 计算在 x2 处的导数xTensor(2.0,mindspore.float32)gradientgrad_fn(x)print(f函数 f(x) 3x^2 4x)print(f在 x 2 处的导数值是:{gradient})# 理论值 f(2) 6*2 4 16输出结果将是16.0与我们手动计算的完全一致4.2 对网络参数求导现在让我们回到神经网络的场景。我们的目标是求损失函数关于网络参数的梯度。这里我们需要一个更强大的工具mindspore.ops.GradOperation它是grad针对网络训练场景的封装。importnumpyasnpimportmindsporefrommindsporeimportnn,ops,Tensor# --- 复用上一章的网络和定义 ---mindspore.set_context(modemindspore.PYNATIVE_MODE)classMyLinearNet(nn.Cell):def__init__(self):super().__init__()self.densenn.Dense(in_channels3,out_channels4)defconstruct(self,x):returnself.dense(x)# 1. 准备工作网络、数据、损失函数netMyLinearNet()loss_fnnn.MSELoss()# 使用均方误差损失optimizernn.SGD(net.trainable_params(),learning_rate0.01)# 定义一个优化器后面会讲# 2. 定义“单步训练函数”# 这个函数描述了从输入到计算出损失的完整前向过程defforward_fn(data,label):logitsnet(data)lossloss_fn(logits,label)returnloss,logits# 3. 获取梯度计算函数# get_by_listTrue 表示我们要求的是关于一个参数列表的梯度# net.trainable_params() 返回了网络中所有需要被训练的参数W和bgrad_fnops.GradOperation(get_by_listTrue)(forward_fn,net.trainable_params())# 4. 模拟一次计算# 准备一批假数据input_dataTensor(np.random.rand(2,3),mindspore.float32)target_labelTensor(np.random.rand(2,4),mindspore.float32)# 执行梯度计算# grads 是一个元组包含了损失对每个可训练参数的梯度loss_value,gradsgrad_fn(input_data,target_label)print(损失值:,loss_value)print(-*20)# 打印第一个参数权重W的梯度print(权重(W)的梯度:\n,grads[0])print(权重(W)的形状:,grads[0].shape)print(-*20)# 打印第二个参数偏置b的梯度print(偏置(b)的梯度:\n,grads[1])print(偏置(b)的形状:,grads[1].shape)代码解读:forward_fn是我们的核心它定义了“猜谜”和“反馈”的全过程。ops.GradOperation(...)创建了一个强大的梯度计算工具。我们告诉它我们要对forward_fn的结果损失进行求导并且求导的目标是net.trainable_params()网络的所有权重和偏置。执行grad_fn后它不仅返回了梯度还返回了forward_fn的原始输出损失值和预测值非常方便。我们成功地拿到了损失对权重W形状为4x3和偏置b形状为4的梯度有了这些梯度优化器就知道该如何更新参数了。5. 总结自动微分是连接模型预测与模型优化的桥梁是深度学习框架的“内功心法”。通过本文我们理解了学习的目标: 最小化损失函数。学习的依据: 损失函数关于模型参数的梯度。学习的实现: MindSpore基于计算图的自动微分机制能够自动、高效地计算出所有参数的梯度。学习的工具:mindspore.grad和ops.GradOperation是我们获取梯度的有力武器。我们已经站在了模型训练的门槛上。我们有了数据Tensor有了网络nn.Cell现在又有了指导优化的方向梯度。万事俱备只欠东风。这“东风”就是负责执行参数更新的优化器 (Optimizer)。下一篇文章我们将正式开始训练我们的第一个模型