当前位置: 首页 > news >正文

wordpress建站位置深圳坪山比亚迪

wordpress建站位置,深圳坪山比亚迪,wordpress 404 nginx,广告制作简介可以从本人以前的文章中可以看出作者以前从事的是嵌入式控制方面相关的工作#xff0c;是一个机器视觉小白#xff0c;之所以开始入门机器视觉的学习只要是一个idea#xff0c;想把机器视觉与控制相融合未来做一点小东西。废话不多说开始正题。 摘要#xff1a;本文是介绍V…  可以从本人以前的文章中可以看出作者以前从事的是嵌入式控制方面相关的工作是一个机器视觉小白之所以开始入门机器视觉的学习只要是一个idea想把机器视觉与控制相融合未来做一点小东西。废话不多说开始正题。 摘要本文是介绍VGG16网络,个人对其的知识总结网络设计的知识点以及代码如何撰写基于pytorch编写代码。作为一个刚入门的小白怎么去学习别人的代码一步一步的去理解每一行代码怎么将网络设计变成代码模仿大佬的代码去撰写。作为小白如有不足之处请批评指正哈。 机器视觉基础知识 在此之前本人学习了机器视觉的基础知识以下是本人学习时的链接希望对你有所帮助。 https://fuhanghang.blog.csdn.net/article/details/135544761?fromshareblogdetailsharetypeblogdetailsharerId135544761sharereferPCsharesourceweixin_52531699sharefromfrom_link 【计算机视觉与深度学习 北京邮电大学 鲁鹏 清晰版合集完整版】 https://www.bilibili.com/video/BV1V54y1B7K3/?share_sourcecopy_webvd_sourceb25ae79b699fbc0a2f70ccb983f6b74a VGG16 在网络设计之前需要明白什么是VGG16。 以下是我借鉴的文章的参考链接 https://blog.csdn.net/weixin_46676835/article/details/129582927?fromshareblogdetailsharetypeblogdetailsharerId129582927sharereferPCsharesourceweixin_52531699sharefromfrom_link https://blog.csdn.net/weixin_46676835/article/details/128730174?fromshareblogdetailsharetypeblogdetailsharerId128730174sharereferPCsharesourceweixin_52531699sharefromfrom_link VGG16是一个深度卷积神经网络它在2014年由牛津大学视觉几何组Visual Geometry Group提出并在ImageNet图像分类任务中取得了显著的成绩。以下是VGG16的一些关键特点 1. 网络结构 层数: VGG16包含16个主要的权重层包括13个卷积层和3个全连接层。 卷积层: VGG16使用小的3x3卷积核进行卷积操作增加了网络的深度同时保持了较少的参数数量。 池化层: 每隔几个卷积层后会使用2x2的最大池化层Max Pooling来降低特征图的尺寸并减少计算量。 2. 激活函数 VGG网络普遍使用ReLURectified Linear Unit作为激活函数增加了网络的非线性表达能力。 3. 输入和输出 输入: VGG16接受224x224像素的RGB图像作为输入。 输出: 最终的输出是一个1000维的向量表示属于1000个类别的概率分布针对ImageNet数据集。 4. 特点与优点 深度: VGG16相对较深16层使其能够学习更复杂的特征。 简单性: 使用统一的小卷积核和堆叠结构使得网络设计相对简单且易于理解。 预训练模型: VGG16在多种任务中被广泛应用并且可以使用预训练权重进行迁移学习以提高其他任务的性能。 5. 应用方面 VGG16被广泛应用于图像分类、物体检测、图像分割等计算机视觉任务。由于其良好的表现许多后续的研究和模型例如VGG19等都是在此基础上进行改进的。 从图中可以看出VGG16包含16个主要的权重层包括13个卷积层和3个全连接层。 计算过程 1输入图像尺寸为224x224x3经64个通道为3的3x3的卷积核步长为1paddingsame填充卷积两次再经ReLU激活输出的尺寸大小为224x224x64 2经max pooling最大化池化滤波器为2x2步长为2图像尺寸减半池化后的尺寸变为112x112x64 3经128个3x3的卷积核两次卷积ReLU激活尺寸变为112x112x128 4max pooling池化尺寸变为56x56x128 5经256个3x3的卷积核三次卷积ReLU激活尺寸变为56x56x256 6max pooling池化尺寸变为28x28x256 7经512个3x3的卷积核三次卷积ReLU激活尺寸变为28x28x512 8max pooling池化尺寸变为14x14x512 9经512个3x3的卷积核三次卷积ReLU尺寸变为14x14x512 10max pooling池化尺寸变为7x7x512 11然后Flatten()将数据拉平成向量变成一维512 ×7 ×725088。 11再经过两层1x1x4096一层1x1x1000的全连接层共三层经ReLU激活 12最后通过softmax输出1000个预测结果这是官方的最终本人输出3种 软件代码构思 有了以上理论基础后开始构建代码思路整体构建思路如下图所示写代码之前一定要构思好大致思路代码永远是为你思路框架服务的。 训练部分代码撰写 1.参数初始化 这一部分的代码的作用是首先是关键参数以及头文件的初始化再然后就是读取jpg文件以及txt文件的内容将其分为3类蚂蚁蜜蜂狗后续品种可以自己添加jpgtxt训练数据多少都可以由自己添加但是文件的命名格式必须为1.jpg1.txt2.jpg2.txt才能读取文件。 1头文件初始化 import os import parser import time import numpy as np import torch import torchvision.transforms as transforms import PIL from PIL import Image from scipy.stats import norm from torch import nn from torch.utils.data import Dataset, random_split, DataLoader, ConcatDataset import torchvision.datasets from torch import nn from torch.nn import MaxPool2d, Flattenimport argparse from pathlib import Pathimport os用于读取文件路径。 import time用于时间相关的功能本文用其计算训练时间。 import torchvision.transforms as transforms用于图像处理和转换的模块常用于数据预处理。 import torchvision.datasets提供了常用数据集的接口例如MNIST、CIFAR等。 from PIL import ImagePillow库用于图像的打开、处理和保存。 from torch.nn import MaxPool2d, Flatten导入特定的层MaxPool2d用于进行二维最大池化Flatten将多维输入展平为一维。 from torch.utils.data import Dataset, random_split, DataLoader, ConcatDataset用于自定义数据集和数据加载器方便批量处理数据。 import argparse用于处理命令行参数使得脚本可以接受用户输入的参数。 from pathlib import Path提供高级路径操作功能方便文件系统的操作。 2参数定义函数 用parse_opt()这个函数主要是见过许多大佬的文章都是用这个函数转义。作为小白像较为官方的标准化参数结构学习。 def parse_opt():parser argparse.ArgumentParser() # 创建 ArgumentParser 对象parser.add_argument(--epochs, typeint, default5, helptotal training epochs) # 添加参数parser.add_argument(--batch_size, typeint, default16, helpsize of each batch) # 添加批次大小参数parser.add_argument(--learning_rate, typeint, default0.03, helpsize of learning_rate) # 添加批次大小参数#--device cuda:0,cuda:1 启用多个设备parser.add_argument(--device, defaultcuda:0, helpcuda device, i.e. 0 or 0,1,2,3 or cpu) #--device cuda:1# 解析参数opt parser.parse_args()return optopt parse_opt() # 调用解析函数 epochs opt.epochs # 训练的轮数 batch_size opt.batch_size # 每个批次的样本数量 learning_rate opt.learning_rate device torch.device(opt.device)3定义文件处理类 这部分代码的编写主要是要实现一个功能如何把1.jpg1.txt2.jpg2.txt…文件读取处理并将txt文件的内容进行处理实现分类。 class CustomDataset(Dataset):def __init__(self, img_dir, label_dir, transformNone):self.img_dir img_dirself.label_dir label_dirself.transform transformself.img_labels self.load_labels()def load_labels(self):label_map {ants: 0, bees: 1,dogs: 2} #字典label_map 来定义标签与数字之间的映射关系labels [] #创建一个空列表 labels用来存储从文件中读取到的标签的数字编码for label_file in os.listdir(self.label_dir):with open(os.path.join(self.label_dir, label_file), r) as f: #对于每个标签文件使用 open() 打开文件并读取第一行内容readline()line f.readline().strip() #strip() 方法用于去掉行首和行尾的空白字符包括换行符#从label_map 中获取当前行的标签对应的数字编码。如果当前行的内容不在 label_map 中则返回-1labels.append(label_map.get(line, -1))return labelsdef __len__(self):return len(self.img_labels)def __getitem__(self, idx):#使用 os.path.join 将图像目录路径 (self.img_dir) 和图像文件名拼接起来。文件名格式为 idx 1即从1开始计数加上 .jpg 后缀。#例如如果idx为0则img_path会是 D:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\ants_image\\1.jpgimg_path os.path.join(self.img_dir, str(idx1) .jpg)image Image.open(img_path).convert(RGB) #打开指定路径的图像文件并将其转换为 RGB 模式。label self.img_labels[idx] #列表中获取当前图像的标签idx 是当前图像的索引if self.transform: #transform变量是在CustomDataset中最终调用的transforms.Compose实现image self.transform(image)return image, label使用字典 label_map 来定义标签与数字之间的映射关系‘ants’ 对应 0‘bees’ 对应 1‘dogs’ 对应 2。对于每个标签文件使用 open() 打开文件并读取第一行内容readline()。strip() 方法用于去掉行首和行尾的空白字符包括换行符。使用 label_map.get(line, -1) 从 label_map 中获取当前行的标签对应的数字编码。如果当前行的内容不在 label_map 中则返回 -1。本人当时在这就犯了一个错误。可以从调试的框中看出我有一个txt文件的内容并不是dogs致使其返回的值为-1出现这个问题的原因是本人txt文件中dogs没有保存所以切记一定要保存文件如果自己训练模型自建数据集的话。很多内容方面注释写的很清楚作者就不细讲了。 订正错误后的结果 4数据集图片输入 代码需要实现一个图像大小设置功能由于输入图像大小不确定需要将其设置成224×224大小图片满足输入网络图像大小的设定。 # 定义转换包括调整大小 transform transforms.Compose([transforms.Resize((224, 224)), # 调整为 224x224 大小transforms.ToTensor(), # 转换为 Tensortorchvision.transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225])# 可以添加其他转换例如归一化等 ])# 初始化数据集 ants_data CustomDataset(img_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\ants_image,label_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\ants_label,transformtransform )bees_data CustomDataset(img_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\bees_image,label_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\bees_label,transformtransform )dogs_data CustomDataset(img_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\dogs_image,label_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\dogs_label,transformtransform )transform 是通过 transforms.Compose 创建的一个组合转换对象。这个对象整合了多个图像预处理步骤包括调整大小、转换为张量以及归一化。调整大小: 将图像调整为 224x224 像素。转换为 Tensor: 将 PIL 图像或 NumPy 数组转换为 PyTorch 张量。归一化: 根据给定的均值和标准差对张量进行归一化处理使得数据分布更适合神经网络训练。归一化是VGG16网络的要求但是本人发现没有也行但所提供的代码为按照官方要求编写的。 ants_data 是 CustomDataset 类的一个实例用于加载蚂蚁图像数据集。 img_dir 指定了存放图像文件的目录。 label_dir 指定了存放标签文件的目录。 transform 是应用于图像的转换操作如缩放、裁剪、归一化等即在加载图像时对其进行预处理。也就是调用transforms.Compose 。 从代码中也可以看出实现的效果是读取图像读取标签然后通过transform将其变成224x224。 训练图片标签地址如图所示。 2.将数据集总和并随机打乱并分成训练集测试集 这段代码的作用是将我所读取的数据ants_databees_datadogs_data总和起来然后随机打乱分割出训练集测试集分别是73。 # 合并数据集 total_data ants_databees_data total_data total_datadogs_data # 计算训练集和验证集的大小 total_size len(total_data) train_size int(0.7 * total_size) # 70% val_size total_size - train_size # 30%train_data_size train_size val_data_size val_sizeprint(训练集长度{}.format(train_data_size)) print(测试集长度{}.format(val_data_size)) # 随机分割数据集 train_data, val_data random_split(total_data, [train_size, val_size])# 创建 DataLoader分成小批量batches以便于进行训练和验证 train_dataloader DataLoader(train_data, batch_size, shuffleTrue) #shuffleTrue可以随机打乱数据 val_dataloader DataLoader(val_data, batch_size, shuffleFalse) # 打印数据集大小在这里插入图片描述print(训练集大小{}.format(len(train_data))) print(验证集大小{}.format(len(val_data)))从调试图中可知ants_data 110,bees_data 70,dogs_data 120,total_data 300这也是我训练时提供的图片数目标太多太累了。 3.创建网络模型 这部分是根据上图的vgg16网络结构搭建的。具体代码如下本人写法为小白写法应该通俗易懂。 class VGG16(nn.Module):def __init__(self):super(VGG16, self).__init__()self.model nn.Sequential( # 构建子类可以减少foward代码撰写nn.Conv2d(in_channels3, out_channels64, kernel_size3, stride1, padding1),nn.Conv2d(in_channels64, out_channels64, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), #最大池化将224变成112nn.Conv2d(in_channels64, out_channels128, kernel_size3, stride1, padding1),nn.Conv2d(in_channels128, out_channels128, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 56x56nn.Conv2d(in_channels128, out_channels256, kernel_size3, stride1, padding1),nn.Conv2d(in_channels256, out_channels256, kernel_size3, stride1, padding1),nn.Conv2d(in_channels256, out_channels256, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 28x28nn.Conv2d(in_channels256, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 14x14nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 7x7)# 使用AdaptiveAvgPool2d来确保输出为固定大小self.avgpool nn.AdaptiveAvgPool2d((7, 7))# 全连接层self.fc1 nn.Linear(in_features512 * 7 * 7, out_features4096)self.fc2 nn.Linear(in_features4096, out_features4096)self.fc3 nn.Linear(in_features4096, out_features3)self.relu nn.ReLU()self.dropout nn.Dropout(0.3)def forward(self, x):x self.model(x)x self.avgpool(x) # 使用自适应平均池化x x.view(x.size(0), -1) # 拉平操作,(batch_size, num_features) 也就是825088 512*7*7 25088x self.relu(self.fc1(x))x self.dropout(x)x self.relu(self.fc2(x))x self.dropout(x)x self.fc3(x)return xx self.avgpool(x) 自适应平均池化将输入特征图x的空间维度降低到固定大小。x x.view(x.size(0), -1) 这行代码将输出张量 x 的形状变为 (batch_size, num_features) 其中 batch_size 是当前批次的样本数量num_features 是特征的总数。这一步是为了将多维张量转换为二维张量 以便进入全连接层进行分类。4.训练加测试 这部分得先明白工作步骤再写代码。1.训练集训练调用VGG16网络结构损失函数构建随机梯度下降优化训练 2.测试集测试设置为评估模式调用VGG16网络结构损失函数构建损失计算。3.输出训练损失测试损失准确率。这部分是机器视觉基础概念知识。 def train():My_VGG16 VGG16() #调用类My_VGG16 My_VGG16.to(device)# (1).损失函数构建loss_fn nn.CrossEntropyLoss() #计算预测值与真实标签之间的差异loss_fn loss_fn.to(device) #将模型和数据都放在同一个设备上GPU# (2).优化器# #随机梯度下降Stochastic Gradient Descent优化器的一种实现。SGD 是一种常见的优化算法optimizer torch.optim.SGD(My_VGG16.parameters(), lrlearning_rate)# 用于存储损失和准确率train_losses []val_losses []accuracies []for i in range(epochs):loss_temp 0 # 临时变量print(--------第{}轮训练开始--------.format(i 1))# 训练阶段My_VGG16.train() # 设置为训练模式#data有两个部分分别是(8,3,224,224),(8,) 一定要注意顺序for data in train_dataloader:imgs, targets dataimgs imgs.to(device)targets targets.to(device)#outputs tensor83outputs My_VGG16(imgs)loss loss_fn(outputs, targets)# 优化器优化模型optimizer.zero_grad() # 梯度清零loss.backward() # 反向传播optimizer.step() # 梯度更新loss_temp loss.item()# 记录训练损失train_losses.append(loss_temp / len(train_dataloader))# 测试阶段My_VGG16.eval() # 设置为评估模式total_test_loss 0total_accuracy 0with torch.no_grad():for data in val_dataloader:imgs, targets dataimgs imgs.to(device)targets targets.to(device)outputs My_VGG16(imgs)loss loss_fn(outputs, targets)total_test_loss loss.item()#找到每个样本的预测类别然后与真实标签进行比较accuracy (outputs.argmax(1) targets).sum().item() # 使用.item()将Tensor转换为Python数值total_accuracy accuracy #计算正确预测的数量并累加到 total_accuracyimgs, targets data这段代码可以从图中看出data有两个部分分别是(8,3,224,224),(8,) 一定要注意顺序分别对应的就是imgstargets outputs My_VGG16(imgs) outputs tensor83outputs单纯的就是输出品种结果8是因为我的batch_size 8输入的是8张图片。 5.保存数据至.pth文件并绘图 这部分代码的编写需要实现的是将训练的权值保存至.pth文件中并在窗口中显示训练时的时间loss准确率输出考虑到train_loss为list5所以直接使用循环的打印输出效果。 # 记录验证损失和准确率val_losses.append(total_test_loss / len(val_dataloader))accuracies.append(total_accuracy / val_data_size)print(整体测试集上的正确率:{}.format(total_accuracy / val_data_size))print(整体测试集上的Loss{}.format(total_test_loss))# 保存模型torch.save(My_VGG16, vgg16_{}.pth.format(2))torch.save(My_VGG16.state_dict(), vgg16_dict_{}.txt.format(2))print(模型已保存)# 绘制损失和准确率曲线epochs_range range(1, epochs 1)plt.figure(figsize(12, 5)) #创建一个新的图形窗口设置图形的大小# 训练和验证损失plt.subplot(1, 2, 1) #第一个图像框plt.plot(epochs_range, train_losses, labelTraining Loss)#train_losses[1.0952595781396937, 1.085733965591148, 1.07982603708903, 1.0776626953372248, 1.0816458507820412]plt.plot(epochs_range, val_losses, labelValidation Loss)plt.title(Loss vs Epochs)plt.xlabel(Epochs)plt.ylabel(Loss)plt.legend()# 准确率plt.subplot(1, 2, 2)plt.plot(epochs_range, accuracies, labelValidation Accuracy)plt.title(Accuracy vs Epochs)plt.xlabel(Epochs)plt.ylabel(Accuracy)plt.legend()plt.tight_layout()plt.show()if __name__ __main__:parse_opt()train()# 测试模型# model VGG16()# sample_input torch.randn(1, 3, 224, 224) # Batch size 为 1# output model(sample_input)# print(Final output shape:, output.shape) # 应输出 [1, 3]代码讲解注释很详细不做细数。 输出图片效果这是只训练了5次的网络可以看到训练效果是不理想的。 以上就是训练集代码及讲解。 训练整体代码 #VGG_16训练网络模型第一代测试代码主要功能如下 #识别3类蚂蚁蜜蜂狗可任意添加文件名为1.jpg,1.txt,内容ants #2代是在一代的基础上添加了图像显示标准化参数设计方面 import os import parser import time import numpy as np import torch import torchvision.transforms as transforms import PIL from PIL import Image from scipy.stats import norm from torch import nn from torch.utils.data import Dataset, random_split, DataLoader, ConcatDataset import torchvision.datasets from torch import nn from torch.nn import MaxPool2d, Flattenimport argparse from pathlib import Path# ------------------------------1.初始化标准参数初始化------------------------------- def parse_opt():parser argparse.ArgumentParser() # 创建 ArgumentParser 对象parser.add_argument(--epochs, typeint, default5, helptotal training epochs) # 添加参数parser.add_argument(--batch_size, typeint, default8, helpsize of each batch) # 添加批次大小参数parser.add_argument(--learning_rate, typeint, default0.03, helpsize of learning_rate) # 添加批次大小参数#--device cuda:0,cuda:1 启用多个设备parser.add_argument(--device, defaultcuda:0, helpcuda device, i.e. 0 or 0,1,2,3 or cpu) #--device cuda:1# 解析参数opt parser.parse_args()return optopt parse_opt() # 调用解析函数 epochs opt.epochs # 训练的轮数 batch_size opt.batch_size # 每个批次的样本数量 learning_rate opt.learning_rate device torch.device(opt.device)class CustomDataset(Dataset):def __init__(self, img_dir, label_dir, transformNone):self.img_dir img_dirself.label_dir label_dirself.transform transformself.img_labels self.load_labels()def load_labels(self):label_map {ants: 0, bees: 1,dogs: 2} #字典label_map 来定义标签与数字之间的映射关系labels [] #创建一个空列表 labels用来存储从文件中读取到的标签的数字编码for label_file in os.listdir(self.label_dir):with open(os.path.join(self.label_dir, label_file), r) as f: #对于每个标签文件使用 open() 打开文件并读取第一行内容readline()line f.readline().strip() #strip() 方法用于去掉行首和行尾的空白字符包括换行符#从label_map 中获取当前行的标签对应的数字编码。如果当前行的内容不在 label_map 中则返回-1labels.append(label_map.get(line, -1))return labelsdef __len__(self):return len(self.img_labels)def __getitem__(self, idx):#使用 os.path.join 将图像目录路径 (self.img_dir) 和图像文件名拼接起来。文件名格式为 idx 1即从1开始计数加上 .jpg 后缀。#例如如果idx为0则img_path会是 D:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\ants_image\\1.jpgimg_path os.path.join(self.img_dir, str(idx1) .jpg)image Image.open(img_path).convert(RGB) #打开指定路径的图像文件并将其转换为 RGB 模式。label self.img_labels[idx] #列表中获取当前图像的标签idx 是当前图像的索引if self.transform: #transform变量是在CustomDataset中最终调用的transforms.Compose实现image self.transform(image)return image, label# 定义转换包括调整大小 transform transforms.Compose([transforms.Resize((224, 224)), # 调整为 224x224 大小transforms.ToTensor(), # 转换为 Tensortorchvision.transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225])# 可以添加其他转换例如归一化等 ])# 初始化数据集 ants_data CustomDataset(img_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\ants_image,label_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\ants_label,transformtransform )bees_data CustomDataset(img_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\bees_image,label_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\bees_label,transformtransform )dogs_data CustomDataset(img_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\dogs_image,label_dirD:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\train\\dogs_label,transformtransform ) #-----------------------2.将数据集总和并随机打乱并分成训练集测试集------------------- # 合并数据集 total_data ants_databees_data total_data total_datadogs_data # 计算训练集和验证集的大小 total_size len(total_data) train_size int(0.7 * total_size) # 70% val_size total_size - train_size # 30%train_data_size train_size val_data_size val_sizeprint(训练集长度{}.format(train_data_size)) print(测试集长度{}.format(val_data_size)) # 随机分割数据集 train_data, val_data random_split(total_data, [train_size, val_size])# 创建 DataLoader分成小批量batches以便于进行训练和验证 train_dataloader DataLoader(train_data, batch_size, shuffleTrue) #shuffleTrue可以随机打乱数据 val_dataloader DataLoader(val_data, batch_size, shuffleFalse) # 打印数据集大小 print(训练集大小{}.format(len(train_data))) print(验证集大小{}.format(len(val_data)))#----------------------------3.创建网络模型-------------------------------- class VGG16(nn.Module):def __init__(self):super(VGG16, self).__init__()self.model nn.Sequential( # 构建子类可以减少foward代码撰写nn.Conv2d(in_channels3, out_channels64, kernel_size3, stride1, padding1),nn.Conv2d(in_channels64, out_channels64, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), #最大池化将224变成112nn.Conv2d(in_channels64, out_channels128, kernel_size3, stride1, padding1),nn.Conv2d(in_channels128, out_channels128, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 56x56nn.Conv2d(in_channels128, out_channels256, kernel_size3, stride1, padding1),nn.Conv2d(in_channels256, out_channels256, kernel_size3, stride1, padding1),nn.Conv2d(in_channels256, out_channels256, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 28x28nn.Conv2d(in_channels256, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 14x14nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 7x7)# 使用AdaptiveAvgPool2d来确保输出为固定大小self.avgpool nn.AdaptiveAvgPool2d((7, 7))# 全连接层self.fc1 nn.Linear(in_features512 * 7 * 7, out_features4096)self.fc2 nn.Linear(in_features4096, out_features4096)self.fc3 nn.Linear(in_features4096, out_features3)self.relu nn.ReLU()self.dropout nn.Dropout(0.3)def forward(self, x):x self.model(x)x self.avgpool(x) # 使用自适应平均池化x x.view(x.size(0), -1) # 拉平操作,(batch_size, num_features) 也就是825088 512*7*7 25088x self.relu(self.fc1(x))x self.dropout(x)x self.relu(self.fc2(x))x self.dropout(x)x self.fc3(x)return x#------------------------------------4.训练加测试-----------------------import numpy as np import matplotlib matplotlib.use(TkAgg) # 或者尝试 Qt5Agg有这行代码会多一个弹窗显示 import matplotlib.pyplot as plt import torch.nn as nndef train():My_VGG16 VGG16() #调用类My_VGG16 My_VGG16.to(device)# (1).损失函数构建loss_fn nn.CrossEntropyLoss() #计算预测值与真实标签之间的差异loss_fn loss_fn.to(device) #将模型和数据都放在同一个设备上GPU# (2).优化器# #随机梯度下降Stochastic Gradient Descent优化器的一种实现。SGD 是一种常见的优化算法optimizer torch.optim.SGD(My_VGG16.parameters(), lrlearning_rate)# 用于存储损失和准确率train_losses []val_losses []accuracies []for i in range(epochs):loss_temp 0 # 临时变量print(--------第{}轮训练开始--------.format(i 1))# 训练阶段My_VGG16.train() # 设置为训练模式#data有两个部分分别是(8,3,224,224),(8,) 一定要注意顺序for data in train_dataloader:imgs, targets dataimgs imgs.to(device)targets targets.to(device)#outputs tensor83outputs My_VGG16(imgs)loss loss_fn(outputs, targets)# 优化器优化模型optimizer.zero_grad() # 梯度清零loss.backward() # 反向传播optimizer.step() # 梯度更新loss_temp loss.item()# 记录训练损失train_losses.append(loss_temp / len(train_dataloader))# 测试阶段My_VGG16.eval() # 设置为评估模式total_test_loss 0total_accuracy 0with torch.no_grad():for data in val_dataloader:imgs, targets dataimgs imgs.to(device)targets targets.to(device)outputs My_VGG16(imgs)loss loss_fn(outputs, targets)total_test_loss loss.item()#找到每个样本的预测类别然后与真实标签进行比较accuracy (outputs.argmax(1) targets).sum().item() # 使用.item()将Tensor转换为Python数值total_accuracy accuracy #计算正确预测的数量并累加到 total_accuracy #-----------------------5.保存数据至.pth文件并绘图---------------------------------------------------# 记录验证损失和准确率val_losses.append(total_test_loss / len(val_dataloader))accuracies.append(total_accuracy / val_data_size)print(整体测试集上的正确率:{}.format(total_accuracy / val_data_size))print(整体测试集上的Loss{}.format(total_test_loss))# 保存模型torch.save(My_VGG16, vgg16_{}.pth.format(2))torch.save(My_VGG16.state_dict(), vgg16_dict_{}.txt.format(2))print(模型已保存)# 绘制损失和准确率曲线epochs_range range(1, epochs 1)plt.figure(figsize(12, 5)) #创建一个新的图形窗口设置图形的大小# 训练和验证损失plt.subplot(1, 2, 1) #第一个图像框plt.plot(epochs_range, train_losses, labelTraining Loss)#train_losses[1.0952595781396937, 1.085733965591148, 1.07982603708903, 1.0776626953372248, 1.0816458507820412]plt.plot(epochs_range, val_losses, labelValidation Loss)plt.title(Loss vs Epochs)plt.xlabel(Epochs)plt.ylabel(Loss)plt.legend()# 准确率plt.subplot(1, 2, 2)plt.plot(epochs_range, accuracies, labelValidation Accuracy)plt.title(Accuracy vs Epochs)plt.xlabel(Epochs)plt.ylabel(Accuracy)plt.legend()plt.tight_layout()plt.show()if __name__ __main__:parse_opt()train()# 测试模型# model VGG16()# sample_input torch.randn(1, 3, 224, 224) # Batch size 为 1# output model(sample_input)# print(Final output shape:, output.shape) # 应输出 [1, 3] 注意本人的训练是用的gpu不推荐用cpu跑代码训练。 检测部分代码撰写 这一部分的代码主要实现的是输入任意大小的图片预测出它的种类。 1.导入头文件参数初始化 导入头文件参数标准化后读取图片并通过transform实现图片输入格式的设置。 import torch import torchvision from PIL import Image from torch import nn from torch.nn import MaxPool2d import argparse from pathlib import Path#--------------------------1.参数数据初始化----------------------------------- def parse_opt():parser argparse.ArgumentParser() # 创建 ArgumentParser 对象parser.add_argument(--Dropout_Val, typeint, default0.4, helpDropout_Val number) # 添加参数#--device cuda:0,cuda:1 启用多个设备parser.add_argument(--device, defaultcuda:0, helpcuda device, i.e. 0 or 0,1,2,3 or cpu) #--device cuda:1# 解析参数opt parser.parse_args()return optopt parse_opt() # 调用解析函数 Dropout_Val opt.Dropout_Val device torch.device(opt.device)image_path D:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\1.jpg image Image.open(image_path) #注意格式为RGBA print(image)image image.convert(RGB) #将格式变成RGB print(image)#确保你的图像预处理步骤如归一化与模型训练时使用的步骤相匹配。通常VGG16 需要将图像归一化到 [0, 1] 范围内 # 并可能需要减去均值和除以标准差 transform torchvision.transforms.Compose([torchvision.transforms.Resize((224, 224)),torchvision.transforms.ToTensor(),torchvision.transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ])image transform(image) print(image.shape)# 类别标签 class_names [ant, bee, dog] # 根据实际情况填写2.搭建VGG16网络结构 class VGG16(nn.Module):def __init__(self):super(VGG16, self).__init__()self.model nn.Sequential( # 构建子类可以减少foward代码撰写nn.Conv2d(in_channels3, out_channels64, kernel_size3, stride1, padding1),nn.Conv2d(in_channels64, out_channels64, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), #最大池化将224变成112nn.Conv2d(in_channels64, out_channels128, kernel_size3, stride1, padding1),nn.Conv2d(in_channels128, out_channels128, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 56x56nn.Conv2d(in_channels128, out_channels256, kernel_size3, stride1, padding1),nn.Conv2d(in_channels256, out_channels256, kernel_size3, stride1, padding1),nn.Conv2d(in_channels256, out_channels256, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 28x28nn.Conv2d(in_channels256, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 14x14nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 7x7)# 使用AdaptiveAvgPool2d来确保输出为固定大小self.avgpool nn.AdaptiveAvgPool2d((7, 7))# 全连接层self.fc1 nn.Linear(in_features512 * 7 * 7, out_features4096)self.fc2 nn.Linear(in_features4096, out_features4096)self.fc3 nn.Linear(in_features4096, out_features3)self.relu nn.ReLU()self.dropout nn.Dropout(Dropout_Val)def forward(self, x):x self.model(x)x self.avgpool(x) # 使用自适应平均池化x x.view(x.size(0), -1) # 拉平操作x self.relu(self.fc1(x))x self.dropout(x)x self.relu(self.fc2(x))x self.dropout(x)x self.fc3(x)return x3.输出测试结果 输出测试结果需要将图片送入VGG16网络进行计算带入训练好的权值vgg16_1.pth得出预测结果将预测的结果输出成概率从而计算是什么品种。 model VGG16() model torch.load(vgg16_1.pth) #模型的权重在GPU上而输入张量在CPU上。要解决这个问题你可以将输入张量移动到GPU device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device) image image.to(device) #模型的权重在CPU上而输入张量在GPU上。要解决这个问题你可以将输入张量移动到CPU #model torch.load(tudui_0.pth,map_locationtorch.device(cpu)) image torch.reshape(image,(1,3,224,224)) model.eval() with torch.no_grad():output model(image) predicted_index output.argmax(1).item() # 获取预测的索引 print(output.argmax(1)) print(output) #输出结果预测的是第六个类别 print(Predicted index:, predicted_index) # 输出对应的类别名称 print(Predicted class:, class_names[predicted_index])测试输出效果 其实多训练几次预测效果还是可以的。 测试整体代码 # vgg16网络测试文件,第一代测试代码主要功能如下 # 任意输入一张图片输出判断类型,二代与一代相比就是多了参数标准化import torch import torchvision from PIL import Image from torch import nn from torch.nn import MaxPool2d import argparse from pathlib import Path#--------------------------1.参数数据初始化----------------------------------- def parse_opt():parser argparse.ArgumentParser() # 创建 ArgumentParser 对象parser.add_argument(--Dropout_Val, typeint, default0.4, helpDropout_Val number) # 添加参数#--device cuda:0,cuda:1 启用多个设备parser.add_argument(--device, defaultcuda:0, helpcuda device, i.e. 0 or 0,1,2,3 or cpu) #--device cuda:1# 解析参数opt parser.parse_args()return optopt parse_opt() # 调用解析函数 Dropout_Val opt.Dropout_Val device torch.device(opt.device)image_path D:\\Pycharm\\Pytorch_test\\数据集\\练手数据集\\1.jpg image Image.open(image_path) #注意格式为RGBA print(image)image image.convert(RGB) #将格式变成RGB print(image)#确保你的图像预处理步骤如归一化与模型训练时使用的步骤相匹配。通常VGG16 需要将图像归一化到 [0, 1] 范围内 # 并可能需要减去均值和除以标准差 transform torchvision.transforms.Compose([torchvision.transforms.Resize((224, 224)),torchvision.transforms.ToTensor(),torchvision.transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ])image transform(image) print(image.shape)# 类别标签 class_names [ant, bee, dog] # 根据实际情况填写#-------------------------------------2.搭建VGG16网络结构--------------------------------------------- class VGG16(nn.Module):def __init__(self):super(VGG16, self).__init__()self.model nn.Sequential( # 构建子类可以减少foward代码撰写nn.Conv2d(in_channels3, out_channels64, kernel_size3, stride1, padding1),nn.Conv2d(in_channels64, out_channels64, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), #最大池化将224变成112nn.Conv2d(in_channels64, out_channels128, kernel_size3, stride1, padding1),nn.Conv2d(in_channels128, out_channels128, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 56x56nn.Conv2d(in_channels128, out_channels256, kernel_size3, stride1, padding1),nn.Conv2d(in_channels256, out_channels256, kernel_size3, stride1, padding1),nn.Conv2d(in_channels256, out_channels256, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 28x28nn.Conv2d(in_channels256, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 14x14nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.Conv2d(in_channels512, out_channels512, kernel_size3, stride1, padding1),nn.MaxPool2d(kernel_size2, stride2), # 7x7)# 使用AdaptiveAvgPool2d来确保输出为固定大小self.avgpool nn.AdaptiveAvgPool2d((7, 7))# 全连接层self.fc1 nn.Linear(in_features512 * 7 * 7, out_features4096)self.fc2 nn.Linear(in_features4096, out_features4096)self.fc3 nn.Linear(in_features4096, out_features3)self.relu nn.ReLU()self.dropout nn.Dropout(Dropout_Val)def forward(self, x):x self.model(x)x self.avgpool(x) # 使用自适应平均池化x x.view(x.size(0), -1) # 拉平操作x self.relu(self.fc1(x))x self.dropout(x)x self.relu(self.fc2(x))x self.dropout(x)x self.fc3(x)return x#---------------------------3.输出测试结果----------------------------- model VGG16() model torch.load(vgg16_1.pth) #模型的权重在GPU上而输入张量在CPU上。要解决这个问题你可以将输入张量移动到GPU device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device) image image.to(device) #模型的权重在CPU上而输入张量在GPU上。要解决这个问题你可以将输入张量移动到CPU #model torch.load(tudui_0.pth,map_locationtorch.device(cpu)) image torch.reshape(image,(1,3,224,224)) model.eval() with torch.no_grad():output model(image) predicted_index output.argmax(1).item() # 获取预测的索引 print(output.argmax(1)) print(output) #输出结果预测的是第六个类别 print(Predicted index:, predicted_index) # 输出对应的类别名称 print(Predicted class:, class_names[predicted_index])最开始训练的次数有点少导致预测结果不理想后来去吃饭前设置训练epochs 500次回来发现结果变好了一点。提高准确率的方式很多还可以丰富训练集。注意我的权值文件权值vgg16_1.pth可能使用的是权值vgg16_2.pth代码我就不改了。主要是要理解以上代码。 以上就是本人的心得与总结如有不足之处请多多包涵。 百度网盘链接代码权值及训练图片 https://pan.baidu.com/s/14xixodOGVEMK-KpE5rZTtw 提取码: dwrg
http://www.dnsts.com.cn/news/42554.html

相关文章:

  • 邢台专业网站建设源码营销策划与运营培训
  • 曰本免费一级a做爰视频网站wordpress author
  • 深圳哪个网站好推广一点吉工之家找工作建筑工作
  • 企业网站优化推广公司免费外贸网站
  • 网站建设公司商务网站项目书目前做网站框架
  • 南京网站建设案例快手自媒体平台注册入口
  • 木马工业设计公司seo培训赚钱
  • 免费创建个人网站美容整形网站模板
  • 海兴做网站莱州教体局网站
  • 请别人做网站的缺点百度申请完域名怎么建设网站
  • 网站建设需要哪些资质知乎 php网站开发书籍_
  • 企业做网站须要注意些什么如何用电脑主机做网站主机
  • 网站开发招标参数外包网站会自己做原型吗
  • 确定网站设计公司简报网站建设80hoe
  • 学院网站建设管理规章制度WordPress 固定域名
  • 怎么建公司网站账号如何做盗版电影网站
  • 哈尔滨网站建设一薇ls15227方维网络的服务范围
  • 南昌县城乡规划建设局官方网站wordpress如何修改布局
  • 素材动图网站南京怎样优化关键词排名
  • 最常见企业网站公司有哪些网站seo外包价格
  • 找工作一般上什么网站比较好ps案例教程网站
  • 珠海网站搭建搜索引擎优化服务公司哪家好
  • 做网站建设工资多少电子政务 和网站建设总结
  • 深圳民治网站建设开发公司会议提纲
  • 无锡手机网站开发wordpress 博客搭建
  • 平凉网站建设软件生成器
  • 成都市金堂县网站建设百度智能云
  • 如何建立手机网站永久免费空间免备案
  • 企业网站用什么域名网站程序 不能创建文件夹
  • 专门做尾单的那个网站叫啥承包工地的网站