当前位置: 首页 > news >正文

【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)
  1. 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.float32torch.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
http://www.dtcms.com/a/318648.html

相关文章:

  • 【0基础PS】PS工具详解--直接选择工具
  • TypeScript 数组类型精简知识点
  • 文本编码扫盲及设计思路总结
  • Mongodb入门介绍
  • [Python 基础课程]学生语文成绩录入和查询需求
  • [假面骑士] 555浅谈
  • AI大语言模型如何重塑软件开发与测试流程
  • Linux操作系统启动项相关研究与总结
  • 高速信号设计之 UPI2.0 篇
  • Spring Security 框架深度集成与开发指南
  • 如何设计一个开放授权平台?
  • 初识神经网络01——认识PyTorch
  • k8s的存储之statefulset控制器
  • 【MyBatis新手避坑】详解 `Could not find resource ...Mapper.xml` 错误
  • Class30数据增广
  • Leetcode刷题营:字符串相关--第35,36题
  • 深度探索:非静态内部类不能定义 static 成员属性和方法 及 静态内部类的必要性
  • 若依前后端分离版学习笔记(六)——JWT
  • K8S、Docker安全漏洞靶场
  • Go语言“fmt”包详解
  • KNN算法:从原理到实战应用
  • SDIO三种触发枚举的方式
  • Python高级排序技术:非原生可比对象的自定义排序策略详解
  • 第14届蓝桥杯Scratch选拔赛初级及中级(STEMA)真题2022年11月27日
  • Java面试宝典:类加载器分层设计与核心机制解析
  • 栈与队列的基本逻辑
  • ToonMe:将照片转换为卡通风格的艺术作品
  • docker run 入门到进阶:容器启动背后的门道
  • 嵌入式开发入门—电感器
  • CASA模型原理详细解析