深度学习之pytorch安装与tensor(张量)

一、Pytorch安装

PyTorch 是由 Facebook AI Research 开发的一个开源深度学习框架,因其灵活的设计和简洁的 Python 接口而受到广泛欢迎。它最大的特点是采用动态图机制,允许用户像写普通 Python 代码一样动态构建神经网络结构,便于调试与实验。此外,PyTorch 拥有类似 NumPy 的张量(Tensor)计算功能,并且支持 GPU 加速和自动求导(autograd),适用于各种深度学习任务。通过 torch.nn 模块,用户可以方便地构建和训练神经网络模型。得益于其强大的生态系统(如 torchvision、torchaudio 等)以及活跃的社区支持,PyTorch 在计算机视觉、自然语言处理、强化学习等领域中得到了广泛应用,是目前学术研究和工业项目中主流的深度学习框架之一。

首先打开GEFOORCE进行显卡驱动更新

接着在安装pytorch之前首先要查看自己电脑的CUDA版本号,win+r打开cmd,输入nvidia-smi查看GPU驱动程序版本

前往pytorch官网:https://pytorch.org/get-started/previous-versions/ 根据官方提供的安装指令安装比自己电脑CUDA版本号低的pytorch即可。

我这里选择的是安装这个上图这个版本。(由于安装包较大,建议在网络环境好的情况下进行安装,或使用VPN进行安装)

二、Pytorch核心---tensor

Tensor 是 PyTorch 的核心基础,几乎可以说是 PyTorch 的"灵魂"。

1.概念

在 PyTorch 中,Tensor(张量)是构建和操作神经网络的最基本数据结构 ,类似于 NumPy 的多维数组,但具有更强大的功能。Tensor 支持在 CPU 和 GPU 之间自由切换,能大幅提升深度学习任务的计算效率。此外,PyTorch 的自动求导机制(Autograd)正是围绕 Tensor 构建的,使其可以记录和追踪所有操作,从而在训练过程中实现反向传播和梯度更新。Tensor 不仅用于表示输入输出数据,还用于存储模型参数和中间计算结果,因此,熟练掌握 Tensor 的创建、变换、索引、广播及与 NumPy 的互操作,是学习和使用 PyTorch 的核心。简而言之,理解和掌握 Tensor 的使用,是深入学习 PyTorch 的第一步

  • 标量 :0 维张量,如 a = torch.tensor(5)
  • 向量 : 1 维张量,如 b = torch.tensor([2, 3, 4])
  • 矩阵 : 2 维张量,如 c = torch.tensor([[1, 2], [3, 4]])

2.tensor的创建

在pytorch中,tensor以"类"的形式封装起来,一些对tensor的运算、处理的方法都被封装在类中,详细请参考官方文档:https://pytorch.org/docs/stable/torch.html#tensors

接下来介绍几种创建tensor的基本方法。

  • torch.tensor()

torch.tensor() 是 PyTorch 中最常用、最通用的张量创建方法之一,它可以将 Python 中的列表、元组、NumPy 数组等数据结构直接转换为张量。

python 复制代码
import torch
import numpy as np


def test1():
    t1 = torch.tensor([1, 2, 3])
    print(t1)
    t2 = torch.tensor([[1, 2, 5], [3, 6, 9]])
    print(t2.shape)
    t3 = torch.tensor(np.random.randint(0, 10, (3, 4)))
    print(t3)


if __name__ == '__main__':
    test1()
# tensor([1, 2, 3])
# torch.Size([2, 3])
# tensor([[6, 5, 7, 1],
#         [9, 8, 4, 6],
#         [9, 4, 3, 5]], dtype=torch.int32)

torch.Tensor()

注意这里的Tensor是大写,该API根据形状创建张量,其也可用来创建指定数据的张量。

python 复制代码
import torch
import numpy as np

def test2():
    t1 = torch.Tensor([1, 2, 3])
    print(t1)
    t2 = torch.Tensor(3, 4)
    print(t2)


if __name__ == '__main__':
    test2()

# tensor([1., 2., 3.])
# tensor([[-7.1016e-18,  1.9002e-42,  0.0000e+00,  0.0000e+00],
#         [ 0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00],
#         [ 0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00]])

torch.tensor() 与 torch.Tensor()的区别:

比较项 torch.tensor() torch.Tensor()
推荐程度 ✅ 推荐使用 ❌ 不推荐(旧式风格)
用途 从已有数据创建一个张量副本 构造一个张量,行为取决于参数类型(可能是空张量)
是否初始化数据 是(复制输入数据) 不一定,传形状参数时不会初始化内容,类似 torch.empty()
参数支持 支持 dtypedevicerequires_gradcopy 不支持这么多参数,功能有限
常见用途 用于明确创建张量,如从 listnumpy 等创建 早期 PyTorch 用法,有潜在初始化错误风险
示例(安全) torch.tensor([1, 2, 3]) torch.Tensor([1, 2, 3])
示例(危险) - torch.Tensor(2, 3) → 得到未初始化的随机值

创建随机张量:

常见的创建随机张量的方法:

函数 作用说明 示例 输出说明
torch.rand(size) [0, 1)均匀分布中采样 torch.rand(3) [0, 1) 区间内的随机数
torch.randn(size) 从标准正态分布 N(0, 1) 中采样 torch.randn(3) 均值为 0,标准差为 1 的正态分布数
torch.randint(low, high, size) [low, high) 区间内生成整数随机数 torch.randint(0, 10, (3,)) 包括 0,不包括 10 的整数
torch.randperm(n) 生成 0 到 n-1 的随机排列 torch.randperm(5) 例如:tensor([3,1,4,0,2])
torch.empty(size).uniform_(a, b) [a, b) 区间内生成均匀分布 torch.empty(3).uniform_(0, 5) 更细粒度控制区间
torch.empty(size).normal_(mean, std) N(mean, std) 分布采样 torch.empty(3).normal_(0, 1) 控制均值与标准差的正态分布采样

在pytorch中可以使用使用torch.manual_seed()设置随机时间种子,通过设置随机数种子,可以做到模型训练和实验结果在不同的运行中进行复现。

示例:

python 复制代码
import torch
import numpy as np

def test3():
    # 设置随机时间种子
    torch.manual_seed(486)

    # 创建随机张量
    t1 = torch.rand(2, 3)
    t2 = torch.randn(2, 3)
    t3 = torch.randint(0, 10, (2, 3))
    print(t1)
    print(t2)
    print(t3)


if __name__ == '__main__':
    test3()

# tensor([[0.0247, 0.9529, 0.6178],
#        [0.8909, 0.8222, 0.7215]])
# tensor([[ 0.4583, -1.0574,  1.2331],
#        [-1.3427, -1.5409, -0.4013]])
# tensor([[1, 5, 9],
#        [5, 4, 7]])

注意:在不使用时间种子的情况下,每次打印的结果都不一样。

3.tensor常见操作

常见属性

属性/方法 说明 示例 返回值类型
tensor.size() 返回张量的尺寸(各维度大小) x.size() torch.Size 对象
tensor.shape 等同于 tensor.size(),更常用于访问属性 x.shape torch.Size 对象
tensor.ndim 返回张量的维度数 x.ndim int
tensor.numel() 返回张量中所有元素的总数 x.numel() int
tensor.dtype 数据类型 x.dtype torch.dtype
tensor.device 当前张量所在的设备(CPU/GPU) x.device torch.device
tensor.requires_grad 是否需要梯度计算 x.requires_grad bool
tensor.is_cuda 是否存储在 CUDA(GPU)上 x.is_cuda bool
tensor.T 转置(仅限 2D 张量) x.T Tensor

示例:

python 复制代码
import torch
import numpy as np

def test4():
    t1 = torch.tensor([[1, 3, 5], [2, 6, 9]])
    print(t1.shape, t1.size(), t1.dtype, t1.device)


if __name__ == '__main__':
    test4()
   
# torch.Size([2, 3]) torch.Size([2, 3]) torch.int64 cpu

注意:这里t1.shapet1.size()返回的都是torch.size,也就是张量的形状。

tensor转numpy

调用numpy()方法,这种方法属于浅拷贝,此时转换前和转换后的变量内存是共享的。

示例:

python 复制代码
import torch
import numpy as np

def test5():
    t1 = torch.tensor([1, 2, 3])
    new_t1 = t1.numpy()
    new_t1[0] = 100
    print(t1)


if __name__ == '__main__':
    test5()
    
# tensor([100,   2,   3])

调用numpy().copy()方法,这种方法属于深拷贝,能够避免内存共享。

示例:

python 复制代码
import torch
import numpy as np

def test6():
    t1 = torch.tensor([1, 2, 3])
    new_t1 = t1.numpy().copy()
    new_t1[0] = 100
    print(t1)


if __name__ == '__main__':
    test6()
   
# tensor([1, 2, 3])

numpy转tensor

调用from_numpy()方法转tensor,这种方法也属于浅拷贝。

python 复制代码
import torch
import numpy as np

def test7():
    data = np.array([1, 2, 3])
    t = torch.from_numpy(data)
    t[0] = 100
    print(data)

if __name__ == '__main__':
    test7()
    
# [100   2   3]

也可直接使用torch.tensor()将numpy数组转为tensor,这种方法为深拷贝,这里我就不再演示,这个方法也是创建tensor的方法。

获取单个元素值

我们可以使用item()方法来获取只有单个元素的tensor值。

python 复制代码
import torch
import numpy as np

def test8():
    t = torch.tensor([[666]])
    data = t.item()
    print(data)
    
if __name__ == '__main__':
    test8()
# 666

注意:这里说的是单个元素,也就是说无论维度是多少,**只要是单个元素的张量都能够获取到它的值,如果不是单个元素则会报错。**并且仅适用于CPU张量,如果张量在GPU上,需先移动到CPU。

设备切换

上面我们提到将张量移动到CPU,一般情况下在使用**torch.tensor()**创建张量时默认的设备为CPU,我们可以在创建张量时直接创建在GPU上:

python 复制代码
# 直接在GPU上创建张量
data = torch.tensor([1, 2, 3], device='cuda')
print(data.device)

也可以使用to()方法进行切换

python 复制代码
import torch
import numpy as np

def test9():
    t = torch.tensor([1, 2, 3])
    print(t.device)
    device = "cuda" if torch.cuda.is_available() else "cpu"
    t = t.to(device)
    print(t.device)

if __name__ == '__main__':
    test9()
# cpu
# cuda:0

阿达玛积

阿达玛积是指两个形状相同的矩阵或张量对应位置的元素相乘。它与矩阵乘法不同,矩阵乘法是线性代数中的标准乘法,而阿达玛积是逐元素操作。假设有两个形状相同的矩阵 A和 B,它们的阿达玛积 C=A∘B定义为:
Cij=Aij×Bij C_{ij}=A_{ij}×B_{ij} Cij=Aij×Bij

其中:

  • Cij 是结果矩阵 C的第 i行第 j列的元素。
  • Aij和 Bij分别是矩阵 A和 B的第 i行第 j 列的元素。

总结一句话就是两个矩阵的对应位置元素相乘

在pytorch中用mul()函数或*来实现:

python 复制代码
import torch
import numpy as np

def test10():
    t1 = torch.tensor([1, 2, 3])
    t2 = torch.tensor([2, 3, 4])
    t_a = t1 * t2
    t_b = t1.mul(t2)
    print(t_a)
    print(t_b)

    
if __name__ == '__main__':
    test10()

# tensor([ 2,  6, 12])
# tensor([ 2,  6, 12])

tensor相乘

矩阵乘法是线性代数中的一种基本运算,用于将两个矩阵相乘,生成一个新的矩阵。

假设有两个矩阵:

  • 矩阵 A的形状为 m×n(m行 n列)。
  • 矩阵 B的形状为 n×p(n行 p列)。

矩阵 A和 B的乘积 C=A×B是一个形状为 m×p的矩阵,其中 C的每个元素 Cij,计算 A的第 i行与 B的第 j列的点积。计算公式为:
Cij=∑k=1nAik×Bkj C_{ij}=∑{k=1}^nA{ik}×B_{kj} Cij=k=1∑nAik×Bkj

矩阵乘法运算要求如果第一个矩阵的shape是 (N, M),那么第二个矩阵 shape必须是 (M, P),最后两个矩阵点积运算的shape为 (N, P)。

pytorch中可以使用@或者matmul完整矩阵乘法运算:

python 复制代码
import torch

def test11():
    data1 = torch.tensor([
        [1, 2, 3],
        [4, 5, 6]
    ])
    data2 = torch.tensor([
        [3, 2],
        [2, 3],
        [5, 3]
    ])
    print(data1 @ data2)
    print(data1.matmul(data2))

if __name__ == '__main__':
    test11()

# tensor([[22, 17],
#        [52, 41]])
# tensor([[22, 17],
#        [52, 41]])

形状改变

在pytorch中可以使用reshape()view两种方法对张量的形状进行变换。

内存连续性 :张量的内存布局决定了其元素在内存中的存储顺序。对于多维张量,内存布局通常按照最后一个维度优先的顺序存储,即先存列,后存行。例如,对于一个二维张量 A,其形状为 (m, n),其内存布局是先存储第 0 行的所有列元素,然后是第 1 行的所有列元素,依此类推。

如果张量的内存布局与形状完全匹配,并且没有被某些操作(如转置、索引等)打乱,那么这个张量就是连续的。PyTorch 的大多数操作都是基于 C 顺序的,我们在进行变形或转置操作时,很容易造成内存的不连续性。

reshape和view变换张量形状的区别

特性 / 方法 reshape() view()
返回值类型 新的张量,可能是原张量的拷贝或视图 总是返回一个视图(view)
是否共享内存 可能共享,也可能不共享内存 一定共享内存(和原张量共用数据)
是否可用于非连续张量 ✅ 可以自动处理非连续张量 ❌ 只适用于连续内存张量
性能 通常略慢于 view()(因为可能涉及复制) 更快(仅改变视图而不复制)
失败风险 较低,自动处理多种情况 如果张量不连续,会抛出错误
适用场景推荐 更通用,推荐在不确定张量是否连续时使用 需要高性能并确认张量是连续时使

升维和降维:

降维: torch.squeeze()

python 复制代码
torch.squeeze(input, dim=None)
  • input:输入的张量。
  • dim (可选): 指定要移除的维度。如果指定了 dim,则只移除该维度(前提是该维度大小为 1);如果不指定,则移除所有大小为 1 的维度。若指定维度的大小不为1,虽然降维不会成功,但不会报错。

升维:torch。unsqueeze()

复制代码
torch.unsqueeze(input, dim)
  • input:输入的张量

  • dim: 指定要增加维度的位置(从 0 开始索引)。

以上内容是博主学习深度学习的一些总结笔记,若文章中出现错误请及时指正博主,感谢浏览☆噜~☆

相关推荐
大志说编程7 分钟前
LangChain框架入门09:什么是RAG?
人工智能·langchain
ezl1fe8 分钟前
RAG 每日一技(十四):化繁为简,统揽全局——用LangChain构建高级RAG流程
人工智能·后端·算法
一碗白开水一40 分钟前
【第6话:相机模型2】相机标定在自动驾驶中的作用、相机标定方法详解及代码说明
人工智能·数码相机·自动驾驶
The moon forgets40 分钟前
Occ3D: A Large-Scale 3D Occupancy Prediction Benchmark for Autonomous Driving
人工智能·pytorch·深度学习·目标检测·3d
新智元1 小时前
刚刚,马斯克 Grok4 干翻谷歌 Gemini!o3 杀入首届大模型对抗赛决战
人工智能·openai
张子夜 iiii1 小时前
机器学习算法系列专栏:逻辑回归(初学者)
人工智能·算法·机器学习·逻辑回归
foddcusL1 小时前
MATLAB深度学习之数据集-数据库构建方法详解
深度学习·matlab
nanxun___1 小时前
【多模态微调】【从0开始】Qwen2-VL + llamafactory
人工智能·python·深度学习·机器学习·语言模型
liupengfei-iot1 小时前
物联网后端系统架构:从基础到AI驱动的未来 - 第十章:AI促进IOT领域发生革命式发展
人工智能·物联网·系统架构
彭军辉2 小时前
什么是抽象主义人工智能?
人工智能·算法·语言模型·机器人