中山优化网站,炫酷的国外网站,如何很好的进行网站的内部推广,较成功营销网站的例子笔记为自我总结整理的学习笔记#xff0c;若有错误欢迎指出哟~ 深度学习专栏链接#xff1a; http://t.csdnimg.cn/dscW7 pytorch——Autograd Autograd简介requires_grad计算图没有梯度追踪的张量ensor.data 、tensor.detach()非叶子节点的梯度计算图特点总结 利用Autograd实… 笔记为自我总结整理的学习笔记若有错误欢迎指出哟~ 深度学习专栏链接 http://t.csdnimg.cn/dscW7 pytorch——Autograd Autograd简介requires_grad计算图没有梯度追踪的张量ensor.data 、tensor.detach()非叶子节点的梯度计算图特点总结 利用Autograd实现线性回归 Autograd简介
autograd是PyTorch中的自动微分引擎它是PyTorch的核心组件之一。autograd提供了一种用于计算梯度的机制使得神经网络的训练变得更加简洁和高效。
在深度学习中梯度是优化算法如反向传播的关键部分。通过计算输入变量相对于输出变量的梯度可以确定如何更新模型的参数以最小化损失函数。
autograd的工作原理是跟踪在张量上进行的所有操作并构建一个有向无环图DAG称为计算图。这个计算图记录了张量之间的依赖关系以及每个操作的梯度函数。当向前传播时autograd会自动执行所需的计算并保存中间结果。当调用.backward()函数时autograd会根据计算图自动计算梯度并将梯度存储在每个张量的.grad属性中。
使用autograd非常简单。只需将需要进行梯度计算的张量设置为requires_gradTrue然后执行前向传播和反向传播操作即可。例如
import torch as tx t.tensor([2.0], requires_gradTrue)
y x**2 3*x 1y.backward()print(x.grad) # 输出tensor([7.])在上述代码中首先创建了一个张量 x并设置了 requires_gradTrue表示想要计算关于 x 的梯度。然后定义了一个计算图 y通过对 x 进行一系列操作得到结果 y。最后调用 .backward() 函数执行反向传播并通过 x.grad 获取计算得到的梯度。
autograd的存在使得训练神经网络变得更加方便无需手动计算和更新梯度。同时它也为实现更复杂的计算图和自定义的梯度函数提供了灵活性和扩展性。
requires_grad
requires_grad是PyTorch中张量的一个属性用于指定是否需要计算该张量的梯度。如果需要计算梯度则需将其设置为True否则设置为False。默认情况下该属性值为False。
在深度学习中通常需要对模型的参数进行优化因此需要计算这些参数的梯度。通过将参数张量的requires_grad属性设置为True可以告诉PyTorch跟踪其计算并计算梯度。除了参数张量之外还可以将其他需要计算梯度的张量设置为requires_gradTrue以便计算它们的梯度。
需要注意的是如果张量的requires_grad属性为True则计算成本会略微增加因为PyTorch需要跟踪该张量的计算并计算其梯度。因此对于不需要计算梯度的张量最好将其requires_grad属性设置为False以减少计算成本。
计算图 PyTorch中autograd的底层采用了计算图计算图是一种特殊的有向无环图DAG用于记录算子与变量之间的关系。一般用矩形表示算子椭圆形表示变量。其计算图如图所示图中MULADD都是算子 a \textbf{a} a b \textbf{b} b c \textbf{c} c即变量。
没有梯度追踪的张量ensor.data 、tensor.detach()
tensor.data和tensor.detach()都可以用于获取一个没有梯度追踪的张量副本但它们之间有一些细微的区别。
tensor.data是一个属性用于返回一个与原始张量共享数据存储的新张量但不会共享梯度信息。这意味着对返回的张量进行操作不会影响到原始张量的梯度。然而如果在计算图中使用了这个新的张量梯度仍会通过原始张量进行传播。
以下是一个示例说明
import torchx torch.tensor([2.0], requires_gradTrue)
y x**2 3*x 1z y.data
z * 2 # 操作z不会影响到y的梯度y.backward()print(x.grad) # 输出tensor([7.])在上述代码中我们首先创建了一个张量x并设置了requires_gradTrue表示我们希望计算关于x的梯度。然后我们定义了一个计算图y并将其赋值给z通过操作z不会影响到y的梯度。最后我们调用.backward()方法计算相对于x的梯度并将梯度存储在x.grad属性中。
tensor.detach()是一个函数用于返回一个新的张量与原始张量具有相同的数据内容但不会共享梯度信息。与tensor.data不同的是tensor.detach()可以应用于任何张量而不仅限于具有requires_gradTrue的张量。
以下是使用tensor.detach()的示例
import torchx torch.tensor([2.0], requires_gradTrue)
y x**2 3*x 1z y.detach()
z * 2 # 操作z不会影响到y的梯度y.backward()print(x.grad) # 输出tensor([7.])在上述代码中我们执行了与前面示例相同的操作将y赋值给z并通过操作z不会影响到y的梯度。最后我们调用.backward()方法计算相对于x的梯度并将梯度存储在x.grad属性中。
总结来说tensor.data和tensor.detach()都可以用于获取一个没有梯度追踪的张量副本但tensor.detach()更加通用可应用于任何张量。
非叶子节点的梯度
在反向传播过程中非叶子节点的梯度默认情况下是被清空的。
1.使用.retain_grad()方法在创建张量时可以使用.retain_grad()方法显式指定要保留梯度信息。然后在反向传播后可以访问这些非叶子节点的梯度。
import torchx torch.tensor([2.0], requires_gradTrue)
y x**2 3*x 1y.retain_grad()z y.mean()z.backward()grad_y y.gradprint(grad_y) # 输出tensor([1.])
2.第二种方法使用hook。hook是一个函数输入是梯度不应该有返回值
import torchdef variable_hook(grad):print(y的梯度,grad)x torch.ones(3, requires_gradTrue)
w torch.rand(3, requires_gradTrue)
y x * w
# 注册hook
hook_handle y.register_hook(variable_hook)
z y.sum()
z.backward()# 除非你每次都要用hook否则用完之后记得移除hook
hook_handle.remove()计算图特点总结
在PyTorch中计算图是一种用于表示计算过程的数据结构。
动态计算图PyTorch使用动态计算图这意味着计算图是根据实际执行流程动态构建的。这使得在每次前向传播过程中可以根据输入数据的不同而灵活地构建计算图。
自动微分PyTorch的计算图不仅用于表示计算过程还支持自动微分。通过计算图PyTorch可以自动计算梯度无需手动编写反向传播算法。这大大简化了深度学习模型的训练过程。
基于节点的表示计算图由一系列节点Node和边Edge组成其中节点表示操作如张量运算或变量如权重边表示数据的流动。每个节点都包含了前向计算和反向传播所需的信息。
叶子节点和非叶子节点在计算图中叶子节点是没有输入边的节点通常表示输入数据或需要求梯度的变量。非叶子节点是具有输入边的节点表示计算操作。在反向传播过程中默认情况下只有叶子节点的梯度会被计算和保留非叶子节点的梯度会被清空。
延迟执行PyTorch中的计算图是按需执行的。也就是说在前向传播过程中只有实际需要计算的节点才会被执行不需要计算的节点会被跳过。这种延迟执行的方式提高了效率尤其对于大型模型和复杂计算图来说。
计算图优化PyTorch内部使用了一些优化技术来提高计算图的效率。例如通过共享内存缓存中间结果避免重复计算通过融合多个操作为一个操作减少计算和内存开销等。这些优化技术可以提高计算速度并减少内存占用。
利用Autograd实现线性回归
【深度学习】pytorch——线性回归http://t.csdnimg.cn/7KsP3
上一篇文章为手动计算梯度这里来利用Autograd实现自动计算梯度
import torch as t
%matplotlib inline
from matplotlib import pyplot as plt
from IPython import display
import numpy as np# 设置随机数种子保证在不同电脑上运行时下面的输出一致
t.manual_seed(1000) def get_fake_data(batch_size8): 产生随机数据yx*23加上了一些噪声x t.rand(batch_size, 1, devicedevice) * 5y x * 2 3 t.randn(batch_size, 1, devicedevice)return x, y# 随机初始化参数
w t.rand(1,1, requires_gradTrue)
b t.zeros(1,1, requires_gradTrue)
losses np.zeros(500)lr 0.02 # 学习率for ii in range(500):x, y get_fake_data(batch_size4)# forward计算lossy_pred x.mm(w) b.expand_as(y) loss 0.5 * (y_pred - y) ** 2 # 均方误差loss loss.sum()losses[ii] loss.item()# backward自动计算梯度loss.backward()# 更新参数w.data.sub_(lr * w.grad.data)b.data.sub_(lr * b.grad.data)# 梯度清零w.grad.data.zero_()b.grad.data.zero_()if ii%50 0:# 画图display.clear_output(waitTrue)x t.arange(0, 6).view(-1, 1).float()y x.mm(w.data) b.data.expand_as(x)plt.plot(x.numpy(), y.numpy(),colorb) # predictedx2, y2 get_fake_data(batch_size100) plt.scatter(x2.numpy(), y2.numpy(),colorr) # true dataplt.xlim(0,5)plt.ylim(0,15) plt.show()plt.pause(0.5)print(w: , w.item(), b: , b.item())w: 2.036161422729492 b: 3.095750331878662
以下是代码的主要步骤 定义了一个get_fake_data函数用于生成带有噪声的随机数据数据的真实关系为 y x ∗ 2 3 yx*23 yx∗23。 初始化参数w和b并设置requires_gradTrue以便自动计算梯度。 进行500轮训练每轮训练包括以下步骤 从get_fake_data函数中获取一个小批量的训练数据。前向传播计算模型的预测值y_pred即 x x x与参数w和b的线性组合。计算均方误差损失函数。反向传播自动计算参数w和b的梯度。更新参数通过梯度下降法更新参数w和b。清零梯度将参数的梯度置零以便下一轮计算梯度。每50轮训练可视化当前模型的预测结果和真实数据的散点图。 训练结束后打印出最终学得的参数w和b。
plt.plot(losses)
plt.ylim(0,50)实现了对损失函数随训练轮数变化的可视化。losses是一个长度为500的数组记录了每一轮训练后的损失函数值。plt.plot(losses)会将这些损失函数值随轮数的变化连成一条曲线可以直观地看到模型在训练过程中损失函数的下降趋势。
plt.ylim(0,50)用于设置y轴的范围保证曲线能够完整显示在图像中。