Machine Learning Academy · 课时

PyTorch 张量:创建、运算与 GPU 传输

您将从 Python 列表和 NumPy 数组创建张量,执行逐元素运算和矩阵运算,并使用 .to('cuda') 将张量移至 GPU。

第 1 / 4 课13 个步骤

PyTorch 张量:创建、运算与 GPU 传输 是 CoddyKit 上的免费 Machine Learning Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Machine Learning Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Machine Learning Academy 课程共包含 4 节课。

什么是 PyTorch tensor

tensor 是 PyTorch 中的基本数据结构,本质上是一种 n 维数组,类似于 NumPy 数组,但内置 GPU 支持和自动微分功能。tensor 可以是标量(0D)、向量(1D)、矩阵(2D)或更高维结构。PyTorch tensor 会跟踪计算历史,从而支持在训练神经网络时自动计算梯度。

import torch

# Scalar (0-dimensional tensor)
scalar = torch.tensor(3.14)
print(scalar.shape)   # torch.Size([])

# Vector (1D)
vector = torch.tensor([1.0, 2.0, 3.0])
print(vector.shape)   # torch.Size([3])

# Matrix (2D)
matrix = torch.tensor([[1, 2], [3, 4]])
print(matrix.shape)   # torch.Size([2, 2])

创建 tensor:常用方法

PyTorch 提供了许多工厂函数,用于创建具有特定值或形状的 tensor。torch.zeros 和 torch.ones 用常量填充 tensor;torch.rand 从均匀分布中采样;torch.randn 从标准正态分布中采样。这些函数是权重初始化和合成数据生成的基础。

import torch

zeros = torch.zeros(3, 4)        # 3x4 matrix of zeros
ones = torch.ones(2, 3)          # 2x3 matrix of ones
rand_uniform = torch.rand(3, 3)  # uniform in [0, 1)
rand_normal = torch.randn(3, 3)  # standard normal N(0,1)
arange = torch.arange(0, 10, 2) # [0, 2, 4, 6, 8]

print(zeros.dtype)    # torch.float32 (default)
print(arange)         # tensor([0, 2, 4, 6, 8])

从 NumPy 数组创建 tensor

您经常会从 NumPy 数组(例如来自 Pandas、scikit-learn 等)开始,并需要将其转换为 PyTorch tensor。torch.from_numpy 会与 NumPy 数组共享内存,因此修改其中一个也会修改另一个。相比之下,torch.tensor 会创建副本。了解两者的区别,可以避免数据流程中出现令人意外的错误。

import torch
import numpy as np

arr = np.array([1.0, 2.0, 3.0])

# Shares memory with arr
t_shared = torch.from_numpy(arr)

# Makes an independent copy
t_copy = torch.tensor(arr)

arr[0] = 99.0
print(t_shared)   # tensor([99.,  2.,  3.])  <- changed
print(t_copy)     # tensor([1., 2., 3.])     <- unchanged

tensor 数据类型(dtype)

tensor 具有用于控制数值精度和内存占用的 dtype。默认值是 torch.float32,它是神经网络权重的标准类型。torch.float64 可提供更高的精度,但内存占用会加倍;torch.int64 用于整数标签。不匹配的 dtype 会导致运行时错误,因此请始终使用 .float() 或 .to(dtype) 显式检查并转换类型。

import torch

f32 = torch.tensor([1.0, 2.0])         # float32 by default
f64 = torch.tensor([1.0, 2.0], dtype=torch.float64)
i64 = torch.tensor([1, 2, 3])          # int64 by default

print(f32.dtype)   # torch.float32
print(i64.dtype)   # torch.int64

# Cast to float32
labels = i64.float()
print(labels.dtype)   # torch.float32

逐元素算术运算

PyTorch 重载了标准 Python 算术运算符,使其能够对形状相同的 tensor 执行逐元素运算。加法、减法、乘法和除法都会逐元素执行。这些运算经过高度优化,当 tensor 位于 CUDA 设备上时会在 GPU 上运行。原地运算(例如 add_)会直接修改 tensor,而不会分配新内存。

import torch

a = torch.tensor([1.0, 2.0, 3.0])
b = torch.tensor([4.0, 5.0, 6.0])

print(a + b)     # tensor([5., 7., 9.])
print(a * b)     # tensor([ 4., 10., 18.])
print(b / a)     # tensor([4., 2.5, 2.])
print(a ** 2)    # tensor([1., 4., 9.])

# In-place add
a.add_(1.0)
print(a)         # tensor([2., 3., 4.])

使用 torch.matmul 进行矩阵乘法

矩阵乘法是每个神经网络层内部的核心运算。torch.matmul(或 @ 运算符)执行矩阵乘法,并通过广播自动处理矩阵批次。对于二维输入,它计算标准矩阵乘积;对于三维或更高维输入,它执行批量矩阵乘法。线性层正是通过 output = input @ weight.T + bias 进行计算的。

import torch

A = torch.randn(3, 4)   # 3x4
B = torch.randn(4, 5)   # 4x5
C = torch.matmul(A, B)  # 3x5
print(C.shape)           # torch.Size([3, 5])

# Equivalent using @ operator
C2 = A @ B
print(torch.allclose(C, C2))  # True

# Batched matmul
batch_A = torch.randn(8, 3, 4)  # batch of 8 matrices
batch_B = torch.randn(8, 4, 5)
result = batch_A @ batch_B       # torch.Size([8, 3, 5])

重塑 tensor:view 和 reshape

在不改变数据的情况下改变 tensor 的形状,是深度学习中最常见的运算之一。view 要求 tensor 在内存中连续,并返回一个视图(共享数据);reshape 可以处理不连续的 tensor,必要时会复制数据。您可以使用 -1 作为通配维度,PyTorch 会推断正确的大小。在进入线性层之前,将二维特征图展平为一维向量就是一个典型用例。

import torch

t = torch.arange(12).float()  # tensor of 12 elements
print(t.shape)                 # torch.Size([12])

m = t.view(3, 4)               # reshape to 3x4
print(m.shape)                 # torch.Size([3, 4])

m2 = t.view(2, -1)             # PyTorch infers 6 columns
print(m2.shape)                # torch.Size([2, 6])

# Flatten to 1D
flat = m.reshape(-1)
print(flat.shape)              # torch.Size([12])

广播:对不同形状执行运算

广播允许 PyTorch 通过隐式扩展维度,对形状不同的 tensor 执行运算。相关规则借鉴自 NumPy:从右侧对齐维度,并且大小为 1 的维度可以扩展,以匹配另一个 tensor。广播无需显式复制数据,从而节省内存。在神经网络层中,为批量输出矩阵添加偏置向量时,经常会使用广播。

import torch

# Matrix (3x4) + vector (4,)  -- vector broadcast over rows
matrix = torch.ones(3, 4)
bias = torch.tensor([1.0, 2.0, 3.0, 4.0])  # shape (4,)
result = matrix + bias
print(result.shape)   # torch.Size([3, 4])
print(result[0])      # tensor([2., 3., 4., 5.])

# Column vector (3,1) * row vector (1,4) -> (3,4)
col = torch.arange(1, 4).float().unsqueeze(1)  # (3,1)
row = torch.arange(1, 5).float().unsqueeze(0)  # (1,4)
print((col * row).shape)   # torch.Size([3, 4])

检查设备:CPU 与 CUDA

每个 tensor 都位于某个设备上:可以是 cpu,也可以是 cuda:0 这样的 CUDA GPU。使用 torch.cuda.is_available() 检查设备是否可用,可以编写不依赖特定设备的代码。参与同一计算的所有 tensor 必须位于同一设备上——尝试将 CPU tensor 与 GPU tensor 相加会引发运行时错误。标准做法是创建一个 device 变量,并将所有内容移动到该设备上。

import torch

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print('Using device:', device)

# Create tensor directly on the chosen device
t = torch.randn(3, 3, device=device)
print(t.device)

# Move an existing CPU tensor to the device
cpu_tensor = torch.tensor([1.0, 2.0, 3.0])
gpu_tensor = cpu_tensor.to(device)
print(gpu_tensor.device)

使用 .to('cuda') 将 tensor 移动到 GPU

对于大型模型,在 GPU 上训练神经网络可能比在 CPU 上快 10 到 100 倍。确认 CUDA 可用后,请使用 .to('cuda') 或 .cuda() 将 tensor 移动到 GPU。要转换为 NumPy,请使用 .cpu() 将其移回 CPU(NumPy 无法直接访问 GPU 内存)。在转换为 NumPy 之前,调用 .detach() 可以将 tensor 从计算图中移除。

import torch

# Simulate GPU workflow (falls back to CPU gracefully)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# Move model weights and data to GPU
weights = torch.randn(256, 128).to(device)
inputs = torch.randn(32, 128).to(device)  # batch of 32
outputs = inputs @ weights.T               # matmul on device
print(outputs.shape)   # torch.Size([32, 256])

# Convert back to NumPy for visualization
np_out = outputs.detach().cpu().numpy()
print(type(np_out))    # <class 'numpy.ndarray'>

实用的 tensor 属性和工具

若要调试和调整数据形状,多个 tensor 属性和工具函数都必不可少。.shape 提供各个维度的大小;.numel() 返回元素总数;.dtype 显示数据类型;.requires_grad 表示是否会跟踪梯度。torch.cat、torch.stack 和 torch.squeeze 等函数经常用于组装批次和移除大小为 1 的维度。

import torch

t = torch.randn(4, 3, 2)
print(t.shape)          # torch.Size([4, 3, 2])
print(t.numel())        # 24
print(t.dtype)          # torch.float32

# Concatenate along dim 0
a = torch.ones(2, 3)
b = torch.zeros(3, 3)
cat = torch.cat([a, b], dim=0)   # shape (5, 3)
print(cat.shape)

# Remove size-1 dimensions
x = torch.randn(1, 5, 1)
print(x.squeeze().shape)         # torch.Size([5])

快速检查

测试您对本课中 Python 机器学习概念的理解。

课程回顾

在本课中,您学习了以下内容:tensor 是 PyTorch 的核心数据结构,支持在 CPU 或 GPU 上处理 n 维数组;创建函数(例如 torch.zeros、torch.randn 和 torch.from_numpy)提供了灵活的数据初始化方式;以及使用 .to(device)将 tensor 移动到 GPU,是加速深度学习训练的关键步骤。接下来,我们将探索使用 Autograd 进行自动微分。

免费开始

用 AI 导师学习 Python — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
30
课程
120

常见问题解答

「PyTorch 张量:创建、运算与 GPU 传输」课时是免费的吗?

是的 — 「PyTorch 张量:创建、运算与 GPU 传输」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Machine Learning Academy 课程的其余内容,请升级到 CoddyKit PRO。 Machine Learning Academy 课程共包含 4 节课。

「PyTorch 张量:创建、运算与 GPU 传输」这节课中我会学到什么?

您将从 Python 列表和 NumPy 数组创建张量,执行逐元素运算和矩阵运算,并使用 .to('cuda') 将张量移至 GPU。 你通过在浏览器中直接运行的动手代码来练习 Machine Learning Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Machine Learning Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Machine Learning Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「PyTorch 张量:创建、运算与 GPU 传输」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Machine Learning Academy 课中编写并运行代码吗?

能。每节 Machine Learning Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. PyTorch 张量:创建、运算与 GPU 传输
  2. Autograd:用于反向传播的自动微分
  3. 使用 nn.Module 构建前馈网络
  4. 训练循环:损失、优化器与训练轮次
← 返回 Machine Learning Academy