【pytorch(02)】Tensor(张量)概述、如何创建、常见属性,切换设备
【pytorch(01)】CUDA、cuDNN、pytorch安装,神奇魔法
目录
- # Tensor概述
- 1. 概念
- 2. 特点
- 3. 数据类型
- Tensor的创建
- 基本创建方式
- 1. torch.tensor
- 2. torch.Tensor
- 总结
- 创建线性和随机张量
- 线性张量
- 1. **torch.arange**
- 2. **torch.linspace**
- 总结
- 随机张量
- 1. torch.randn
- 总结
- Tensor常见属性
- 获取属性
- 切换设备
- 类型转换
# Tensor概述
PyTorch会将数据封装成张量(Tensor)进行计算,所谓张量就是元素为相同类型的多维矩阵。
张量可以在 GPU 上加速运行。
1. 概念
张量是一个多维数组,通俗来说可以看作是扩展了标量、向量、矩阵的更高维度的数组。张量的维度决定了它的形状(Shape),例如:
- 标量 是 0 维张量,如
a = torch.tensor(5)
- 向量 是 1 维张量,如
b = torch.tensor([1, 2, 3])
- 矩阵 是 2 维张量,如
c = torch.tensor([[1, 2], [3, 4]])
- 更高维度的张量,如3维、4维等,通常用于表示图像、视频数据等复杂结构。
2. 特点
- 动态计算图:PyTorch 支持动态计算图,这意味着在每一次前向传播时,计算图是即时创建的。
- GPU 支持:PyTorch 张量可以通过
.to('cuda')
移动到 GPU 上进行加速计算。 - 自动微分:通过
autograd
模块,PyTorch 可以自动计算张量运算的梯度,这对深度学习中的反向传播算法非常重要。
3. 数据类型
PyTorch中有3种数据类型:浮点数、整数、布尔。其中,浮点数和整数又分为8位、16位、32位、64位,加起来共9种。
为什么要分为8位、16位、32位、64位呢?
场景不同,对数据的精度和速度要求不同。通常,移动或嵌入式设备追求速度,对精度要求相对低一些。精度越高,往往效果也越好,自然硬件开销就比较高。
Tensor的创建
在Torch中张量以 “类” 的形式封装起来,对张量的一些运算、处理的方法被封装在类中,官方文档:https://pytorch.org/docs/stable/torch.html#tensors
基本创建方式
1. torch.tensor
- 用途:torch.tensor 是一个工厂函数,用于根据给定的数据创建一个新的张量。它可以自动推断数据的类型。
- 语法:
torch.tensor(data, dtype=None, device=None, requires_grad=False)
- 参数:
data:可以是列表、元组、NumPy 数组等。
dtype:指定张量的数据类型(例如 torch.float32, torch.int64 等)。
device:指定张量存储的设备(例如 CPU 或 GPU)。
requires_grad:如果设置为 True,则会跟踪该张量上的所有操作,用于自动求导。 - 示例:
import torchdata = [[1, 2], [3, 4]]
tensor = torch.tensor(data, dtype=torch.float32)
print(tensor)
2. torch.Tensor
- 用途:torch.Tensor 是 PyTorch 中张量的基本类。它是一个通用的多维数组,类似于 NumPy 的 ndarray,但支持 GPU 加速和自动求导。
- 特点:
默认情况下,torch.Tensor 创建的是浮点型张量(torch.FloatTensor)。
可以通过继承或实例化来创建特定类型的张量。 - 语法:
torch.Tensor(size, *, dtype=None, device=None, requires_grad=False)
或者直接从数据创建:
torch.Tensor(data)
- 示例:
import torch# 从数据创建
tensor = torch.Tensor([[1, 2], [3, 4]]) # 默认为 float32
print(tensor)# 根据大小创建
tensor = torch.Tensor(2, 2) # 初始化为未定义值
print(tensor)
- torch.IntTensor
- 用途:torch.IntTensor 是一个特定类型的张量类,用于表示整数型张量。它是 torch.Tensor 的子类,专门用于存储 32 位整数(int32)。
- 特点:
默认情况下,使用 32 位整数。
可以通过多种方式创建,包括从数据、大小或其他张量转换而来。 - 语法:
torch.IntTensor(size)
torch.IntTensor(data)
torch.IntTensor(tensor)
- 示例:
import torch# 从数据创建
int_tensor = torch.IntTensor([[1, 2], [3, 4]])
print(int_tensor)# 根据大小创建
int_tensor = torch.IntTensor(2, 2).zero_()
print(int_tensor)
总结
- torch.tensor 是一个灵活的工厂函数,可以根据输入数据自动推断类型并创建张量。
- torch.Tensor 是一个通用的张量类,默认创建浮点型张量,可以通过多种方式实例化。
- torch.IntTensor 是一个特定类型的张量类,专门用于存储整数型数据。
创建线性和随机张量
线性张量
1. torch.arange
- 用途:torch.arange 用于生成一个包含在指定范围内等间隔值的一维张量。类似于 Python 的 range 函数,但返回的是张量而不是列表。
- 语法:
torch.arange(start=0, end, step=1, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
start:起始值(默认为 0)。
end:结束值(不包含此值)。
step:步长(默认为 1)。
- 示例:
import torch# 生成从 0 到 9 的张量
tensor1 = torch.arange(10)
print(tensor1)
# 输出: tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])# 生成从 1 到 9,步长为 2 的张量
tensor2 = torch.arange(1, 10, 2)
print(tensor2)
# 输出: tensor([1, 3, 5, 7, 9])
2. torch.linspace
- 用途:torch.linspace 用于生成一个在指定范围内均匀分布的固定数量的值的一维张量。它适用于需要在一定范围内生成固定数量样本的场景。
- 语法:
torch.linspace(start, end, steps=100, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
start:起始值。
end:结束值。
steps:生成的样本数量(默认为 100)。
- 示例:
import torch# 生成从 0 到 1,包含 5 个均匀分布的值的张量
tensor1 = torch.linspace(0, 1, 5)
print(tensor1)
# 输出: tensor([0.0000, 0.2500, 0.5000, 0.7500, 1.0000])# 生成从 -1 到 1,包含 10 个均匀分布的值的张量
tensor2 = torch.linspace(-1, 1, 10)
print(tensor2)
# 输出: tensor([-1.0000, -0.7778, -0.5556, -0.3333, -0.1111, 0.1111, 0.3333, 0.5556, 0.7778, 1.0000])
总结
torch.arange 适合于生成基于步长的序列,适用于需要连续整数或等差序列的场景。
torch.linspace 适合于生成基于固定样本数量的均匀分布序列,适用于需要在一定范围内均匀采样的场景。
随机张量
在 PyTorch 中,torch.randn 是一个用于生成具有标准正态分布(均值为 0,标准差为 1)的随机张量的函数。这个函数在初始化权重、生成随机噪声等场景中非常常用。下面我将详细介绍 torch.randn 的用法和示例。
1. torch.randn
- 用途:生成一个形状为指定尺寸的张量,其中的元素是从标准正态分布中随机采样得到的。
- 语法:
torch.randn(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
*size:一个或多个整数,指定输出张量的形状。例如,torch.randn(2, 3) 将生成一个 2x3 的张量。
out:可选参数,用于指定输出张量的存储位置。
dtype:可选参数,指定张量的数据类型(如 torch.float32, torch.float64 等)。
layout:可选参数,指定张量的布局(默认为 torch.strided)。
device:可选参数,指定张量存储的设备(如 CPU 或 GPU)。
requires_grad:可选参数,如果设置为 True,则会跟踪该张量上的所有操作,用于自动求导。
示例 1:生成一维随机张量
import torch# 生成一个包含 5 个元素的一维张量
tensor1 = torch.randn(5)
print(tensor1)
输出:
tensor([ 0.1234, -1.2345, 0.6789, 1.2345, -0.9876])
示例 2:生成二维随机张量
import torch# 生成一个 2x3 的二维张量
tensor2 = torch.randn(2, 3)
print(tensor2)
输出:
tensor([[ 0.1234, -1.2345, 0.6789],[ 1.2345, -0.9876, 0.4567]])
示例 3:指定数据类型和设备
import torch# 生成一个 3x3 的张量,数据类型为 float64,并在 GPU 上创建(如果可用)
tensor3 = torch.randn(3, 3, dtype=torch.float64, device='cuda' if torch.cuda.is_available() else 'cpu')
print(tensor3)
输出示例(假设在 CPU 上运行)::
tensor([[ 0.1234, -1.2345, 0.6789],[ 1.2345, -0.9876, 0.4567],[ 0.7890, -0.3456, 1.2345]], dtype=torch.float64)
设置随机种子
为了确保每次生成的随机张量相同,可以设置随机种子。这在调试和复现实验结果时非常有用。
import torch# 设置随机种子
torch.manual_seed(0)# 生成一个 4x4 的随机张量
tensor4 = torch.randn(4, 4)
print(tensor4)
输出:
tensor([[ 1.5410, 0.0706, 0.1296, 0.2591],[-0.2605, -0.2517, -0.4523, -0.1193],[ 0.3510, 0.3938, -0.1992, -0.1487],[ 0.4154, -0.7246, 0.0898, -0.3092]])
通过设置相同的随机种子,每次运行上述代码都会生成相同的随机张量。
总结
- torch.randn 用于生成标准正态分布的随机张量,适用于需要随机初始化的场景。
- 可以通过指定 size 参数来控制张量的形状。
- 可以通过 dtype 和 device 参数来指定张量的数据类型和存储设备。
- 使用 torch.manual_seed 可以设置随机种子,确保生成的随机张量可复现。
Tensor常见属性
属性名 | 描述 |
---|---|
.shape | 返回 Tensor 的形状,即一个表示每个维度大小的元组。 |
.size() | 返回一个包含 Tensor 各维度大小的元组,与 .shape 类似。 |
.dim() | 返回 Tensor 的维度数。 |
.numel() | 返回 Tensor 中元素的总数。 |
.stride() | 返回一个元组,表示每个维度上步进到下一个元素所需的步长。 |
.storage() | 返回 Tensor 存储数据的存储对象。 |
.is_contiguous() | 检查 Tensor 是否是连续的,即数据是否在内存中紧密排列。 |
.requires_grad | 表示是否需要计算梯度。如果设置为 True,Tensor 的操作会被记录下来,以便进行自动梯度计算。 |
.grad_fn | 如果 Tensor 是通过计算得到的,.grad_fn 会引用创建它的函数。这对于自动梯度计算很重要。 |
.device | 返回 Tensor 所在的设备(例如 CPU 或 GPU)。 |
.dtype | 返回 Tensor 的数据类型(例如 torch.float32 、torch.int64 等)。 |
获取属性
示例代码:
import torch# 检查是否有可用的 GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("Using device:", device)# 创建一个 Tensor 并将其移动到指定设备
tensor = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
tensor = tensor.to(device)print("Tensor on device:", tensor.device) # 输出: Tensor on device: cuda:0 或 cpu# 如果需要,可以将 Tensor 移回 CPU
tensor_cpu = tensor.to("cpu")
print("Tensor back on CPU:", tensor_cpu.device) # 输出: Tensor back on CPU: cpu
切换设备
在 PyTorch 中,可以将 Tensor 从一个设备移动到另一个设备,例如从 CPU 移动到 GPU 或反之。这通常用于加速计算,因为 GPU 在处理大规模矩阵运算时比 CPU 更高效。
示例代码:
import torch# 检查是否有可用的 GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("Using device:", device)# 创建一个 Tensor 并将其移动到指定设备
tensor = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
tensor = tensor.to(device)print("Tensor on device:", tensor.device) # 输出: Tensor on device: cuda:0 或 cpu# 如果需要,可以将 Tensor 移回 CPU
tensor_cpu = tensor.to("cpu")
print("Tensor back on CPU:", tensor_cpu.device) # 输出: Tensor back on CPU: cpu
类型转换
在 PyTorch 中,可以轻松地将 Tensor 转换为不同的数据类型。这在需要不同精度或特定类型的操作时非常有用。
常见的数据类型转换方法
- .to(dtype):将 Tensor 转换为指定的数据类型。
- .float():将 Tensor 转换为 torch.float32 类型。
- .double():将 Tensor 转换为 torch.float64 类型。
- .int():将 Tensor 转换为 torch.int32 类型。
- .long():将 Tensor 转换为 torch.int64 类型。
示例代码:
import torch# 创建一个浮点型 Tensor
tensor_float = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
print("Original Tensor (float32):", tensor_float.dtype) # 输出: Original Tensor (float32): torch.float32# 转换为 double 类型
tensor_double = tensor_float.double()
print("Tensor converted to double:", tensor_double.dtype) # 输出: Tensor converted to double: torch.float64# 转换为整数类型
tensor_int = tensor_float.int()
print("Tensor converted to int32:", tensor_int.dtype) # 输出: Tensor converted to int32: torch.int32# 使用 .to 方法进行类型转换
tensor_long = tensor_float.to(torch.long)
print("Tensor converted to int64:", tensor_long.dtype) # 输出: Tensor converted to int64: torch.int64