推荐使用 Anaconda 来管理 Python 环境,访问官网下载安装:
https://www.anaconda.com/download/success
请根据自己的系统平台(Windows/Linux/macOS)和 CUDA 版本访问以下链接获取安装命令:
https://pytorch.org/get-started/locally/
检查 CUDA 工具链是否安装成功:
!nvcc --version
测试 GPU 加速是否可用:
import torch
print(torch.cuda.is_available()) # True 表示当前设备支持 GPU 运算
import torch
import numpy as np
# 使用 PyTorch 生成 5x5 的随机整数矩阵,取值范围在 [0, 5)
# torch.randint(lower_bound, upper_bound, size)
A = torch.randint(0, 5, (5, 5))
print("Torch 矩阵 A:\n", A)
# 使用 NumPy 生成相同尺寸的随机整数矩阵
# np.random.randint(lower_bound, upper_bound, size)
A_np = np.random.randint(0, 5, (5, 5))
print("NumPy 矩阵 A_np:\n", A_np)
# 访问第 4 行第 3 列元素(从0开始)
print("A[3][2] =", A[3][2])
# 构造两个 5x6 的整数矩阵
A = torch.randint(0, 5, (5, 6))
B = torch.randint(0, 5, (5, 6))
A_np = np.random.randint(0, 5, (5, 6))
B_np = np.random.randint(0, 5, (5, 6))
C = A + B # 按元素相加
print("Torch 加法:\n", C)
C_np = A_np + B_np
print("NumPy 加法:\n", C_np)
C = A - B # 按元素相减
print("Torch 减法:\n", C)
C_np = A_np - B_np
print("NumPy 减法:\n", C_np)
C = A * B # 对应元素相乘
print("Torch 元素级乘法:\n", C)
C_np = A_np * B_np
print("NumPy 元素级乘法:\n", C_np)
# 对 B 进行转置后乘法,得到结果为 [5, 5]
C = torch.matmul(A, B.T)
print("Torch 矩阵乘法 matmul:\n", C)
C = A @ B.T # 简写形式
print("Torch 矩阵乘法 @:\n", C)
C = A.mm(B.T) # 旧API
print("Torch 矩阵乘法 mm:\n", C)
C_np = np.matmul(A_np, B_np.T)
print("NumPy 矩阵乘法:\n", C_np)
import matplotlib.pyplot as plt
torch.manual_seed(42) # 设置随机种子以确保结果一致
num_samples = 500 # 每类样本数量
dim = 2 # 每个样本的维度
# 类别 0:中心在 (-2, -2),协方差为单位阵
mean_0 = torch.tensor([-2.0, -2.0])
cov_0 = torch.eye(dim)
# 类别 1:中心在 (2, 2),协方差为单位阵
mean_1 = torch.tensor([2.0, 2.0])
cov_1 = torch.eye(dim)
# 从多元高斯分布中采样
class_0 = torch.distributions.MultivariateNormal(mean_0, cov_0).sample((num_samples,))
class_1 = torch.distributions.MultivariateNormal(mean_1, cov_1).sample((num_samples,))
# 创建标签
labels_0 = torch.zeros(num_samples, dtype=torch.long)
labels_1 = torch.ones(num_samples, dtype=torch.long)
# 合并数据与标签
X = torch.cat([class_0, class_1], dim=0)
y = torch.cat([labels_0, labels_1], dim=0)
# 打乱样本顺序
indices = torch.randperm(X.size(0))
X, y = X[indices], y[indices]
# 可视化
plt.figure(figsize=(6, 6))
plt.scatter(X[:, 0], X[:, 1], c=y, cmap="coolwarm", edgecolors="k", alpha=0.7)
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.title("二维高斯分布数据集")
plt.show()
torch.eye用法
import torch
I = torch.eye(3)
print(I)
tensor([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
from torch.utils.data import Dataset
class GaussianDataset(Dataset):
def __init__(self, X, y):
"""
初始化数据集
参数:
- X (Tensor): 特征数据,形状为 [样本数, 特征维度]
- y (Tensor): 标签数据,形状为 [样本数]
"""
self.X = X
self.y = y
def __len__(self):
"""
返回数据集总长度
"""
return len(self.X)
def __getitem__(self, index):
"""
获取第 index 个样本
参数:
- index (int): 样本索引
返回:
- tuple: (样本特征, 样本标签)
"""
return self.X[index], self.y[index]
from torch.utils.data import DataLoader
# 实例化数据集
dataset = GaussianDataset(X, y)
# 创建 Dataloader:按 batch_size 划分,每轮训练前打乱顺序
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
for batch_idx, batch in enumerate(dataloader):
data, label = batch
print("Batch 索引:", batch_idx)
print("数据形状:", data.shape)
print("标签形状:", label.shape)
print("第一个样本:", data[0])
print("对应标签:", label[0])
break # 只看一个批次
for batch_idx, batch in enumerate(dataloader):
data, label = batch
plt.figure(figsize=(6, 6))
plt.scatter(data[:, 0], data[:, 1], c=label, cmap="coolwarm", edgecolors="k", alpha=0.7)
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.title(f"第 {batch_idx+1} 个批次")
plt.show()
if batch_idx == 2: # 展示前 3 个批次即可
break
torch.randint
low
:最小值(含)high
:最大值(不含)size
:输出张量形状torch.distributions.MultivariateNormal
mean
:均值向量covariance_matrix
:协方差矩阵.sample((n,))
:采样 n 个样本DataLoader
dataset
:继承自 Dataset
的对象batch_size
:每个批次的样本数量shuffle
:是否打乱数据顺序plt.scatter
x, y
:二维数据坐标c
:颜色标签cmap
:颜色映射edgecolors
:边框颜色alpha
:透明度定义:
点乘是两个向量之间的操作,将两个一维向量压缩成一个标量(数值)。
设有两个长度为 n n n 的向量:
a = [ a 1 , a 2 , … , a n ] , b = [ b 1 , b 2 , … , b n ] \mathbf{a} = [a_1, a_2, \dots, a_n], \quad \mathbf{b} = [b_1, b_2, \dots, b_n] a=[a1,a2,…,an],b=[b1,b2,…,bn]
它们的点积(dot product)定义为:
a ⋅ b = ∑ i = 1 n a i ⋅ b i \mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i \cdot b_i a⋅b=i=1∑nai⋅bi
举例:
import torch
a = torch.tensor([1.0, 2.0, 3.0])
b = torch.tensor([4.0, 5.0, 6.0])
dot = torch.dot(a, b)
print(dot) # 输出:32.0 = 1×4 + 2×5 + 3×6
定义:
矩阵乘法是两个二维矩阵之间的乘积,满足以下维度条件:
若 A ∈ R m × n A \in \mathbb{R}^{m \times n} A∈Rm×n, B ∈ R n × k B \in \mathbb{R}^{n \times k} B∈Rn×k,
则它们的乘积为 C ∈ R m × k C \in \mathbb{R}^{m \times k} C∈Rm×k,其计算方式为:
C i , j = ∑ l = 1 n A i , l ⋅ B l , j C_{i,j} = \sum_{l=1}^{n} A_{i,l} \cdot B_{l,j} Ci,j=l=1∑nAi,l⋅Bl,j
即:第 i i i 行 × 第 j j j 列。
算法解释:
# 手动实现矩阵乘法(简化版本)
import torch
A = torch.tensor([[1., 2.],
[3., 4.]]) # 2x2
B = torch.tensor([[5., 6.],
[7., 8.]]) # 2x2
# 目标结果矩阵
C = torch.zeros(2, 2)
for i in range(2): # 遍历 A 的行
for j in range(2): # 遍历 B 的列
for k in range(2): # 对应维度求和
C[i][j] += A[i][k] * B[k][j]
print(C)
# 输出:
# tensor([[19., 22.], 19=5+14 22 = 6+16
# [43., 50.]]) 43 = 15+28 50= 18+32
等效 PyTorch 写法:
C = torch.matmul(A, B)
对比项 | 点乘(dot) | 矩阵乘法(matmul) |
---|---|---|
操作对象 | 一维向量 a , b \mathbf{a}, \mathbf{b} a,b | 二维矩阵 A , B A, B A,B |
输出 | 标量(单个数字) | 矩阵(新的二维张量) |
函数 | torch.dot(a, b) |
torch.matmul(A, B) or A @ B |
应用场景 | 计算相似度、投影、内积 | 神经网络权重变换、特征转换、线性层 |
# 举例说明区别
a = torch.tensor([1., 2., 3.])
b = torch.tensor([4., 5., 6.])
print("点乘结果:", torch.dot(a, b)) # 输出:32.0
A = torch.tensor([[1., 2.], [3., 4.]])
B = torch.tensor([[5., 6.], [7., 8.]])
print("矩阵乘法结果:\n", torch.matmul(A, B))
若有两个相同形状的矩阵:
A = [ a 11 a 12 a 21 a 22 ] , B = [ b 11 b 12 b 21 b 22 ] A = \begin{bmatrix} a_{11} & a_{12} \\\\ a_{21} & a_{22} \end{bmatrix}, \quad B = \begin{bmatrix} b_{11} & b_{12} \\\\ b_{21} & b_{22} \end{bmatrix} A= a11a21a12a22 ,B= b11b21b12b22
它们的 Hadamard 积 定义为:
C = A ⊙ B = [ a 11 ⋅ b 11 a 12 ⋅ b 12 a 21 ⋅ b 21 a 22 ⋅ b 22 ] C = A \odot B = \begin{bmatrix} a_{11} \cdot b_{11} & a_{12} \cdot b_{12} \\\\ a_{21} \cdot b_{21} & a_{22} \cdot b_{22} \end{bmatrix} C=A⊙B= a11⋅b11a21⋅b21a12⋅b12a22⋅b22
其中 ⊙ \odot ⊙ 表示逐元素相乘,即对应位置元素分别相乘,不进行矩阵乘法的求和操作。
import torch
A = torch.tensor([[1., 2.], [3., 4.]])
B = torch.tensor([[10., 20.], [30., 40.]])
C = A * B # Hadamard 积
print(C)
tensor([[10., 40.],
[90., 160.]])