前段时间间做了猫狗识别的项目,采用的是pytorch这个框架,准确率达到了98%,其中对于神经网络 构建也采用了很多种方式,采用过迁移学习使用resnet50、resnet18、vgg16和vgg19,也尝试过自己构建神经网络(自己构建的准确率比较低,但是目的在于熟悉图片维度的计算)
首先我们要知道深度学习常用的几个框架有哪些,例如:TensorFlow、Keras、Pytorch等。
TensorFlow:这个框架是目前非常常用的
Keras:封装的比较好,容易上手,相对简单点
优点:极简,只需几行代码就能构建一个神经网络(对TensorFlow进行封装,相当于一个api)缺点:速度慢Pytorch:
优点:是一个动态的框架,在运算过程中,会根据不同的数值,按照最优方式进行合理安排缺点:在短时间内建立结果和方案更适合于计算机程序爱好者或者是小规模项目1.下面采用resnet50损失值和准确率,准确率在97%以上
2.自定义的神经网络准确率及损失值,由于自己写神经网络的目的在于了解神经网络的处理一张图片的计算流程 ,所以没太去深究提高准确率
下面这张更容易理解一点,计算机看到的一张图片是如下图右下角的图片,整体流程中包含输入层、隐藏层和输出层,中间的圈相当于人脑中的神经元
更加详细的一个卷积神经网络的处理过程,包括卷积层、池化层和全连接层
卷积层的作用是对输入的数据做特征提取,而完成该功能的是卷积核,如图为卷积核如何在卷积层进行运算(下图也是在网上经常见到的,备注:引用的图片)
池化层一般对数据进行进一步的特征提取,不仅实现对数据的压缩,还大量减少了参与模型计算的参数,从某种意义上讲,提升了计算效率,池化的方式有取最大、取最小以及取平均值
全连接层主要作用是将输入的图像在经过卷积核池化操作后提取的特征进行压缩,并根据压缩的特征完成模型的分类功能。
下面是我画的一个项目的思维导图,看图完全就可以看懂整个项目的流程,就不多用文字介绍了
下面是采用迁移学习resnet50实现的代码,用vgg16以及其它的网络模型的时候只需要更换网络模型即可,注释掉的class类是自定义的神经网络,想要学习流程的话可以看看,代码后面有注释
import torch import torchvision from torchvision import datasets,models,transforms import os from torch.autograd import Variable import torch.nn as nn import torch.utils.data import torch.nn.functional as F #from network import Net # class Net(nn.Module): # 新建一个网络类,就是需要搭建的网络,必须继承PyTorch的nn.Module父类 # def __init__(self): # 构造函数,用于设定网络层 # super(Net, self).__init__() # 标准语句 # self.conv1 = torch.nn.Conv2d(3, 16, 3, padding=1) # 第一个卷积层,输入通道数3,输出通道数16,卷积核大小3×3,padding大小1,其他参数默认 # self.conv2 = torch.nn.Conv2d(16, 16, 3, padding=1) # self.fc1 = nn.Linear(56*56*16, 128) # 第一个全连层,线性连接,输入节点数50×50×16,输出节点数128 # self.fc2 = nn.Linear(128, 64) # self.fc3 = nn.Linear(64, 2) # def forward(self, x): # 重写父类forward方法,即前向计算,通过该方法获取网络输入数据后的输出值 # x = self.conv1(x) # x = F.relu(x) # x = F.max_pool2d(x, 2) # x = self.conv2(x) # x = F.relu(x) # x = F.max_pool2d(x, 2) # x = x.view(x.size()[0], -1) # x = F.relu(self.fc1(x)) # x = F.relu(self.fc2(x)) # y = self.fc3(x) # return y data_dir = "F:/猫狗识别二/DogsVSCats" #图片处理 data_trainsforms = { "train":transforms.Compose([ #transforms.RandomResizedCrop(300), transforms.Resize((224,224)), #transforms.RandomCrop((224,224)), #transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5]), # transforms.ToTensor() ]), "test":transforms.Compose([ #transforms.RandomResizedCrop(300), #transforms.RandomHorizontalFlip(), transforms.Resize((224,224)), transforms.ToTensor(), transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5]), ]),} #拼接路径 image_datasets = { x:datasets.ImageFolder(root=os.path.join(data_dir, x), transform=data_trainsforms[x]) for x in ["train", "test"] } #数据加载器 data_loader = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=20, shuffle=True) for x in ["train", "test"] } X_example,y_example = next(iter(data_loader["train"])) example_classees = image_datasets["train"].classes index_classes = image_datasets["train"].class_to_idx #迁移学习模型 model = models.resnet50(pretrained = True) #自定义模型 #model = Net() Use_gpu = torch.cuda.is_available() for parma in model.parameters(): parma.requires_grad = False#屏蔽预训练模型的权重,只训练最后一层的全连接的权重 model.fc = torch.nn.Linear(2048,2) # print(model) if Use_gpu: model = model.cuda() #损失函数和优化器 loss_f = torch.nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.fc.parameters(),lr = 0.00001) #optimizer = torch.optim.Adam(model.parameters(),lr = 0.00001) epoch_n = 5 for epoch in range(epoch_n): print("Epoch {}/{}".format(epoch,epoch_n - 1)) print("-"*10) for phase in ["train","test"]: if phase == "train": print("training") model.train(True) else: print("testing") model.train(False) running_loss = 0.0 running_corrects = 0 for batch,data in enumerate(data_loader[phase],1): X,y = data if Use_gpu: X,y = Variable(X.cuda()),Variable(y.cuda()) else: X,y = Variable(X),Variable(y) y_pred = model(X) _,pred = torch.max(y_pred.data,1) optimizer.zero_grad() loss = loss_f(y_pred,y) if phase == "train": loss.backward()#反向传播计算当前梯度# 误差反向传播,采用求导的方式,计算网络中每个节点参数的梯度,显然梯度越大说明参数设置不合理,需要调整 optimizer.step()#优化采用设定的优化方法对网络中的各个参数进行调整 running_loss += loss.item() running_corrects += torch.sum(pred == y.data) if batch%250 == 0 and phase == "train": print("Batch{},Train Loss:{:.4f},Train ACC:{:.4f}".format(batch,running_loss/batch,100*running_corrects/(20*batch))) epoch_loss = running_loss*20/len(image_datasets[phase]) epoch_acc = 100*running_corrects/len(image_datasets[phase]) print("{} Loss:{:.4f} Acc:{:.4f}%".format(phase,epoch_loss,epoch_acc)) #torch.save(model.state_dict(),'model.ckpt1') # torch.save(model.state_dict(),'model.pth' print("over")
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131数据集采用两万五千张图片,来源于kaggle官网。先测试代码的话可以先用我上传在资源里面的测试集把它分一部分作为训练集就好,训练集太大不好上传。
猫狗识别对于深度学习来说是入门级的教程,但是对于新手真的很有必要完全弄懂这个例子,通过代码去回顾一些基本知识,例如权重、损失函数、数据加载器等一些基本知识和其对最后的准确率的影响。
相关知识
PyTorch深度学习:猫狗情感识别
基于Pytorch实现的声音分类
PyTorch猫狗:深度学习在宠物识别中的应用
CNN简单实战:PyTorch搭建CNN对猫狗图片进行分类
基于Pytorch框架的深度学习densenet121神经网络鸟类行为识别分类系统源码
基于深度学习的犬种识别系统详解(网页版+YOLOv8/v7/v6/v5代码+训练数据集)
基于深度学习的鸟类识别系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)
MeowBot:ESP32 语音控制宠物猫 DIY 教程——玩转语音识别与 MQTT 智能家居控制 (附代码解析)
3598
web网页html版通过CNN卷积神经网络的宠物行为训练识别
网址: 详解pytorch实现猫狗识别98%附代码 https://m.mcbbbk.com/newsview171544.html
上一篇: 虚拟桌宠模拟器 常见问题 Q&A |
下一篇: 在地面附近的真空中.存在着竖直向 |