长春网站公司有哪些内容,六安建设机械网站,网页设计的网站,天元建设集团有限公司青岛第二建筑工程分公司#x1f368; 本文为#x1f517;365天深度学习训练营中的学习记录博客#x1f356; 原作者#xff1a;K同学啊
#x1f37a;要求#xff1a;
训练过程中保存效果最好的模型参数。
加载最佳模型参数识别本地的一张图片。
调整网络结构使测试集accuracy到达88%#x… 本文为365天深度学习训练营中的学习记录博客 原作者K同学啊
要求
训练过程中保存效果最好的模型参数。
加载最佳模型参数识别本地的一张图片。
调整网络结构使测试集accuracy到达88%重点。
拔高可选
调整模型参数并观察测试集的准确率变化。
尝试设置动态学习率。
测试集accuracy到达90%。 本周的代码相对于上周增加指定图片预测与保存并加载模型这个两个模块在学习这个两知识点后时间有余的同学请自由探索更佳的模型结构以提升模型是识别准确率模型的搭建是深度学习程度的重点。 我的环境
语言环境Python3.8
编译器Jupyter Lab
深度学习环境Pytorch
一、 前期准备
1. 设置GPU 如果设备上支持GPU就使用GPU,否则使用CPU。
import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms, datasetsimport os,PIL,pathlibdevice torch.device(cuda if torch.cuda.is_available() else cpu)device
device(typecuda)
2. 导入数据
import os,PIL,random,pathlibdata_dir /kaggle/input/monkey-images/monkey/#这里路径要完整记得最右边的/不要忘了直接从数据集右边的类别的上一级目录复制路径即可
data_dir pathlib.Path(data_dir)data_paths list(data_dir.glob(*))
classeNames [str(path).split(/)[5] for path in data_paths] # 这里记得kaggle里面是/然后后面的[]的索引里面记得取数据集的路径层级
classeNames
[Monkeypox, Others]
第一步使用pathlib.Path()函数将字符串类型的文件夹路径转换为pathlib.Path对象。第二步使用glob()方法获取data_dir路径下的所有文件路径并以列表形式存储在data_paths中。第三步通过split()函数对data_paths中的每个文件路径执行分割操作获得各个文件所属的类别名称并存储在classeNames中第四步打印classeNames列表显示每个文件所属的类别名称。
total_datadir /kaggle/input/monkey-images/monkey/# 关于transforms.Compose的更多介绍可以参考https://blog.csdn.net/qq_38251616/article/details/124878863
train_transforms transforms.Compose([transforms.Resize([224, 224]), # 将输入图片resize成统一尺寸transforms.ToTensor(), # 将PIL Image或numpy.ndarray转换为tensor并归一化到[0,1]之间transforms.Normalize( # 标准化处理--转换为标准正太分布高斯分布使模型更容易收敛mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) # 其中 mean[0.485,0.456,0.406]与std[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
])total_data datasets.ImageFolder(total_datadir,transformtrain_transforms)
total_data
Dataset ImageFolderNumber of datapoints: 2142Root location: /kaggle/input/monkey-images/monkey/StandardTransform
Transform: Compose(Resize(size[224, 224], interpolationbilinear, max_sizeNone, antialiasTrue)ToTensor()Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]))
total_data.class_to_idx
{Monkeypox: 0, Others: 1} total_data.class_to_idx是一个存储了数据集类别和对应索引的字典。在PyTorch的ImageFolder数据加载器中根据数据集文件夹的组织结构每个文件夹代表一个类别class_to_idx字典将每个类别名称映射为一个数字索引。 具体来说如果数据集文件夹包含两个子文件夹比如Monkeypox和Othersclass_to_idx字典将返回类似以下的映射关系{Monkeypox: 0, Others: 1}
3. 划分数据集
train_size int(0.8 * len(total_data))
test_size len(total_data) - train_size
train_dataset, test_dataset torch.utils.data.random_split(total_data, [train_size, test_size])
train_dataset, test_dataset
(torch.utils.data.dataset.Subset at 0x7823152d5b10,torch.utils.data.dataset.Subset at 0x78231534b970)
train_size,test_size
(1713, 429)
batch_size 32train_dl torch.utils.data.DataLoader(train_dataset,batch_sizebatch_size,shuffleTrue,num_workers1)
test_dl torch.utils.data.DataLoader(test_dataset,batch_sizebatch_size,shuffleTrue,num_workers1)
for X, y in test_dl:print(Shape of X [N, C, H, W]: , X.shape)print(Shape of y: , y.shape, y.dtype)break
Shape of X [N, C, H, W]: torch.Size([32, 3, 224, 224])
Shape of y: torch.Size([32]) torch.int64
torch.utils.data.DataLoader()参数详解 torch.utils.data.DataLoader 是 PyTorch 中用于加载和管理数据的一个实用工具类。它允许你以小批次的方式迭代你的数据集这对于训练神经网络和其他机器学习任务非常有用。DataLoader 构造函数接受多个参数下面是一些常用的参数及其解释 dataset必需参数这是你的数据集对象通常是 torch.utils.data.Dataset 的子类它包含了你的数据样本。batch_size可选参数指定每个小批次中包含的样本数。默认值为 1。shuffle可选参数如果设置为 True则在每个 epoch 开始时对数据进行洗牌以随机打乱样本的顺序。这对于训练数据的随机性很重要以避免模型学习到数据的顺序性。默认值为 False。num_workers可选参数用于数据加载的子进程数量。通常将其设置为大于 0 的值可以加快数据加载速度特别是当数据集很大时。默认值为 0表示在主进程中加载数据。pin_memory可选参数如果设置为 True则数据加载到 GPU 时会将数据存储在 CUDA 的锁页内存中这可以加速数据传输到 GPU。默认值为 False。drop_last可选参数如果设置为 True则在最后一个小批次可能包含样本数小于 batch_size 时丢弃该小批次。这在某些情况下很有用以确保所有小批次具有相同的大小。默认值为 False。timeout可选参数如果设置为正整数它定义了每个子进程在等待数据加载器传递数据时的超时时间以秒为单位。这可以用于避免子进程卡住的情况。默认值为 0表示没有超时限制。worker_init_fn可选参数一个可选的函数用于初始化每个子进程的状态。这对于设置每个子进程的随机种子或其他初始化操作很有用。
二、构建简单的CNN网络 网络结构图可单击放大查看、 import torch.nn.functional as Fclass Network_bn(nn.Module):def __init__(self):super(Network_bn, self).__init__()nn.Conv2d()函数第一个参数in_channels是输入的channel数量第二个参数out_channels是输出的channel数量第三个参数kernel_size是卷积核大小第四个参数stride是步长默认为1第五个参数padding是填充大小默认为0self.conv1 nn.Conv2d(in_channels3, out_channels12, kernel_size5, stride1, padding0)self.bn1 nn.BatchNorm2d(12)self.conv2 nn.Conv2d(in_channels12, out_channels12, kernel_size5, stride1, padding0)self.bn2 nn.BatchNorm2d(12)self.pool nn.MaxPool2d(2,2)self.conv4 nn.Conv2d(in_channels12, out_channels24, kernel_size5, stride1, padding0)self.bn4 nn.BatchNorm2d(24)self.conv5 nn.Conv2d(in_channels24, out_channels24, kernel_size5, stride1, padding0)self.bn5 nn.BatchNorm2d(24)self.fc1 nn.Linear(24*50*50, len(classeNames))def forward(self, x):x F.relu(self.bn1(self.conv1(x))) x F.relu(self.bn2(self.conv2(x))) x self.pool(x) x F.relu(self.bn4(self.conv4(x))) x F.relu(self.bn5(self.conv5(x))) x self.pool(x) x x.view(-1, 24*50*50)x self.fc1(x)return xdevice cuda if torch.cuda.is_available() else cpu
print(Using {} device.format(device))model Network_bn().to(device)
model Using cuda deviceNetwork_bn((conv1): Conv2d(3, 12, kernel_size(5, 5), stride(1, 1))(bn1): BatchNorm2d(12, eps1e-05, momentum0.1, affineTrue, track_running_statsTrue)(conv2): Conv2d(12, 12, kernel_size(5, 5), stride(1, 1))(bn2): BatchNorm2d(12, eps1e-05, momentum0.1, affineTrue, track_running_statsTrue)(pool): MaxPool2d(kernel_size2, stride2, padding0, dilation1, ceil_modeFalse)(conv4): Conv2d(12, 24, kernel_size(5, 5), stride(1, 1))(bn4): BatchNorm2d(24, eps1e-05, momentum0.1, affineTrue, track_running_statsTrue)(conv5): Conv2d(24, 24, kernel_size(5, 5), stride(1, 1))(bn5): BatchNorm2d(24, eps1e-05, momentum0.1, affineTrue, track_running_statsTrue)(fc1): Linear(in_features60000, out_features2, biasTrue)
)三、 训练模型
1. 设置超参数
loss_fn nn.CrossEntropyLoss() # 创建损失函数
learn_rate 1e-4 # 学习率
opt torch.optim.SGD(model.parameters(),lrlearn_rate)
2. 编写训练函数
# 训练循环
def train(dataloader, model, loss_fn, optimizer):size len(dataloader.dataset) # 训练集的大小一共60000张图片num_batches len(dataloader) # 批次数目187560000/32train_loss, train_acc 0, 0 # 初始化训练损失和正确率for X, y in dataloader: # 获取图片及其标签X, y X.to(device), y.to(device)# 计算预测误差pred model(X) # 网络输出loss loss_fn(pred, y) # 计算网络输出和真实值之间的差距targets为真实值计算二者差值即为损失# 反向传播optimizer.zero_grad() # grad属性归零loss.backward() # 反向传播optimizer.step() # 每一步自动更新# 记录acc与losstrain_acc (pred.argmax(1) y).type(torch.float).sum().item()train_loss loss.item()train_acc / sizetrain_loss / num_batchesreturn train_acc, train_loss
3. 编写测试函数 测试函数和训练函数大致相同但是由于不进行梯度下降对网络权重进行更新所以不需要传入优化器。
def test (dataloader, model, loss_fn):size len(dataloader.dataset) # 测试集的大小一共10000张图片num_batches len(dataloader) # 批次数目31310000/32312.5向上取整test_loss, test_acc 0, 0# 当不进行训练时停止梯度更新节省计算内存消耗with torch.no_grad():for imgs, target in dataloader:imgs, target imgs.to(device), target.to(device)# 计算losstarget_pred model(imgs)loss loss_fn(target_pred, target)test_loss loss.item()test_acc (target_pred.argmax(1) target).type(torch.float).sum().item()test_acc / sizetest_loss / num_batchesreturn test_acc, test_loss
4. 正式训练
epochs 20
train_loss []
train_acc []
test_loss []
test_acc []for epoch in range(epochs):model.train()epoch_train_acc, epoch_train_loss train(train_dl, model, loss_fn, opt)model.eval()epoch_test_acc, epoch_test_loss test(test_dl, model, loss_fn)train_acc.append(epoch_train_acc)train_loss.append(epoch_train_loss)test_acc.append(epoch_test_acc)test_loss.append(epoch_test_loss)template (Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%Test_loss:{:.3f})print(template.format(epoch1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss))
print(Done)
Epoch: 1, Train_acc:57.5%, Train_loss:0.744, Test_acc:62.9%Test_loss:0.714
Epoch: 2, Train_acc:65.9%, Train_loss:0.640, Test_acc:70.9%Test_loss:0.591
Epoch: 3, Train_acc:72.3%, Train_loss:0.562, Test_acc:72.5%Test_loss:0.566
Epoch: 4, Train_acc:75.4%, Train_loss:0.525, Test_acc:73.4%Test_loss:0.540
Epoch: 5, Train_acc:77.3%, Train_loss:0.492, Test_acc:75.1%Test_loss:0.526
Epoch: 6, Train_acc:78.7%, Train_loss:0.469, Test_acc:73.0%Test_loss:0.547
Epoch: 7, Train_acc:80.7%, Train_loss:0.443, Test_acc:74.6%Test_loss:0.515
Epoch: 8, Train_acc:82.4%, Train_loss:0.421, Test_acc:74.1%Test_loss:0.508
Epoch: 9, Train_acc:83.2%, Train_loss:0.406, Test_acc:76.7%Test_loss:0.473
Epoch:10, Train_acc:83.7%, Train_loss:0.398, Test_acc:78.3%Test_loss:0.465
Epoch:11, Train_acc:84.8%, Train_loss:0.383, Test_acc:77.4%Test_loss:0.472
Epoch:12, Train_acc:86.1%, Train_loss:0.364, Test_acc:79.3%Test_loss:0.456
Epoch:13, Train_acc:87.0%, Train_loss:0.356, Test_acc:78.3%Test_loss:0.449
Epoch:14, Train_acc:87.6%, Train_loss:0.343, Test_acc:80.9%Test_loss:0.438
Epoch:15, Train_acc:88.7%, Train_loss:0.331, Test_acc:80.7%Test_loss:0.461
Epoch:16, Train_acc:88.3%, Train_loss:0.319, Test_acc:79.7%Test_loss:0.448
Epoch:17, Train_acc:89.0%, Train_loss:0.312, Test_acc:81.6%Test_loss:0.425
Epoch:18, Train_acc:89.5%, Train_loss:0.301, Test_acc:80.9%Test_loss:0.415
Epoch:19, Train_acc:90.0%, Train_loss:0.297, Test_acc:81.6%Test_loss:0.430
Epoch:20, Train_acc:90.9%, Train_loss:0.286, Test_acc:80.9%Test_loss:0.406
Done
四、 结果可视化
1. Loss与Accuracy图
import matplotlib.pyplot as plt
#隐藏警告
import warnings
warnings.filterwarnings(ignore) #忽略警告信息
plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签
plt.rcParams[axes.unicode_minus] False # 用来正常显示负号
plt.rcParams[figure.dpi] 100 #分辨率epochs_range range(epochs)plt.figure(figsize(12, 3))
plt.subplot(1, 2, 1)plt.plot(epochs_range, train_acc, labelTraining Accuracy)
plt.plot(epochs_range, test_acc, labelTest Accuracy)
plt.legend(loclower right)
plt.title(Training and Validation Accuracy)plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, labelTraining Loss)
plt.plot(epochs_range, test_loss, labelTest Loss)
plt.legend(locupper right)
plt.title(Training and Validation Loss)
plt.show() 2. 指定图片进行预测
⭐torch.squeeze()详解 对数据的维度进行压缩去掉维数为1的的维度。
函数原型
t orch.squeeze(input, dimNone, *, outNone)
关键参数说明
input (Tensor)输入Tensor。
dim (int, optional)如果给定输入将只在这个维度上被压缩。
from PIL import Image classes list(total_data.class_to_idx)def predict_one_image(image_path, model, transform, classes):test_img Image.open(image_path).convert(RGB)# plt.imshow(test_img) # 展示预测的图片test_img transform(test_img)img test_img.to(device).unsqueeze(0)model.eval()output model(img)_,pred torch.max(output,1)pred_class classes[pred]print(f预测结果是{pred_class}) # 预测训练集中的某张照片
predict_one_image(image_path/kaggle/input/monkey-images/monkey/Monkeypox/M01_02_04.jpg, modelmodel, transformtrain_transforms, classesclasses)
预测结果是Monkeypox 五、保存并加载模型
# 模型保存
PATH ./model.pth # 保存的参数文件名
torch.save(model.state_dict(), PATH)# 将参数加载到model当中
model.load_state_dict(torch.load(PATH, map_locationdevice)) All keys matched successfully
六、个人总结 学会了用模型预测图片在准确率上还未到要求换个GPU再跑一次。