Pytorch数据转换&数据增强
数据预处理:( torchvision.transform() )
- 调整数据格式、大小和范围,使其适合模型输入。
- 例如,图像需要调整为固定大小、张量格式并归一化到 [ 0 , 1 ] [0,1] [0,1] 。
数据增强:
- 在训练时对数据进行变换,以增加多样性。
- 例如,通过随机旋转、翻转和裁剪增加数据样本的变种,避免过拟合。
灵活性:
- 通过定义一系列转换操作,可以动态地对数据进行处理,简化数据加载的复杂度。
基础操作
from torch torchvision import transforms
transform = transforms.Compose( [transforms.ToTensor(), transforms.Normalize( (0.5,), (0.5,) )] )
- transforms.ToTensor()
将 PIL 图像或 NumPy 数组转换为 PyTorch 张量。同时将像素值从 [ 0 , 255 ] [0,255] [0,255] 归一化为 [ 0 , 1 ] [0,1] [0,1] 。 - Normalize
对数据进行标准化,使其符合特定的均值和标准差。
通常用于图像数据,将其像素值归一化为零均值和单位方差。
transform = transforms.Normalize(mean=[0.485, 0.456,0.406], std=[0.229,0.224,0.225])
- Resize
调整图像的大小。
transform = transforms.Resize((128, 128))
- CenterCrop
从图像中心裁剪指定大小的区域。
transform = transforms.CenterCrop(128)
| 函数名称 | 描述 | 实例 |
|---|---|---|
| transforms.Ran domHorizontal Flip(p) | 随机水平翻转图像。 | transform= transforms.RandomHorizontalFlip( p = 0.5 \mathrm{p}=0.5 p=0.5 ) |
| transforms.Ran domRotation(d egrees) | 随机旋转图像。 | transform= transforms.RandomRotation(degrees=45) |
| transforms.Col orJitter(brightn ess,contrast, saturation, hue) | 调整图像的亮度、对比度、饱和度和色调。 | transform= transforms.ColorJitter(brightness=0.2, contrast = 0.2 =0.2 =0.2 ,saturation = 0.2 =0.2 =0.2 ,hue = 0.1 =0.1 =0.1 ) |
| transforms.Ran domCrop(size) | 随机裁剪指定大小的区域。 | transform=transforms.RandomCrop(224) |
| transforms.Ran domResizedCro p(size) | 随机裁剪图像并调整到指定大小。 | transform= transforms.RandomResizedCrop(224) |
- 通过 transforms.Compose 可将多个变换进行组合
transform = transforms.Compose([
transforms.Resize((128, 128)),
transforms.RandomHorizontalFlip(p=0.5),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5], std=[0.5])
])
torch API 数学运算 随机数 线性代数 手册
| 类别 | API | 描述 |
|---|---|---|
| Tensors | is_tensor(obj) | 检查 obj 是否为 PyTorch 张量。 |
| is_storage(obj) | 检查 obj 是否为 PyTorch 存储对象。 | |
| is_complex(inp ut) | 检查 input 数据类型是否为复数数据类型。 | |
| is_conj(input) | 检查 input 是否为共轭张量。 | |
| is_floating_poi nt(input) | 检查 input 数据类型是否为浮点数据类型。 | |
| is_nonzero(inp ut) | 检查 input 是否为非零单一元素张量。 | |
| set_default_dty pe(d) | 设置默认浮点数据类型为 d 。 | |
| get_default_dt ype() | 获取当前默认浮点 torch.dtype。 | |
| set_default_de vice(device) | 设置默认 torch.Tensor 分配的设备为 device。 | |
| get_default_de vice() | 获取默认 torch.Tensor 分配的设备。 | |
| numel(input) | 返回 input 张量中的元素总数。 | |
| Creation Ops | tensor(data) | 通过复制 data 构造无自动梯度历史的张量。 |
| sparse_coo_te nsor(indices, values) | 在指定的 indices 处构造稀疏张量,具有指定的值。 | |
| as_tensor(data ) | 将 data 转换为张量,共享数据并尽可能保留自动梯度历史。 | |
| zeros(size) | 返回一个用标量值 0 填充的张量,形状由 size 定义。 | |
| ones(size) | 返回一个用标量值 1 填充的张量,形状由 size 定义。 | |
| arange(start, end,step) | 返回一个 1-D 张量,包含从 start 到 end 的值,步长为 step。 | |
| rand(size) | 返回一个从 [ 0 , 1 ) [0,1) [0,1) 区间均匀分布的随机数填充的张量。 | |
| randn(size) | 返回一个从标准正态分布填充的张量。 | |
| Math operations | add(input, other,alpha) | 将 other(由 alpha缩放)加到 input 上。 |
| mul(input, other) | 将 input 与 other 相乘。 | |
| matmul(input, other) | 执行 input 和 other 的矩阵乘法。 | |
| mean(input, dim) | 计算 input 在维度 dim 上的均值。 | |
| sum(input, dim) | 计算 input 在维度 dim 上的和。 | |
| max(input, dim) | 返回 input 在维度 dim 上的最大值。 | |
| min(input, dim) | 返回 input 在维度 dim 上的最小值。 |
import torch
my_device = torch.device('cpu')
torch.set_default_device(my_device)
a = torch.tensor(2)
print( torch.is_tensor(a)
, torch.is_floating_point(a)
, torch.get_default_device()
, torch.numel(torch.zeros([2,3]))
)
# 创建一个复数张量
x = torch.tensor([-1 + 1j, 2 - 3j])
# 获取共轭视图 (O(1) 复杂度)
y = torch.conj(x)
print(y) # 输出: tensor([-1.-1.j, 2.+3.j])
print(y.is_conj()) # 输出: True
| 函数 | 描述 |
|---|---|
| torch.tensor(data,dtype,device,requires_grad) | 从数据创建张量。 |
| torch.as_tensor(data,dtype,device) | 将数据转换为张量(共享内存)。 |
| torch.from_numpy(ndarray) | 从 NumPy 数组创建张量(共享内存)。 |
| torch.zeros(*size,dtype,device,requires_grad) | 创建全零张量。 |
| torch.ones(*size,dtype,device,requires_grad) | 创建全一张量。 |
| torch.empty(*size,dtype,device,requires_grad) | 创建未初始化的张量。 |
| torch.arange(start,end,step,dtype,device, requires_grad) | 创建等差序列张量。 |
| torch.linspace(start,end,steps,dtype,device, requires_grad) | 创建等间隔序列张量。 |
| torch.logspace(start,end,steps,base,dtype, device,requires_grad) | 创建对数间隔序列张量。 |
| torch.eye(n,m,dtype,device,requires_grad) | 创建单位矩阵。 |
| torch.full(size,fill_value,dtype,device, requires_grad) | 创建填充指定值的张量。 |
| torch.rand(*size,dtype,device,requires_grad) | 创建均匀分布随机张量(范围[0, 1))。 |
| torch.randn(*size,dtype,device,requires_grad) | 创建标准正态分布随机张量。 |
| torch.randint(low,high,size,dtype,device, requires_grad) | 创建整数随机张量。 |
| torch.randperm(n,dtype,device,requires_grad) | 创建 0 到 n − 1 \mathrm{n}-1 n−1 的随机排列。 |
# rand返回均匀分布
# randn返回正态分布
print(torch.rand([2,3])
, torch.arange(0,1,0.1)
, torch.randn([2,3])
, torch.eye(3)
)
| 函数 | 描述 |
|---|---|
| torch.add(input,other) | 逐元素加法。 |
| torch.sub(input,other) | 逐元素减法。 |
| torch.mul(input,other) | 逐元素乘法。 |
| torch.div(input,other) | 逐元素除法。 |
| torch.matmul(input,other) | 矩阵乘法。 |
| torch.pow(input,exponent) | 逐元素幂运算。 |
| torch.sqrt(input) | 逐元素平方根。 |
| torch.exp(input) | 逐元素指数函数。 |
| torch.log(input) | 逐元素自然对数。 |
| torch.sum(input,dim) | 沿指定维度求和。 |
| torch.mean(input,dim) | 沿指定维度求均值。 |
| torch.max(input,dim) | 沿指定维度求最大值。 |
| torch.min(input,dim) | 沿指定维度求最小值。 |
| torch.abs(input) | 逐元素绝对值。 |
| torch.clamp(input,min,max) | 将张量值限制在指定范围内。 |
| torch.round(input) | 逐元素四舍五入。 |
| torch.floor(input) | 逐元素向下取整。 |
| torch.ceil(input) | 逐元素向上取整。 |
| 函数 | 描述 |
|---|---|
| torch.manual_seed(seed) | 设置随机种子。 |
| torch.initial_seed() | 返回当前随机种子。 |
| torch.rand(*size) | 创建均匀分布随机张量(范围 [ 0 [0 [0 , 1))。 |
| torch.randn(*size) | 创建标准正态分布随机张量。 |
| torch.randint(low,high,size) | 创建整数随机张量。 |
| torch.randperm(n) | 返回 0 到 n − 1 n-1 n−1 的随机排列。 |
矩阵运算:
| 函数 | 描述 |
|---|---|
| torch.dot(input,other) | 计算两个向量的点积。 |
| torch.mm(input,mat2) | 矩阵乘法。 |
| torch.bmm(input,mat2) | 批量矩阵乘法。 |
| torch.eig(input) | 计算矩阵的特征值和特征向量。 |
| torch.svd(input) | 计算矩阵的奇异值分解。 |
| torch.inverse(input) | 计算矩阵的逆。 |
| torch.det(input) | 计算矩阵的行列式。 |
| torch.trace(input) | 计算矩阵的迹。 |
设备管理
| 函数 | 描述 |
|---|---|
| torch.cuda.is_available() | 检查 CUDA 是否可用。 |
| torch.device(device) | 创建一个设备对象(如'cpu'或'cuda:0')。 |
| torch.to(device) | 将张量移动到指定设备。 |
print( torch.trace( torch.ones([3,3]) ) )
print( torch.det(torch.ones([2,2])) )
# print( torch.inverse(torch.ones([2,2])) )
print( torch.cuda.is_available() )
torch.nn 参考手册
- 推荐使用 torch.nn 的情况:
- 当需要在模型定义(__init__)中统一配置参数(如 weight 或 reduction),并在整个训练过程中复用该配置时。
- 当希望将损失函数视为网络的一层,方便使用 nn .Sequential 等容器管理时。
- 推荐使用 torch.nn.functional 的情况:
- 在损失函数不需要存储任何状态或参数时(如简单的 F.mse_loss),可以直接在 forward 过程中使用以减少代码量。
- 在进行复杂的自定义损失计算,或者需要动态改变损失计算逻辑时,函数式接口更加灵活。
| 类/函数 | 描述 |
|---|---|
| torch.nn.ReLU() | ReLU 激活函数。 |
| torch.nn.Sigmoid() | Sigmoid 激活函数。 |
| torch.nn. Tanh ( ) \operatorname{Tanh}() Tanh() | Tanh 激活函数。 |
| torch.nn.Softmax(dim) | Softmax 激活函数。 |
| torch.nn.LogSoftmax(dim) | LogSoftmax 激活函数。 |
| torch.nn.LeakyReLU(negative_slope) | LeakyReLU 激活函数。 |
| torch.nn.ELU(alpha) | ELU 激活函数。 |
| torch.nn.SELU() | SELU 激活函数。 |
| torch.nn.GELU() | GELU 激活函数。 |
torch.nn.Sequential
torch.nn.Sequential 是 PyTorch 中常用的容器之一,用于按照固定的顺序将多个网络层组合在一起:
- 数据会按照你定义的顺序,逐层通过容器中的每一个模块。前一层的输出自动作为后一层的输入;
- 由于模块间的连接逻辑是固定的串行关系,故不再需要手动编写 forward 函数中的每一行调用逻辑,系统会自动完成链式传递;
- 可以将 Sequential 包装的一组层视为一个单一的模块。对其进行操作(如 .to(device) 或参数初始化)会递归地作用于其包含的所有子层。
场景:
- 模型快速原型设计:当网络结构是简单的直线堆叠(无残差连接、无分支)时。
- 模块化构建:例如在大型网络中,将卷积、BN 和激活函数封装成一个“基础块”。
使用方式示例1(搭建小网络):
import torch
import torch.nn as nn
# 定义一个简单的全连接网络
model = nn.Sequential(
nn.Flatten(), # 将输入展平
nn.Linear(28 * 28, 512), # 第一个全连接层
nn.ReLU(), # 激活层
nn.Linear(512, 10) # 输出层
)
# 测试运行
input_data = torch.randn(1, 1, 28, 28)
output = model(input_data)
print(output.shape) # 输出: torch.Size([1, 10])
使用方式示例2:使用 collections.OrderedDict 可以为每一层指定名称,方便查看模型结构
from collections import OrderedDict
model = nn.Sequential(OrderedDict([
('conv_layer', nn.Conv2d(1, 20, 5)),
('active_func', nn.ReLU()),
('pooling', nn.MaxPool2d(2, 2))
]))
# 访问特定层
print(model.conv_layer)
在使用 nn.Sequential 封装好多个基础模块(例如:卷积块、残差块、全连接块)后,构建深层模型时,可将这些封装好的 Sequential 对象作为子组件,嵌入到一个更大的 nn.Module 类中,或者嵌套进更高级别的 nn.Sequential 中:
在 nn.Module 的 init 中实例化多个 Sequential 模块,并在 forward 中定义它们的执行顺序。这种方式支持在模块间加入非线性分支(如残差连接):
import torch
import torch.nn as nn
class DeepNet(nn.Module):
def __init__(self):
super(DeepNet, self).__init__()
# 封装模块 A:特征提取层
self.feature_extractor = nn.Sequential(
nn.Conv2d(3, 64, 3),
nn.ReLU(),
nn.MaxPool2d(2)
)
# 封装模块 B:中间处理层
self.middle_processor = nn.Sequential(
nn.Linear(64 * 13 * 13, 512),
nn.ReLU()
)
# 封装模块 C:输出层
self.classifier = nn.Sequential(
nn.Dropout(0.5),
nn.Linear(512, 10)
)
def forward(self, x):
x = self.feature_extractor(x)
x = torch.flatten(x, 1) # 展平
x = self.middle_processor(x)
x = self.classifier(x)
return x
model = DeepNet()
模型保存与加载
1.训练中断恢复:当训练过程意外中断时,可以从保存点继续训练
2.模型部署:将训练好的模型部署到生产环境
3.模型共享:方便团队成员之间共享模型成果
4.迁移学习:保存预训练模型用于其他任务
5.性能评估:保存不同训练阶段的模型进行比较
示例1(保存结构与参数):
# 保存整个模型
torch.save(model, 'model.pth')
# 加载整个模型
loaded_model = torch.load('model.pth')
示例2(保存状态字典state_dict):
# 保存模型参数
torch.save(model.state_dict(), 'model_weights.pth')
# 加载模型参数
model = models.resnet18() # 必须先创建相同架构的模型
model.load_state_dict(torch.load('model_weights.pth'))
model.eval() # 设置为评估模式
示例3(保存加载训练状态(优化器、epoch等信息))
# 保存检查点
checkpoint = {
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'loss': loss,
# 可以添加其他需要保存的信息
}
torch.save(checkpoint, 'checkpoint.pth')
# 加载检查点
checkpoint = torch.load('checkpoint.pth')
model.load_state_dict(checkpoint['model_state_dict'])
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
epoch = checkpoint['epoch']
loss = checkpoint['loss']
model.eval() # 或者 model.train() 取决于你的需求
1167

被折叠的 条评论
为什么被折叠?



