文章目录
1、概述
本篇博客用来记录,在深度学习过程中,常用的 python 语法内容
2、学习内容
2.1、pytorch 常见语法
2.1.1、sum
在 PyTorch 中,torch.sum()
是一个非常常用的函数,用于对张量(Tensor)进行求和操作。
它的核心作用是沿着指定的维度对张量元素进行累加,支持灵活的维度选择和结果维度保留。
函数定义
python
torch.sum(input, dim=None, keepdim=False, dtype=None) → Tensor
- input:输入的张量(Tensor)。
- dim:指定求和的维度(可以是单个整数或整数列表)。如果不指定(dim=None),则对整个张量的所有元素求和。
- keepdim:布尔值,是否保留被求和的维度。默认为 False(不保留),若设为 True,则返回的张量会在指定维度上保留大小为 1 的维度。
- dtype:可选参数,指定输出张量的数据类型。
对所有张量求和
python
import torch
x = torch.tensor([[1, 2], [3, 4]])
result = torch.sum(x) # 等价于 1 + 2 + 3 + 4
print(result) # 输出: tensor(10)
沿着指定维度求和
python
x = torch.tensor([[1, 2], [3, 4]])
# 按列求和(dim=0)
result_dim0 = torch.sum(x, dim=0) # 1+3, 2+4
print(result_dim0) # 输出: tensor([4, 6])
# 按行求和(dim=1)
result_dim1 = torch.sum(x, dim=1) # 1+2, 3+4
print(result_dim1) # 输出: tensor([3, 7])
保留维度求和
python
x = torch.tensor([[1, 2], [3, 4]])
# 按列求和(dim=0)
result_dim0 = torch.sum(x, dim=0) # 1+3, 2+4
print(result_dim0) # 输出: tensor([4, 6])
# 按行求和(dim=1)
result_dim1 = torch.sum(x, dim=1) # 1+2, 3+4
print(result_dim1) # 输出: tensor([3, 7])
2.1.2、广播机制
**广播机制(Broadcasting)**是 Python 的 NumPy 和 PyTorch 等科学计算库中的核心功能,它允许不同形状的张量/数组进行逐元素运算(如加法、乘法等),而无需显式复制数据。其核心目标是自动扩展较小数组的维度,使其与较大数组的维度匹配,从而简化代码并提高计算效率。
举例
python
import torch
x = torch.tensor([[1, 2], [3, 4]])
y = x + 10 # 标量 10 被广播为 [[10, 10], [10, 10]]
print(y)
# 输出:
# tensor([[11, 12],
# [13, 14]])
2.1.3、张量
在深度学习和科学计算中(如 PyTorch、TensorFlow),张量被定义为多维数组的通用数据结构,用于高效存储和操作数据。
维度(Rank):张量的"阶数",即数组的维度数量。
- 0阶(标量):单个数(如 5)。
- 1阶(向量):一维数组(如 [1, 2, 3])。
- 2阶(矩阵):二维数组(如 [[1, 2], [3, 4]])。
- 3阶及以上:三维及以上数组(如 [[[1, 2], [3, 4]], [[5, 6], [7, 8]]])。
形状(Shape):描述每个维度的大小。例如:
- 标量:()。
- 向量:(n,)。
- 矩阵:(m, n)。
- 三维张量:(a, b, c)。
张量在深度学习中的作用
- 数据表示:
图像:[通道数, 高度, 宽度](如 [3, 256, 256] 表示 RGB 图像)。
视频:[帧数, 通道数, 高度, 宽度]。 - 批次数据:[批次大小, ...](如 [128, 3, 256, 256] 表示 128 张图像)。
- 模型参数:神经网络的权重和偏置通常以张量形式存储。
- 高效计算:支持 GPU/TPU 加速,适用于大规模数据处理。
python
import torch
# 创建张量
scalar = torch.tensor(5) # 0阶张量 (标量)
vector = torch.tensor([1, 2, 3]) # 1阶张量 (向量)
matrix = torch.tensor([[1, 2], [3, 4]]) # 2阶张量 (矩阵)
tensor_3d = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) # 3阶张量
print("标量形状:", scalar.shape) # 输出: torch.Size([])
print("向量形状:", vector.shape) # 输出: torch.Size([3])
print("矩阵形状:", matrix.shape) # 输出: torch.Size([2, 2])
print("三维张量形状:", tensor_3d.shape) # 输出: torch.Size([2, 2, 2])
2.1.4、DataLoader
PyTorch 的 DataLoader
是深度学习训练中处理数据的核心工具之一,它通过高效的数据加载和预处理机制,显著提升了训练速度和灵活性。
核心功能
DataLoader
的主要目标是按需批量加载数据,并支持多线程/多进程加速、数据打乱、自动内存管理等功能。其核心功能包括:
- 批量处理(Batching)
将数据集划分为多个批次(batch),每个批次包含batch_size
个样本。
批量处理是深度学习模型训练的标准方式,可以充分利用 GPU 的并行计算能力。 - 数据打乱(Shuffling)
通过shuffle=True
参数,在每个epoch
开始时随机打乱数据顺序,避免模型学习到数据顺序的偏差。
如果需要自定义打乱逻辑,可通过sampler
参数传入自定义采样器(如RandomSampler
或WeightedRandomSampler
)。 - 多进程数据加载(Multi-worker)
通过num_workers
参数指定工作进程数量,利用多进程并行加载数据,减少主进程的等待时间。
适用于 CPU 密集型的数据预处理(如图像解码、数据增强)。 - 内存优化
按需加载数据(惰性计算),避免一次性加载整个数据集到内存。
支持自动释放不再使用的数据内存,防止内存泄漏。 - 自定义批处理逻辑
通过collate_fn
参数自定义如何将单个样本组合成一个批次(默认行为是简单堆叠张量)。
适用于处理不规则数据(如不同长度的文本序列)。 - 支持分布式训练
配合DistributedSampler
实现多设备(如多 GPU)的数据分片,确保每个设备只处理分配到的子集。
DataLoader的核心参数
使用步骤
- 定义DataSet
python
from torch.utils.data import Dataset
import os
from PIL import Image
class MyDataset(Dataset):
def __init__(self, root_dir, label_dir, transform=None):
self.root_dir = root_dir
self.label_dir = label_dir
self.transform = transform
self.paths = [os.path.join(root_dir, label_dir, f) for f in os.listdir(os.path.join(root_dir, label_dir))]
def __len__(self):
return len(self.paths)
def __getitem__(self, idx):
img_path = self.paths[idx]
image = Image.open(img_path)
label = self.label_dir # 示例:标签为目录名
if self.transform:
image = self.transform(image)
return image, label
- 创建DataLoader
将Dataset
实例传入DataLoader
,并配置参数:
python
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
# 数据预处理
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor()
])
# 初始化 Dataset
dataset = MyDataset(root_dir="data", label_dir="cats", transform=transform)
# 创建 DataLoader
dataloader = DataLoader(
dataset,
batch_size=32,
shuffle=True,
num_workers=4,
pin_memory=True
)
- 迭代使用DataLoader
在训练循环中按批次获取数据:
python
for epoch in range(10): # 10个epoch
for batch_idx, (images, labels) in enumerate(dataloader):
# images: (batch_size, channels, height, width)
# labels: (batch_size,)
print(f"Epoch {epoch}, Batch {batch_idx}, Images shape: {images.shape}")
# 训练模型...
2.2、普通语法
2.2.1、迭代器
在Python中,迭代器(Iterator)是一种逐个访问数据集合的机制,它通过__iter__()
和__next__()
方法实现对数据的按需读取。迭代器的核心特性包括惰性计算、内存高效和统一的遍历接口,这些特性使其在处理大规模数据(如深度学习训练数据)时尤为重要。
基本原理
- 可迭代对象(Iterable):支持逐个返回元素的对象(如列表、字典、字符串等),通过
__iter__()
方法返回一个迭代器。 - 迭代器(Iterator):通过
__next__()
方法逐个获取元素,当没有更多元素时抛出StopIteration异常。 - 惰性计算:迭代器不会一次性加载所有数据到内存,而是按需生成下一个值,从而节省内存资源。
核心特性
- 逐项访问:每次调用
next()
获取一个元素,直到数据耗尽。 - 内存高效:适用于处理大型数据集,避免一次性加载全部数据。
- 统一接口:所有迭代器遵循相同的
__iter__()
和__next__()
协议,便于与for循环、生成器等协同工作。
代码实现
- 内置迭代器
Python的内置数据结构(如列表、字典、字符串)都可以通过iter()
函数转换为迭代器:
python
numbers = [1, 2, 3]
iterator = iter(numbers)
print(next(iterator)) # 输出: 1
print(next(iterator)) # 输出: 2
- 自定义迭代器
通过实现__iter__()
和__next__()
方法定义自定义迭代器:
python
class MyRange:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current < self.end:
num = self.current
self.current += 1
return num
else:
raise StopIteration
for i in MyRange(1, 4):
print(i) # 输出: 1, 2, 3
- 数据生成器
生成器是更简洁的迭代器实现方式,通过yield
关键字逐个返回值:
python
def my_generator():
yield 1
yield 2
yield 3
for value in my_generator():
print(value) # 输出: 1, 2, 3
迭代器和深度学习的关联
在深度学习中,数据通常是大规模的(如图像数据集、文本语料库等),直接加载所有数据到内存会导致内存不足。迭代器通过按需加载和批处理(batching)解决了这一问题,成为深度学习框架(如PyTorch、TensorFlow)的核心组件。
pytorch 的 DataLoader
python
from torch.utils.data import DataLoader, TensorDataset
import torch
# 创建虚拟数据
features = torch.randn(1000, 10) # 1000个样本,每个样本10个特征
labels = torch.randint(0, 2, (1000,)) # 二分类标签
dataset = TensorDataset(features, labels)
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
for batch_features, batch_labels in dataloader:
# 每个batch包含32个样本
print(batch_features.shape) # 输出: torch.Size([32, 10])