宝安专业网站设计公司,网站建设时怎么附加数据库,深圳市住房和建设局领导,做网站app需多少钱文章目录 0 前言1 项目运行效果2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 最后 0 前言
#x1f525;这两年开始毕业设计和毕业答辩的要求和难度不…文章目录0 前言1 项目运行效果2.算法原理2.1 算法简介2.2网络架构2.3 关键代码3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集4 模型训练5 最后0 前言这两年开始毕业设计和毕业答辩的要求和难度不断提升传统的毕设题目缺少创新和亮点往往达不到毕业答辩的要求这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。并且很难找到完整的毕设参考学习资料。为了大家能够顺利以及最少的精力通过毕设学长分享优质毕业设计项目提供大家参考学习今天要分享的是毕业设计 深度学习交通标志识别系统源码论文学长这里给一个题目综合评分(每项满分5分)难度系数3分工作量3分创新点4分 项目分享:见文末!1 项目运行效果视频效果毕业设计 深度学习交通标志识别系统2.算法原理整个互联网基本没有国内交通标志识别的开源项目(都是国外的)今天学长分享一个中国版本的实时交通标志识别项目非常适合作为毕业设计~这里学长做一个大致的demo讲解项目的大致原理作为参考实际项目要相对复杂。2.1 算法简介YOLOv5是一种单阶段目标检测算法该算法在YOLOv4的基础上添加了一些新的改进思路使其速度与精度都得到了极大的性能提升。主要的改进思路如下所示输入端在模型训练阶段提出了一些改进思路主要包括Mosaic数据增强、自适应锚框计算、自适应图片缩放基准网络融合其它检测算法中的一些新思路主要包括Focus结构与CSP结构Neck网络目标检测网络在BackBone与最后的Head输出层之间往往会插入一些层Yolov5中添加了FPNPAN结构Head输出层输出层的锚框机制与YOLOv4相同主要改进的是训练时的损失函数GIOU_Loss以及预测框筛选的DIOU_nms。2.2网络架构上图展示了YOLOv5目标检测算法的整体框图。对于一个目标检测算法而言我们通常可以将其划分为4个通用的模块具体包括输入端、基准网络、Neck网络与Head输出端对应于上图中的4个红色模块。YOLOv5算法具有4个版本具体包括YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x四种本文重点讲解YOLOv5s其它的版本都在该版本的基础上对网络进行加深与加宽。输入端-输入端表示输入的图片。该网络的输入图像大小为608*608该阶段通常包含一个图像预处理阶段即将输入图像缩放到网络的输入大小并进行归一化等操作。在网络训练阶段YOLOv5使用Mosaic数据增强操作提升模型的训练速度和网络的精度并提出了一种自适应锚框计算与自适应图片缩放方法。基准网络-基准网络通常是一些性能优异的分类器种的网络该模块用来提取一些通用的特征表示。YOLOv5中不仅使用了CSPDarknet53结构而且使用了Focus结构作为基准网络。Neck网络-Neck网络通常位于基准网络和头网络的中间位置利用它可以进一步提升特征的多样性及鲁棒性。虽然YOLOv5同样用到了SPP模块、FPNPAN模块但是实现的细节有些不同。Head输出端-Head用来完成目标检测结果的输出。针对不同的检测算法输出端的分支个数不尽相同通常包含一个分类分支和一个回归分支。YOLOv4利用GIOU_Loss来代替Smooth L1 Loss函数从而进一步提升算法的检测精度。2.3 关键代码classDetect(nn.Module):strideNone# strides computed during buildonnx_dynamicFalse# ONNX export parameterdef__init__(self,nc80,anchors(),ch(),inplaceTrue):# detection layersuper().__init__()self.ncnc# number of classesself.nonc5# number of outputs per anchorself.nllen(anchors)# number of detection layersself.nalen(anchors[0])//2# number of anchorsself.grid[torch.zeros(1)]*self.nl# init gridself.anchor_grid[torch.zeros(1)]*self.nl# init anchor gridself.register_buffer(anchors,torch.tensor(anchors).float().view(self.nl,-1,2))# shape(nl,na,2)self.mnn.ModuleList(nn.Conv2d(x,self.no*self.na,1)forxinch)# output convself.inplaceinplace# use in-place ops (e.g. slice assignment)defforward(self,x):z[]# inference outputforiinrange(self.nl):x[i]self.m[i](x[i])# convbs,_,ny,nxx[i].shape# x(bs,255,20,20) to x(bs,3,20,20,85)x[i]x[i].view(bs,self.na,self.no,ny,nx).permute(0,1,3,4,2).contiguous()ifnotself.training:# inferenceifself.onnx_dynamicorself.grid[i].shape[2:4]!x[i].shape[2:4]:self.grid[i],self.anchor_grid[i]self._make_grid(nx,ny,i)yx[i].sigmoid()ifself.inplace:y[...,0:2](y[...,0:2]*2-0.5self.grid[i])*self.stride[i]# xyy[...,2:4](y[...,2:4]*2)**2*self.anchor_grid[i]# whelse:# for YOLOv5 on AWS Inferentia https://github.com/ultralytics/yolov5/pull/2953xy(y[...,0:2]*2-0.5self.grid[i])*self.stride[i]# xywh(y[...,2:4]*2)**2*self.anchor_grid[i]# whytorch.cat((xy,wh,y[...,4:]),-1)z.append(y.view(bs,-1,self.no))returnxifself.trainingelse(torch.cat(z,1),x)def_make_grid(self,nx20,ny20,i0):dself.anchors[i].deviceifcheck_version(torch.__version__,1.10.0):# torch1.10.0 meshgrid workaround for torch0.7 compatibilityyv,xvtorch.meshgrid([torch.arange(ny).to(d),torch.arange(nx).to(d)],indexingij)else:yv,xvtorch.meshgrid([torch.arange(ny).to(d),torch.arange(nx).to(d)])gridtorch.stack((xv,yv),2).expand((1,self.na,ny,nx,2)).float()anchor_grid(self.anchors[i].clone()*self.stride[i])\.view((1,self.na,1,1,2)).expand((1,self.na,ny,nx,2)).float()returngrid,anchor_gridclassModel(nn.Module):def__init__(self,cfgyolov5s.yaml,ch3,ncNone,anchorsNone):# model, input channels, number of classessuper().__init__()ifisinstance(cfg,dict):self.yamlcfg# model dictelse:# is *.yamlimportyaml# for torch hubself.yaml_filePath(cfg).namewithopen(cfg,encodingascii,errorsignore)asf:self.yamlyaml.safe_load(f)# model dict# Define modelchself.yaml[ch]self.yaml.get(ch,ch)# input channelsifncandnc!self.yaml[nc]:LOGGER.info(fOverriding model.yaml nc{self.yaml[nc]}with nc{nc})self.yaml[nc]nc# override yaml valueifanchors:LOGGER.info(fOverriding model.yaml anchors with anchors{anchors})self.yaml[anchors]round(anchors)# override yaml valueself.model,self.saveparse_model(deepcopy(self.yaml),ch[ch])# model, savelistself.names[str(i)foriinrange(self.yaml[nc])]# default namesself.inplaceself.yaml.get(inplace,True)# Build strides, anchorsmself.model[-1]# Detect()ifisinstance(m,Detect):s256# 2x min stridem.inplaceself.inplace m.stridetorch.tensor([s/x.shape[-2]forxinself.forward(torch.zeros(1,ch,s,s))])# forwardm.anchors/m.stride.view(-1,1,1)check_anchor_order(m)self.stridem.stride self._initialize_biases()# only run once# Init weights, biasesinitialize_weights(self)self.info()LOGGER.info()defforward(self,x,augmentFalse,profileFalse,visualizeFalse):ifaugment:returnself._forward_augment(x)# augmented inference, Nonereturnself._forward_once(x,profile,visualize)# single-scale inference, traindef_forward_augment(self,x):img_sizex.shape[-2:]# height, widths[1,0.83,0.67]# scalesf[None,3,None]# flips (2-ud, 3-lr)y[]# outputsforsi,fiinzip(s,f):xiscale_img(x.flip(fi)iffielsex,si,gsint(self.stride.max()))yiself._forward_once(xi)[0]# forward# cv2.imwrite(fimg_{si}.jpg, 255 * xi[0].cpu().numpy().transpose((1, 2, 0))[:, :, ::-1]) # saveyiself._descale_pred(yi,fi,si,img_size)y.append(yi)yself._clip_augmented(y)# clip augmented tailsreturntorch.cat(y,1),None# augmented inference, traindef_forward_once(self,x,profileFalse,visualizeFalse):y,dt[],[]# outputsforminself.model:ifm.f!-1:# if not from previous layerxy[m.f]ifisinstance(m.f,int)else[xifj-1elsey[j]forjinm.f]# from earlier layersifprofile:self._profile_one_layer(m,x,dt)xm(x)# runy.append(xifm.iinself.saveelseNone)# save outputifvisualize:feature_visualization(x,m.type,m.i,save_dirvisualize)returnxdef_descale_pred(self,p,flips,scale,img_size):# de-scale predictions following augmented inference (inverse operation)ifself.inplace:p[...,:4]/scale# de-scaleifflips2:p[...,1]img_size[0]-p[...,1]# de-flip udelifflips3:p[...,0]img_size[1]-p[...,0]# de-flip lrelse:x,y,whp[...,0:1]/scale,p[...,1:2]/scale,p[...,2:4]/scale# de-scaleifflips2:yimg_size[0]-y# de-flip udelifflips3:ximg_size[1]-x# de-flip lrptorch.cat((x,y,wh,p[...,4:]),-1)returnpdef_clip_augmented(self,y):# Clip YOLOv5 augmented inference tailsnlself.model[-1].nl# number of detection layers (P3-P5)gsum(4**xforxinrange(nl))# grid pointse1# exclude layer counti(y[0].shape[1]//g)*sum(4**xforxinrange(e))# indicesy[0]y[0][:,:-i]# largei(y[-1].shape[1]//g)*sum(4**(nl-1-x)forxinrange(e))# indicesy[-1]y[-1][:,i:]# smallreturnydef_profile_one_layer(self,m,x,dt):cisinstance(m,Detect)# is final layer, copy input as inplace fixothop.profile(m,inputs(x.copy()ifcelsex,),verboseFalse)[0]/1E9*2ifthopelse0# FLOPsttime_sync()for_inrange(10):m(x.copy()ifcelsex)dt.append((time_sync()-t)*100)ifmself.model[0]:LOGGER.info(f{time (ms):10s}{GFLOPs:10s}{params:10s}{module})LOGGER.info(f{dt[-1]:10.2f}{o:10.2f}{m.np:10.0f}{m.type})ifc:LOGGER.info(f{sum(dt):10.2f}{-:10s}{-:10s}Total)def_initialize_biases(self,cfNone):# initialize biases into Detect(), cf is class frequency# https://arxiv.org/abs/1708.02002 section 3.3# cf torch.bincount(torch.tensor(np.concatenate(dataset.labels, 0)[:, 0]).long(), minlengthnc) 1.mself.model[-1]# Detect() moduleformi,sinzip(m.m,m.stride):# frombmi.bias.view(m.na,-1)# conv.bias(255) to (3,85)b.data[:,4]math.log(8/(640/s)**2)# obj (8 objects per 640 image)b.data[:,5:]math.log(0.6/(m.nc-0.999999))ifcfisNoneelsetorch.log(cf/cf.sum())# clsmi.biastorch.nn.Parameter(b.view(-1),requires_gradTrue)def_print_biases(self):mself.model[-1]# Detect() moduleformiinm.m:# frombmi.bias.detach().view(m.na,-1).T# conv.bias(255) to (3,85)LOGGER.info((%6g Conv2d.bias:%10.3g*6)%(mi.weight.shape[1],*b[:5].mean(1).tolist(),b[5:].mean()))# def _print_weights(self):# for m in self.model.modules():# if type(m) is Bottleneck:# LOGGER.info(%10.3g % (m.w.detach().sigmoid() * 2)) # shortcut weightsdeffuse(self):# fuse model Conv2d() BatchNorm2d() layersLOGGER.info(Fusing layers... )forminself.model.modules():ifisinstance(m,(Conv,DWConv))andhasattr(m,bn):m.convfuse_conv_and_bn(m.conv,m.bn)# update convdelattr(m,bn)# remove batchnormm.forwardm.forward_fuse# update forwardself.info()returnselfdefautoshape(self):# add AutoShape moduleLOGGER.info(Adding AutoShape... )mAutoShape(self)# wrap modelcopy_attr(m,self,include(yaml,nc,hyp,names,stride),exclude())# copy attributesreturnmdefinfo(self,verboseFalse,img_size640):# print model informationmodel_info(self,verbose,img_size)def_apply(self,fn):# Apply to(), cpu(), cuda(), half() to model tensors that are not parameters or registered buffersselfsuper()._apply(fn)mself.model[-1]# Detect()ifisinstance(m,Detect):m.stridefn(m.stride)m.gridlist(map(fn,m.grid))ifisinstance(m.anchor_grid,list):m.anchor_gridlist(map(fn,m.anchor_grid))returnselfdefparse_model(d,ch):# model_dict, input_channels(3)LOGGER.info(f\n{:3}{from:18}{n:3}{params:10}{module:40}{arguments:30})anchors,nc,gd,gwd[anchors],d[nc],d[depth_multiple],d[width_multiple]na(len(anchors[0])//2)ifisinstance(anchors,list)elseanchors# number of anchorsnona*(nc5)# number of outputs anchors * (classes 5)layers,save,c2[],[],ch[-1]# layers, savelist, ch outfori,(f,n,m,args)inenumerate(d[backbone]d[head]):# from, number, module, argsmeval(m)ifisinstance(m,str)elsem# eval stringsforj,ainenumerate(args):try:args[j]eval(a)ifisinstance(a,str)elsea# eval stringsexceptNameError:passnn_max(round(n*gd),1)ifn1elsen# depth gainifmin[Conv,GhostConv,Bottleneck,GhostBottleneck,SPP,SPPF,DWConv,MixConv2d,Focus,CrossConv,BottleneckCSP,C3,C3TR,C3SPP,C3Ghost]:c1,c2ch[f],args[0]ifc2!no:# if not outputc2make_divisible(c2*gw,8)args[c1,c2,*args[1:]]ifmin[BottleneckCSP,C3,C3TR,C3Ghost]:args.insert(2,n)# number of repeatsn1elifmisnn.BatchNorm2d:args[ch[f]]elifmisConcat:c2sum(ch[x]forxinf)elifmisDetect:args.append([ch[x]forxinf])ifisinstance(args[1],int):# number of anchorsargs[1][list(range(args[1]*2))]*len(f)elifmisContract:c2ch[f]*args[0]**2elifmisExpand:c2ch[f]//args[0]**2else:c2ch[f]m_nn.Sequential(*(m(*args)for_inrange(n)))ifn1elsem(*args)# moduletstr(m)[8:-2].replace(__main__.,)# module typenpsum(x.numel()forxinm_.parameters())# number paramsm_.i,m_.f,m_.type,m_.npi,f,t,np# attach index, from index, type, number paramsLOGGER.info(f{i:3}{str(f):18}{n_:3}{np:10.0f}{t:40}{str(args):30})# printsave.extend(x%iforxin([f]ifisinstance(f,int)elsef)ifx!-1)# append to savelistlayers.append(m_)ifi0:ch[]ch.append(c2)returnnn.Sequential(*layers),sorted(save)3 数据集处理中国交通标志检测数据集CCTSDB由长沙理工大学提供包括上万张有标注的图片推荐只使用前4000张照片因为后面有很多张图片没有标注需要一张一张的删除太过于麻烦所以尽量用前4000张图片没有标注的图片比较少而且对于一般网络来说训练4000张图片已经可以满足要求3.1 VOC格式介绍VOC格式主要包含三个文件夹AnnotationsImageSetsJPEGImages主要适用于faster-rcnn等模型的训练ImageSets下面有一个Main的文件夹如下图一定按照这个名字和格式建好文件夹Annotations这里是存放你对所有数据图片做的标注每张照片的标注信息必须是xml格式。JPEGImages用来保存你的数据图片一定要对图片进行编号一般按照voc数据集格式采用六位数字编码如000001.jpg、000002.jpg等。ImageSets该文件下有一个main文件main文件下有四个txt文件分别是train.txt、test.txt、trainval.txt、val.txt里面都是存放的图片号码。3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式将标注的数据提取出来并且排序并将里面每一行分割成一个文件3.3 手动标注数据集如果为了更深入的学习也可自己标注但过程相对比较繁琐麻烦。以下简单介绍数据标注的相关方法数据标注这里推荐的软件是labelimg通过pip指令即可安装相关教程可网上搜索pip install labelimg4 模型训练修改train.py中的weights、cfg、data、epochs、batch_size、imgsz、device、workers等参数训练代码成功执行之后会在命令行中输出下列信息接下来就是安心等待模型训练结束即可。篇幅有限更多详细设计见设计论文5 最后项目包含内容完整详细设计论文 项目分享:见文末!