1.图像数据操作和预处理
torchvision中的transforms模块可以针对每张图像进行预处理操作,在该模块
中提供了如表2-12所示的常用图像操作
In[2]:## 使用FashionMNIST数据,准备训练数据集train_data = FashionMNIST(root = "./data/FashionMNIST", # 数据的路径train = True, # 只获取训练数据集## 数据处理:先由HWC转置为CHW格式;再转为float32类型## 最后每个像素除以255。transform = transforms.ToTensor(), download= False # True:下载数据;False:从文件夹中读取)## 定义一个数据加载器train_loader = Data.DataLoader(dataset = train_data, shuffle = True, # 每次迭代前打乱数据batch_size=64, num_workers = 2 )## 计算train_loader有多少个batchprint("train_loader的batch数量为:",len(train_loader))
Out[2]:train_loader的batch数量为: 938
In[5]:## 读取图像train_data_dir = "data/chap2/imagedata/"train_data = ImageFolder( train_data_dir, transform=train_
data_transforms)train_data_loader = Data.DataLoader(train_data,batch_size=4,shuffle=True,num_workers=1)print("数据集的标签:",train_data.targets)## 获得一个batch的数据for step, (b_x, b_y) in enumerate(train_data_loader): if step > 0:break## 输出一个batch训练图像的尺寸和标签的尺寸print("b_x.shape:", b_x.shape)print("b_y.shape:", b_y.shape)print("图像的取值范围为:",b_x.min(),"~",b_x.max())
Out[5]:数据集的标签: [0, 0, 1, 2]
b_x.shape: torch.Size([4, 3, 224, 224])b_y.shape: torch.Size([4])图像的取值范围为: tensor(-2.1179) ~ tensor(2.6226)
## (注意,由于图像数据有随机操作,所以每次运行的可视化结果会有差异)plt.figure(figsize=(12,4))for ii in range(4):plt.subplot(1,4,ii+1)## 获取图像数据im = b_x.numpy()[ii,...].transpose((1,2,0))## 像素值标准化到0~1之间im = (im - im.min()) / (im.max() - im.min())plt.imshow(im), plt.axis("off")plt.tight_layout(), plt.show()
2.损失函数
深度学习的优化方法直接作用的对象是损失函数。损失函数就是用来表示预测与实际数据之间的差距程度。一个最佳化问题的目标是将损失函数最小化,针对分类问题,直观的表现就是分类正确的样本越多越好,在回归问题中,直观的表现就是预测值与实际值误差越小越好。
PyTorch中的nn模块提供了多种可直接使用的深度学习损失函数,如交叉熵、
均方误差等,针对不同的问题,可以直接调用现有的损失函数类。常用损失函数如表2-14所示。
(1)均方误差损失
torch.nn.MSELoss(size_average=None, reduce=None, reduction='mean')
(2)交叉熵损失
torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_
index=-100,
reduce = None, reduction='mean'):
3.优化器
PyTorch的optim模块提供了多种可直接使用的深度学习优化算法,内置算法包
括Adam、SGD、RMSprop等,无需人工实现随机梯度下降算法,直接调用即可。可直接调用的优化算法类优化器如表2-13所示。
表2-13列出了PyTorch中可直接调用的优化算法。这些优化方法的使用方式很
相似,下面以Adam算法为例,介绍优化器中参数的使用情况,以及如何优化所建立的网络。Adam类的使用方式如下所述
torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False
)
针对一个已经建立好的深度学习网络(testnet),定义优化器时通常使用下面的方式:
optimizer = Adam(testnet.parameters(),lr=0.001)
例如
import torch
import torch.nn as nn
import torch.optim as optim# 定义一个简单的神经网络
class SimpleNet(nn.Module):def __init__(self):super(SimpleNet, self).__init__()self.fc1 = nn.Linear(10, 50)self.relu = nn.ReLU()self.fc2 = nn.Linear(50, 1)def forward(self, x):x = self.fc1(x)x = self.relu(x)x = self.fc2(x)return x# 创建模型
model = SimpleNet()# 定义损失函数
criterion = nn.MSELoss()# 定义优化器
optimizer = optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)# 创建一些虚拟数据
inputs = torch.randn(100, 10) # 100 个样本,每个样本 10 个特征
targets = torch.randn(100, 1) # 100 个目标值# 训练模型
for epoch in range(10): # 训练 10 个 epochoptimizer.zero_grad() # 清空之前的梯度outputs = model(inputs) # 前向传播loss = criterion(outputs, targets) # 计算损失loss.backward() # 反向传播optimizer.step() # 更新参数print(f"Epoch {epoch+1}, Loss: {loss.item()}")