Task:
1.彩色和灰度图片测试和训练的规范写法:封装在函数中
2.展平操作:除第一个维度batchsize外全部展平
3.dropout操作:训练阶段随机丢弃神经元,测试阶段eval模式关闭dropout
作业:仔细学习下测试和训练代码的逻辑,这是基础,这个代码框架后续会一直沿用,后续的重点慢慢就是转向模型定义阶段了。
1. 彩色和灰度图片测试和训练的规范写法(封装在函数中):
-
目的: 将数据预处理和加载过程封装成函数,提高代码的可读性、可维护性和复用性。
-
关键步骤:
- 数据加载: 使用
torchvision.datasets
或自定义数据集类加载图像数据。 - 数据预处理: 使用
torchvision.transforms
定义一系列图像变换,例如:Resize()
:调整图像大小。ToTensor()
:将图像转换为 Tensor,并将像素值归一化到 [0, 1] 范围。Normalize()
:对图像进行标准化,使其具有零均值和单位方差。Grayscale()
:将彩色图像转换为灰度图像。
- 数据增强(仅训练集): 在训练集上应用随机变换,例如:
RandomHorizontalFlip()
:随机水平翻转图像。RandomRotation()
:随机旋转图像。RandomCrop()
:随机裁剪图像。
- 数据加载器: 使用
torch.utils.data.DataLoader
创建数据加载器,用于批量加载数据,并进行 shuffle 和多线程处理。
- 数据加载: 使用
-
函数示例:
import torch import torchvision from torchvision import transforms from torch.utils.data import DataLoaderdef load_data(data_dir, batch_size, is_train=True, grayscale=False):"""加载图像数据,并进行预处理。Args:data_dir (str): 数据集目录。batch_size (int): 批量大小。is_train (bool): 是否为训练集。grayscale (bool): 是否转换为灰度图像。Returns:torch.utils.data.DataLoader: 数据加载器。"""transform_list = []if is_train:transform_list.append(transforms.RandomHorizontalFlip())transform_list.append(transforms.RandomRotation(10)) # 随机旋转transform_list.append(transforms.Resize((224, 224))) # 调整大小if grayscale:transform_list.append(transforms.Grayscale())transform_list.append(transforms.ToTensor())transform_list.append(transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])) # 标准化transform = transforms.Compose(transform_list)dataset = torchvision.datasets.ImageFolder(data_dir, transform=transform)data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=is_train, num_workers=4)return data_loader
2. 展平操作:除第一个维度 batchsize 外全部展平
-
目的: 将卷积层或池化层的输出转换为一维向量,以便输入到全连接层。
-
方法: 使用
torch.flatten(x, start_dim=1)
函数,从第二个维度开始展平。 -
示例:
import torchx = torch.randn(32, 64, 7, 7) # batch_size=32, 64个特征图, 7x7大小 x_flattened = torch.flatten(x, start_dim=1) # 展平除 batch_size 以外的所有维度 print(x_flattened.shape) # 输出: torch.Size([32, 3136]) (64 * 7 * 7 = 3136)
3. Dropout 操作:训练阶段随机丢弃神经元,测试阶段 eval 模式关闭 dropout
-
目的: 防止过拟合,提高模型的泛化能力。
-
原理: 在训练过程中,随机将一部分神经元的输出设置为 0,迫使网络学习更鲁棒的特征。
-
实现: 使用
torch.nn.Dropout(p=0.5)
层,其中p
是丢弃概率。 -
关键点:
- 训练阶段:
model.train()
模式下,Dropout 层会随机丢弃神经元。 - 测试阶段:
model.eval()
模式下,Dropout 层会被禁用,所有神经元都会参与计算。 这确保了模型在测试时使用完整的网络结构进行预测。
- 训练阶段:
-
示例:
import torch import torch.nn as nnclass MyModel(nn.Module):def __init__(self):super(MyModel, self).__init__()self.fc1 = nn.Linear(100, 50)self.dropout = nn.Dropout(p=0.5)self.fc2 = nn.Linear(50, 10)def forward(self, x):x = torch.relu(self.fc1(x))x = self.dropout(x)x = self.fc2(x)return xmodel = MyModel()# 训练阶段 model.train() x = torch.randn(32, 100) output = model(x)# 测试阶段 model.eval() with torch.no_grad(): # 禁用梯度计算x = torch.randn(32, 100)output = model(x)
总结:
我理解了数据加载和预处理的重要性,以及如何使用 torchvision.transforms
和 torch.utils.data.DataLoader
来实现。 我也理解了展平操作的必要性,以及 Dropout 层在训练和测试阶段的不同行为。 这些都是构建深度学习模型的基础,我会继续深入学习和实践。