首页 / 资讯中心 / 文章详情

深度学习26:PyTorch:参数更新方法(Momentum)

深度学习26:PyTorch:参数更新方法(Momentum) ★ FEATURED ARTICLE
目录标题一、Momentum二、理解上面代码三、X_clone X.clone().detach().requires_grad_(True)一、MomentumMomentum动量法会保存历史梯度并给予一定的权重使其也参与到参数更新中V ← α V − η ∇ V \leftarrow \alpha V - \eta \nablaV←αV−η∇W ← W V W \leftarrow W VW←WVV VV历史负梯度的加权和α \alphaα历史梯度的权重∇ \nabla∇当前梯度即∂ L ∂ W \frac{\partial L}{\partial W}∂W∂L​η \etaη学习率可以通过torch.optim.SGD()并设置momentum历史梯度权重参数来使用动量法。以寻找f ( x 1 , x 2 ) 0.05 x 1 2 x 2 2 f(x_1, x_2) 0.05x_1^2 x_2^2f(x1​,x2​)0.05x12​x22​的最小值为例importtorchimportnumpyasnpimportmatplotlib.pyplotasplt#这是在函数上找一个最小点, 二不是找到一组权重 w使得在未知数据上的预测最准# 定义函数deff(X):return0.05*X[0]**2X[1]**2# 定义函数实现梯度下降法defgradient_descent(X,optimizer,num_iters):# 拷贝当前X的值放入列表中X_arrX.detach().numpy().copy()foriinrange(num_iters):# 1. 前向传播得到损失值yf(X)# 2. 反向传播y.backward()# 3. 更新参数optimizer.step()# 4. 梯度清零optimizer.zero_grad()# 将更新之后的X保存到列表中X_arrnp.vstack((X_arr,X.detach().numpy()))returnX_arr# 主流程# 1. 参数X初始化Xtorch.tensor(data[-7.0,2.0],requires_gradTrue)# 2. 定义超参数lr0.01num_iters500# 3. 优化器对比# 3.1 SGDX_cloneX.clone().detach().requires_grad_(True)optimizertorch.optim.SGD(params[X_clone],lrlr)# 梯度下降X_arr1gradient_descent(X_clone,optimizer,num_iters)# 画出点轨迹plt.plot(X_arr1[:,0],X_arr1[:,1],r)# 3.2 动量法X_cloneX.clone().detach().requires_grad_(True)optimizertorch.optim.SGD(params[X_clone],lrlr,momentum0.9)# 梯度下降X_arr2gradient_descent(X_clone,optimizer,num_iters)# 画出点轨迹plt.plot(X_arr2[:,0],X_arr2[:,1],b)# 画出等高线x1_grid,x2_gridnp.meshgrid(np.linspace(-7,7,100),np.linspace(-2,2,100))y_grid0.05*x1_grid**2x2_grid**2plt.contour(x1_grid,x2_grid,y_grid,levels30,colorsgray)plt.legend([SGD,Momentum])# plt.show()plt.savefig(momentum_result.png)效果图二、理解上面代码参考blog 机器学习:线性回归3正规方程法和梯度下降法 里面的 三、梯度下降中的一元线性回归-梯度下降法(当初我也用这个和一元线性回归的梯度下降法和真实多元梯度下降对比)在真正的机器学习深度学习中损失函数确实是计算“预测值”与“真实标签Ground Truth”之间的差距比如均方误差 MSE、交叉熵等但在这段代码中并没有真实的训练数据也没有神经网络模型。它其实是在演示一个数学优化问题寻找函数极小值原来blog起始点是 (1,1) 导数(梯度)是2Θ这个上面代码起始点是 和导数(梯度) 都是 X torch.tensor(data[-7.0, 2.0], requires_gradTrue)上面代码就是参考 blog 里的逻辑但是这里我还要分析一遍下面为你详细解释为什么这里没有数据以及它和真实机器学习的区别1. 为什么这里可以直接用函数上的一个点这段代码演示的是最基础的梯度下降Gradient Descent物理过程。你可以把函数f ( x ) 0.05 ∗ X [ 0 ] 2 X [ 1 ] 2 f(x) 0.05 * X[0]^2 X[1]^2f(x)0.05∗X[0]2X[1]2想象成一个真实的碗或者山谷。参数 X初始在[-7.0, 2.0]就像是一个放在碗壁上的玻璃珠。梯度Gradient就是这个位置的坡度倾斜方向。梯度下降就是让玻璃珠顺着坡度最陡的地方往下滚。在这个“滚下山”的过程中你不需要任何数据集。你唯一需要的就是当前位置X以及当前位置的坡度通过y.backward()算出来。所以它确实只是在用函数上的点不断迭代。2. 如果换成真实的机器学习它会是什么样假设我们要训练一个神经网络来预测房价。代码的逻辑就会变成这样# 1. 有真实数据了# X_train 是房子面积y_true 是真实房价X_traintorch.tensor([50.0,80.0,100.0])y_truetorch.tensor([100.0,150.0,200.0])# 2. 有模型了# w 是权重参数相当于上面代码里的 Xwtorch.tensor([1.0],requires_gradTrue)# 3. 前向传播计算预测值y_predw*X_train# 预测房价 权重 * 面积# 4. 计算损失这里才体现出“预测值减真实值”# 比如用均方误差 (MSE)losstorch.mean((y_pred-y_true)**2)# 5. 反向传播loss.backward()# 6. 更新参数优化器更新的是权重 w而不是数据optimizer.step()optimizer.zero_grad()3. 对比一下两者的逻辑对比项提供的代码函数优化演示真实的机器学习训练参数被更新的对象坐标XX[0],X[1]模型权重w/b神经网络的神经元参数损失函数计算什么当前坐标X在空间里的高度/函数值模型预测出的y_pred与真实标签y_true的差距前向传播把X代入公式f(X)把真实数据X_train喂给模型算y_pred优化目标找到坐标系里函数值最小的点(0,0)找到一组权重w使得在未知数据上的预测最准应用场景纯粹的数学/可视化教学演示图像识别、自然语言处理等实际工程三、X_clone X.clone().detach().requires_grad_(True)这行代码是 PyTorch 中非常经典且严谨的写法通常出现在需要对一个张量重新开启梯度追踪但又不想影响原张量的场景中比如写自定义优化器、或者手动实现梯度下降1.x.clone()克隆复制一份数据作用在内存中复制一份和x一模一样的新数据。为什么需要如果你直接用x后续的修改会影响到原来的变量。clone()保证了新变量和原变量是完全独立的修改x_clone不会影响x。2..detach()脱离计算图断开追踪作用把克隆出来的张量从当前的计算图中剥离出来。为什么需要如果你直接用x.clone()这个新张量依然会记录着它是怎么从x计算出来的带有grad_fn。如果你之后想把它当作一个全新的、独立的变量来用就必须用detach()切断它和过去的联系把它变成一个普通的叶子节点Leaf Tensor。3..requires_grad_(True)重新开启梯度追踪作用强制让这个新张量可以计算梯度。为什么需要detach()之后这个张量默认是不需要求导的requires_gradFalse。但这行代码的目的是为了重新训练或计算所以必须加个下划线_这是原地修改方法强制把它设为True。
阅读完成 · 觉得有帮助?
咨询建站