PyTorch张量操作完全指南:从创建、运算到GPU加速与自动求导

2024-06-21 人工智能 193 次阅读 0 次点赞
本文全面介绍了PyTorch张量的核心操作,包括张量的定义(如zeros、ones、rand创建方法)、元素访问(类似NumPy的索引方式)、基本数学运算(加减乘除、矩阵乘法、转置)、与NumPy数组的互转、GPU加速计算(通过.cuda())以及自动求导机制。文章通过代码示例展示了各类操作,并重点解析了动态计算图与梯度计算过程。掌握这些基础知识是使用PyTorch进行深度学习开发的重要前提。

PyTorch作为深度学习领域最流行的框架之一,其核心数据结构是张量(Tensor)。本文将带你全面了解PyTorch中的张量操作,从基础定义到高级运算,帮助快速掌握PyTorch的数学运算能力。

定义张量

在PyTorch中,张量是多维数组的泛化,可以理解为更强大的NumPy数组。以下是三种最常见的张量创建方式:

import torch

# 创建全零张量
x = torch.zeros((3, 2))
print("全零张量:")
print(x)

# 创建全一张量
y = torch.ones((3, 2))
print("\n全一张量:")
print(y)

# 创建随机张量(均匀分布)
z = torch.rand((3, 2))
print("\n随机张量:")
print(z)

输出结果:

全零张量:
tensor([[0., 0.],
        [0., 0.],
        [0., 0.]])

全一张量:
tensor([[1., 1.],
        [1., 1.],
        [1., 1.]])

随机张量:
tensor([[0.9255, 0.9734],
        [0.3468, 0.9825],
        [0.3859, 0.7481]])

访问张量元素

掌握张量元素的访问是进行数据操作的基础,PyTorch提供了类似NumPy的索引方式:

import torch

# 创建5行3列的随机张量
a = torch.rand((5, 3))
print("原张量:")
print(a)

# 各种访问方式
print("\n第1行:")
print(a[0])

print("\n第1行第3列:")
print(a[0][2])
print(a[0, 2])  # 更简洁的写法

print("\n前2行:")
print(a[:2])

print("\n第2列:")
print(a[:, 1])

输出结果:

原张量:
tensor([[0.9835, 0.6304, 0.3341],
        [0.1006, 0.8246, 0.2030],
        [0.7149, 0.7477, 0.7167],
        [0.7997, 0.5218, 0.9917],
        [0.9539, 0.2919, 0.0582]])

第1行:
tensor([0.9835, 0.6304, 0.3341])

第1行第3列:
tensor(0.3341)
tensor(0.3341)

前2行:
tensor([[0.9835, 0.6304, 0.3341],
        [0.1006, 0.8246, 0.2030]])

第2列:
tensor([0.6304, 0.8246, 0.7477, 0.5218, 0.2919])

基本数学运算

PyTorch支持多种数学运算,包括元素级运算和矩阵运算:

import torch

x = torch.ones((2, 2)) * 2  # 所有元素为2
y = torch.ones((2, 2))       # 所有元素为1

# 基本运算
a = x.add(y)    # 加法:x + y
b = x.sub(y)    # 减法:x - y  
c = x.mul(y)    # 乘法(元素级):x * y
d = x.div(y)    # 除法:x / y
e = x.mm(y)     # 矩阵乘法
f = x.t()       # 转置

print("加法结果:")
print(a)
print("\n减法结果:")
print(b)
print("\n乘法结果:")
print(c)
print("\n除法结果:")
print(d)
print("\n矩阵乘法结果:")
print(e)
print("\n转置结果:")
print(f)

输出结果:

加法结果:
tensor([[3., 3.],
        [3., 3.]])

减法结果:
tensor([[1., 1.],
        [1., 1.]])

乘法结果:
tensor([[2., 2.],
        [2., 2.]])

除法结果:
tensor([[2., 2.],
        [2., 2.]])

矩阵乘法结果:
tensor([[4., 4.],
        [4., 4.]])

转置结果:
tensor([[2., 2.],
        [2., 2.]])

提示:使用 x.add()x.sub() 等方法不会修改原张量。如需原地修改,可使用 x.add_()x.sub_() 等带下划线的方法。

NumPy与张量互转

PyTorch张量和NumPy数组可以轻松互转,这在数据预处理时非常实用:

import torch
import numpy as np

# 创建张量和NumPy数组
x_tensor = torch.randn(2, 3)      # 正态分布随机张量
y_numpy = np.random.randn(2, 3)   # 正态分布随机数组

# 张量 → NumPy
x_numpy = x_tensor.numpy()

# NumPy → 张量
y_tensor = torch.from_numpy(y_numpy)
z_tensor = torch.FloatTensor(y_numpy)  # 另一种转换方式

print("转换后的NumPy数组:")
print(x_numpy)
print("\n从NumPy转换的张量:")
print(y_tensor)
print(z_tensor)

提示torch.rand() 生成均匀分布随机数,torch.randn() 生成标准正态分布随机数。

GPU加速运算

PyTorch的一大优势是能够利用GPU进行加速计算:

import torch

x = torch.rand(2, 3)
y = torch.randn(2, 3)

# 检查CUDA是否可用
cuda = torch.cuda.is_available()
print(f"CUDA可用: {cuda}")

if cuda:
    # 将张量移至GPU
    a = x.cuda()
    b = y.cuda()
    c = a + b
    print("\nGPU上的运算结果:")
    print(c)
    
    # 移回CPU
    a = a.cpu()
    b = b.cpu()
    c = a + b
    print("\nCPU上的运算结果:")
    print(c)

输出结果:

CUDA可用: True

GPU上的运算结果:
tensor([[ 0.5795,  0.7328,  1.2017],
        [ 1.3393,  0.9051, -0.1900]], device='cuda:0')

CPU上的运算结果:
tensor([[ 0.5795,  0.7328,  1.2017],
        [ 1.3393,  0.9051, -0.1900]])

自动求导与计算图

PyTorch的自动求导机制是其核心特性,通过动态计算图实现梯度计算:

import torch

# 创建需要梯度的张量
x = torch.ones(2, 2, requires_grad=True)
print("输入x:")
print(x.data)

# 前向传播
y = x + 2
print("\ny = x + 2:")
print(y.data)
print(f"y的梯度函数: {y.grad_fn}")

z = y * y
print("\nz = y * y:")
print(z.data)
print(f"z的梯度函数: {z.grad_fn}")

t = torch.mean(z)  # 对所有元素求平均
print("\nt = mean(z):")
print(t.data)

# 反向传播
t.backward()

# 查看梯度
print("\n梯度结果:")
print(f"x.grad: {x.grad}")

输出结果:

输入x:
tensor([[1., 1.],
        [1., 1.]])

y = x + 2:
tensor([[3., 3.],
        [3., 3.]])
y的梯度函数: <AddBackward0 object>

z = y * y:
tensor([[9., 9.],
        [9., 9.]])
z的梯度函数: <MulBackward0 object>

t = mean(z):
tensor(9.)

梯度结果:
x.grad: tensor([[1.5000, 1.5000],
                [1.5000, 1.5000]])

计算过程解析

整个计算过程可以用以下计算图表示:

x (2x2全1矩阵)
    ↓
y = x + 2  (每个元素+2)
    ↓
z = y * y  (每个元素平方)
    ↓
t = mean(z) = (z₁₁ + z₁₂ + z₂₁ + z₂₂) / 4

根据链式法则:

  • ∂t/∂z = 1/4
  • ∂z/∂y = 2y
  • ∂y/∂x = 1

因此: ∂t/∂x = ∂t/∂z × ∂z/∂y × ∂y/∂x = (1/4) × (2y) × 1 = y/2 = (x+2)/2

代入 x=1,得到 ∂t/∂x = (1+2)/2 = 1.5

总结

本文介绍了PyTorch张量的核心操作:

  • 张量创建:zeros、ones、rand等方法
  • 元素访问:类似NumPy的灵活索引方式
  • 数学运算:加减乘除、矩阵乘法、转置等
  • 数据转换:与NumPy的无缝互转
  • GPU加速:简单的.cuda()调用即可
  • 自动求导:通过动态计算图实现梯度计算

这些基础知识是使用PyTorch进行深度学习开发的基石。掌握这些操作后,你就可以开始构建自己的神经网络模型了。记住,多动手实践是掌握这些概念的最佳方式!

最后更新于1小时前
本文由人工编写,AI优化,转载请注明原文地址: PyTorch张量操作完全指南:从创建、运算到GPU加速与自动求导

评论 (0)

登录 后发表评论

暂无评论,快来发表第一条评论吧!