PyTorch 神经网络基础:Variable 与 Tensor 的梯度计算
本文介绍了 PyTorch 中 Variable 和 Tensor 的基本使用方法,重点解析了如何在计算中使用它们完成自动求导和梯度计算。文章通过实例展示了从早期的 Variable 到 Tensor 的演进,以及在 PyTorch 中对计算图和自动求导的支持。此外,文中详细解释了张量梯度的计算公式与结果,同时展示了如何从 Variable 和 Tensor 中提取数据,并转换为 NumPy 格式
PyTorch 神经网络基础:Variable 与 Tensor 的梯度计算
本文介绍了 PyTorch 中 Variable 和 Tensor 的基本使用方法,重点解析了如何在计算中使用它们完成自动求导和梯度计算。文章通过实例展示了从早期的 Variable 到 Tensor 的演进,以及在 PyTorch 中对计算图和自动求导的支持。此外,文中详细解释了张量梯度的计算公式与结果,同时展示了如何从 Variable 和 Tensor 中提取数据,并转换为 NumPy 格式。内容旨在帮助读者理解 PyTorch 的核心概念,掌握张量计算的基础技能,为深度学习模型的构建打下坚实基础。
文章目录
一 导入依赖
import torch
from torch.autograd import Variable # 导入 PyTorch 中的 Variable
二 Variable 介绍
在早期的 PyTorch 版本中,Variable 是一个用于封装 Tensor 的数据结构,它提供了额外的功能,例如自动求导和计算图管理。然而,从 PyTorch 0.4.0 开始,Variable 已经被弃用,其功能被完全合并到 Tensor 中。Variable 是基于张量构建的结构,支持与张量相同的操作,并通过设置 requires_grad=True 实现自动梯度计算和计算图记录。
# 创建一个 Float 类型的张量
tensor = torch.FloatTensor([[1, 2], [3, 4]])
# 使用 Variable 封装张量并设置 requires_grad=True
variable = Variable(tensor, requires_grad=True)
print("Tensor:", tensor) # 输出张量
print("Variable:", variable) # 输出 Variable
自 PyTorch 0.4.0 起,Variable 被废弃,所有张量(Tensor)均支持自动求导功能,不需要显式地使用 Variable ,可以直接这样写:
# 直接创建一个支持梯度计算的张量
tensor = torch.tensor([[1.0, 2.0], [3.0, 4.0]], requires_grad=True)
print("Data:", tensor) # 输出张量的值
三 梯度计算
1)使用 Variable 计算
# 计算 x^2 的均值
v_out = torch.mean(variable * variable) # x^2
print("Output:", v_out) # 输出结果: 7.5
# 进行反向传播,计算梯度
v_out.backward()
print("Gradient of Variable:", variable.grad) # 输出初始 Variable 的梯度
2)使用 Tensor 计算
# 创建支持梯度计算的张量
tensor = torch.tensor([[1.0, 2.0], [3.0, 4.0]], requires_grad=True)
print("Data:", tensor) # 输出张量的值
# 定义一个计算过程 (均值平方)
output = torch.mean(tensor * tensor) # 相当于 x^2 的均值
# 输出计算结果
print("Output of mean(square):", output.item()) # 输出标量值
# 进行反向传播,计算梯度
output.backward()
# 查看梯度
print("Gradient of Tensor:", tensor.grad) # 输出梯度
3)划重点 - 梯度公式释义
假设 tensor = [[1.0, 2.0], [3.0, 4.0]]:
-
计算过程:
output = 1 n ∑ ( x 2 ) = 1 4 ( 1 2 + 2 2 + 3 2 + 4 2 ) = 7.5 \text{output} = \frac{1}{n} \sum (x^2) = \frac{1}{4} (1^2 + 2^2 + 3^2 + 4^2) = 7.5 output=n1∑(x2)=41(12+22+32+42)=7.5 -
梯度公式: 对于
output = 1 4 ∑ ( x 2 ) \text{output} = \frac{1}{4} \sum (x^2) output=41∑(x2)
梯度为:
∂ output ∂ x = 1 4 ⋅ 2 x = x 2 \frac{\partial \text{output}}{\partial x} = \frac{1}{4} \cdot 2x = \frac{x}{2} ∂x∂output=41⋅2x=2x -
张量的梯度: 每个元素的梯度为:
tensor.grad = tensor 2 = [ 0.5 1.0 1.5 2.0 ] \text{tensor.grad} = \frac{\text{tensor}}{2} = \begin{bmatrix} 0.5 & 1.0 \\ 1.5 & 2.0 \end{bmatrix} tensor.grad=2tensor=[0.51.51.02.0]
四 获取数据
1)获取 Variable 里的数据
print("Variable:", variable) # 输出 Variable 形式
print("Variable data:", variable.data) # 获取 Variable 中的张量数据
print("Variable data as NumPy:", variable.data.numpy()) # 转换为 NumPy 数据
2)获取 Tensor 里的数据
# 直接获取 Tensor 的数据
print("Tensor:", tensor)
# 去除梯度信息,获取纯数据
print("Tensor data (no grad):", tensor.detach())
# 转换为 NumPy 数据
print("Tensor as NumPy array:", tensor.detach().numpy())
五 完整代码示例
# This is a sample Python script.
# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.
import torch
from torch.autograd import Variable # torch 中 Variable 模块
def variable_old():
# 创建一个 Float 类型的张量
tensor = torch.FloatTensor([[1, 2], [3, 4]])
# 使用 Variable 封装张量并设置 requires_grad=True
variable = Variable(tensor, requires_grad=True)
print("Tensor:", tensor) # 输出张量
print("Variable:", variable) # 输出 Variable
# 计算 x^2 的均值
v_out = torch.mean(variable * variable) # x^2
print("Output:", v_out) # 输出结果: 7.5
# 进行反向传播,计算梯度
v_out.backward()
print("Gradient of Variable:", variable.grad) # 输出初始 Variable 的梯度
print("Variable:", variable) # 输出 Variable 形式
print("Variable data:", variable.data) # 获取 Variable 中的张量数据
print("Variable data as NumPy:", variable.data.numpy()) # 转换为 NumPy 数据
def tensor_new():
# 创建支持梯度计算的张量
tensor = torch.tensor([[1.0, 2.0], [3.0, 4.0]], requires_grad=True)
print("Data:", tensor) # 输出张量的值
# 定义一个计算过程 (均值平方)
output = torch.mean(tensor * tensor) # 相当于 x^2 的均值
# 输出计算结果
print("Output of mean(square):", output.item()) # 输出标量值
# 进行反向传播,计算梯度
output.backward()
# 查看梯度
print("Gradient of Tensor:", tensor.grad) # 输出梯度
# 直接获取 Tensor 的数据
print("Tensor:", tensor)
# 去除梯度信息,获取纯数据
print("Tensor data (no grad):", tensor.detach())
# 转换为 NumPy 数据
print("Tensor as NumPy array:", tensor.detach().numpy())
def print_hi(name):
# Use a breakpoint in the code line below to debug your script.
print(f'Hi, {name}') # Press ⌘F8 to toggle the breakpoint.
# 老的写法
variable_old()
# 新的写法
tensor_new()
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
print_hi('变量 Variable 和 Tensor')
# See PyCharm help at https://www.jetbrains.com/help/pycharm/
复制粘贴并覆盖到你的 main.py 中运行,运行结果如下。
Hi, 变量 Variable 和 Tensor
Tensor: tensor([[1., 2.],
[3., 4.]])
Variable: tensor([[1., 2.],
[3., 4.]], requires_grad=True)
Output: tensor(7.5000, grad_fn=<MeanBackward0>)
Gradient of Variable: tensor([[0.5000, 1.0000],
[1.5000, 2.0000]])
Variable: tensor([[1., 2.],
[3., 4.]], requires_grad=True)
Variable data: tensor([[1., 2.],
[3., 4.]])
Variable data as NumPy: [[1. 2.]
[3. 4.]]
Data: tensor([[1., 2.],
[3., 4.]], requires_grad=True)
Output of mean(square): 7.5
Gradient of Tensor: tensor([[0.5000, 1.0000],
[1.5000, 2.0000]])
Tensor: tensor([[1., 2.],
[3., 4.]], requires_grad=True)
Tensor data (no grad): tensor([[1., 2.],
[3., 4.]])
Tensor as NumPy array: [[1. 2.]
[3. 4.]]
六 源码地址
代码地址,GitHub 之 变量 Variable 和 Tensor.py 。
七 参考
[1] PyTorch 官方文档
[2] 莫烦 Python
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐




所有评论(0)