缘由

2021年的暑假辅导学生参加首届长三角人工智能算法擂台赛。
初赛为基于AI开发平台ModelArts,使用Python语言编写代码,完成包括党徽、国徽、国旗、军礼、军徽、少先队徽、红领巾、团徽的党史图像检测挑战。

初赛小结

我们自行在网上找了1500张相关图片,并在ModelArts中开始标注,完成后用ModelArts内置的算法开始训练并打榜,有YOLOv3,v5以及Fast-RCNN。由于经费及每日打榜次数的限制,加上初赛时我们经验的不足,最终的成绩是0.52(满分为1,初高中分别排名,非官方参赛队不计入名次),幸好在我们组入围了决赛。

**PS1:**本以为训练集是不提供的,所以自行在网上找图片。后来官方提供了训练集,但此时不忍心丢弃已标注的图片,就在官方的训练集中挑选了300张,加之自行寻找的,共1800张进行训练的。

**PS2:**初赛的训练集中有一些图片是否需要标注给我们带来了很大的困扰:如黑白的、红色的、镂空的,卡通的党徽团徽队徽等等。标了担心对成绩有反作用(测试集不公开的),不标有担心测试集中有。

事后想想若我们对训练集精心挑选+标注一下,也许初赛的成绩会更好一些。

决赛赛题

主要考核点有交通信号灯识别、车道线检测、斑马线检测、限速标志识别、施工标志识别、障碍物检测等,其中交通信号灯、斑马线、限速标志检测算法需要基于AI开发平台ModelArts开发。

重点部分:
1、禁用内置YOLOv5
2、官方提供的数据集中有标志样例
3、官方明确表示,训练集和测试集中没有过分夸张的图片

因为决赛禁用内置YOLOv5,我们推测YOLOv5识别率相对会高一些,加之初赛我们组用了Fast-RCNN(费用较高,训练一次在100元左右),结果不甚理想,所以我们组决定尝试自行搭建本地YOLOv5的环境。

自行搭建本地YOLOv5的环境

Windows中安装深度学习环境pytorch+paddle(Anaconda+Pycharm)

在CSDN上找到了一篇8月底新发的搭建YOLOv5保姆级教程,https://blog.csdn.net/didiaopao/article/details/119787139。
参照教程,在一台系统为Server2012的服务器和一台WIN10的办公用机上同时搭建环境。由于这两台机器都没有显卡,所以跳过了安装显卡驱动的环节。安装好anaconda后,新建了pytorch和paddle的环境(都是基于python3.8的)。

__PS1:__事后找了一台有显卡(P106)的机器,不知为什么在安装pytorch环境时,选择清华源是显示报错,报错信息如下,大概意思是清华源上没有cuda11.1下pytorch的环境,无奈只能选择国外源。(但安装无显卡,仅仅是CPU的pytorch环境是可以选择清华源)

__PS2:__总结不推荐在Server2012上跑YOLOv5,若要用服务器跑,建议使用Server2019以上的版本。

在pycharm中新建工程,分别选择pytorch和paddle环境(CPU),参照教程里的验证代码,输出结果如下(安装成功)。

从Github下载YOLOv5程序+安装所需库

接下去,按如下教程(https://blog.csdn.net/didiaopao/article/details/119954291)从github上下载YOLOv5源码,解压后并在pycharm中以工程打开(选择pytorch环境)。在执行requestments文件的第一句语句 pip install -r requirements.txt后,发生如下错误。


打开test.py文件后,发现pycharm有如图错误提示,很明显是没有成功安装这两个库。

opencv_python库解决办法:

将opencv_python-4.5.1.18-cp38-cp38-win_amd64.whl复制到Anaconda中的pytorch环境的库安装目录(c:\Users\administrator.conda\envs\pytorch\Lib\site-package),打开Anaconda的命令提示符,激活pytorch环境,进入上述库安装目录,手动输入命令“pip install opencv_python-4.5.1.18-cp38-cp38-win_amd64.whl”,安装完成即可。

pycocotools库解决办法:

执行过pip install -r requirements.txt后,其实已安装了pycocotools库,但YOLOv5依旧说不满足所需,pycharm给出的报错信息是vc++,其实不需要安装相应的vc++。
参照以下方法即可解决:https://blog.csdn.net/Gao_qie/article/details/118391417

其实就是将高版本的库文件下载并解压后,直接复制替换原先安装的低版本的库文件。

这样就解决了opencv_python库和pycootools库不满足需求的问题。

XML转TXT:

接一下就可以跑训练了,但YOLOv5的数据集标签是TXT格式(矩形中心的坐标xy与wh的归一化值),若在ModelArts中标注后的格式为VOC的XML格式(如图),需要人工将XML的标签转换为TXT的格式,详细转换方法见链接https://blog.csdn.net/didiaopao/article/details/120022845

还需将数据集划分为训练集和验证集来进行YOLOv5模型的训练,一张图片的JPG文件名和标注TXT文件名必须一致。数据最好放在最外一级目录中,数据集的目录格式如下图所示。

配置自己的模型参数:

做好如上准备后,在正式跑YOLOv5之前还有一些准备工作。

第一、下载预训练权重文件
为了缩短网络的训练时间,并达到更好的精度,一般需加载预训练权重进行训练。而yolov5提供了几个预训练权重,可以对应不同的需求选择不同的版本的预训练权重。通过如下的图可以获得权重的名字和大小信息,可以预料的到,预训练权重越大,训练出来的精度就会相对来说越高,但是其检测的速度就会越慢。预训练权重可以通过这个网址 https://github.com/ultralytics/yolov5/releases 进行下载,如图,本文中以yolov5s.pt为预训练权重。

第二、修改数据配置文件
修改data目录下相应的yaml文件。找到data目录下的voc.yaml文件,将该文件复制一份,将复制的文件重命名,最好和项目相关,这样方便后面操作,这里我修改为csj52.yaml。

打开csj52.yaml文件修改其中的参数,首先将箭头1中的那一行代码注释掉,如果不注释则可能训练时候会报错;箭头2中需要将训练和测试的数据集的路径填上(绝对路径和相对路径都可以,绝对路径不可能出错);箭头3中需要检测的类别数,填写6,表明有6个类别;最后箭头4中填写需要识别的类别的名字(必须是英文,否则会乱码识别不出来)。

第三、修改模型配置文件
由于使用的是yolov5s.pt这个预训练权重,所以要使用models目录下的yolov5s.yaml文件中的相应参数(因为不同的预训练权重对应着不同的网络层数,所以用错预训练权重会报错)。同上修改data目录下的yaml文件一样,我们最好将yolov5s.yaml文件复制一份,然后将其重命名,我将其重命名为yolov5s_csj52.yaml。

打开yolov5s_csj52.yaml文件只需要修改如图中的nc后面的数字就好了,这里是识别六个类别。

其实下面两个参数depth_multiple和width_multiple就是模型的深度和层数的比例值,不同预训练模型的这两个值是不同的。
至此,相应的配置参数就修改好了。

跑YOLOv5训练:

找到train.py这个py文件,

然后找到主函数的入口,这里面有模型的主要参数。模型的主要参数解析如下所示。

if __name__ == '__main__':
"""opt模型主要参数解析:--weights:初始化的权重文件的路径地址--cfg:模型yaml文件的路径地址--data:数据yaml文件的路径地址--hyp:超参数文件路径地址--epochs:训练轮次--batch-size:喂入批次文件的多少--img-size:输入图片尺寸--rect:是否采用矩形训练,默认False--resume:接着打断训练上次的结果接着训练--nosave:不保存模型,默认False--notest:不进行test,默认False--noautoanchor:不自动调整anchor,默认False--evolve:是否进行超参数进化,默认False--bucket:谷歌云盘bucket,一般不会用到--cache-images:是否提前缓存图片到内存,以加快训练速度,默认False--image-weights:使用加权图像选择进行训练--device:训练的设备,cpu;0(表示一个gpu设备cuda:0);0,1,2,3(多个gpu设备)--multi-scale:是否进行多尺度训练,默认False--single-cls:数据集是否只有一个类别,默认False--adam:是否使用adam优化器--sync-bn:是否使用跨卡同步BN,在DDP模式使用--local_rank:DDP参数,请勿修改--workers:最大工作核心数--project:训练模型的保存位置--name:模型保存的目录名称--exist-ok:模型目录是否存在,不存在就创建
"""parser = argparse.ArgumentParser()parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path')parser.add_argument('--cfg', type=str, default='', help='model.yaml path')parser.add_argument('--data', type=str, default='data/coco128.yaml', help='data.yaml path')parser.add_argument('--hyp', type=str, default='data/hyp.scratch.yaml', help='hyperparameters path')parser.add_argument('--epochs', type=int, default=300)parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs')parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='[train, test] image sizes')parser.add_argument('--rect', action='store_true', help='rectangular training')parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')parser.add_argument('--notest', action='store_true', help='only test final epoch')parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class')parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer')parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')parser.add_argument('--project', default='runs/train', help='save to project/name')parser.add_argument('--entity', default=None, help='W&B entity')parser.add_argument('--name', default='exp', help='save to project/name')parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')parser.add_argument('--quad', action='store_true', help='quad dataloader')parser.add_argument('--linear-lr', action='store_true', help='linear LR')parser.add_argument('--label-smoothing', type=float, default=0.0, help='Label smoothing epsilon')parser.add_argument('--upload_dataset', action='store_true', help='Upload dataset as W&B artifact table')parser.add_argument('--bbox_interval', type=int, default=-1, help='Set bounding-box image logging interval for W&B')parser.add_argument('--save_period', type=int, default=-1, help='Log model after every "save_period" epoch')parser.add_argument('--artifact_alias', type=str, default="latest", help='version of dataset artifact to be used')opt = parser.parse_args()

训练自己的模型时需要修改如下几个参数。首先将weights权重yolov5s.pt的路径填写到对应的参数里面,然后将修好的models模型的yolov5s_csj52.yaml文件路径填写到相应的参数里面,最后将data数据的csj52.yaml文件路径填写到相对于的参数里面。这几个参数是必须要修改的参数。

    parser.add_argument('--weights', type=str, default='weights/yolov5s.pt', help='initial weights path')parser.add_argument('--cfg', type=str, default='models/yolov5s_csj52.yaml', help='model.yaml path')parser.add_argument('--data', type=str, default='data/csj52.yaml', help='data.yaml path')

还有几个参数需根据自己的需求来更改:

首先是模型的训练(迭代)轮次,这里默认是训练的300轮,但事实上150轮后,mAP值的变化是不大了,除非x6的预训练模型。

parser.add_argument('--epochs', type=int, default=100)

其次是输入图片的数量(与显存的大小有关)和工作的核心数,每台电脑的硬件配置不一样,所以需要根据电脑硬件性能来。
如出现如下报错信息,则是显存不够,需把batch-size和workers调小一些(默认都是4)。

parser.add_argument('--batch-size', type=int, default=4, help='total batch size for all GPUs')
parser.add_argument('--workers', type=int, default=4, help='maximum number of dataloader workers')

至此,就可以运行train.py函数训练自己的模型了。

推理测试:

等到数据训练好了以后,就会在主目录下产生一个run文件夹,在run/train/exp/weights目录下会产生两个权重文件,一个是最后一轮的权重文件,一个是最好的权重文件,就要利用这个最好的权重文件来做推理测试。除此以外还会产生一些验证文件的图片等一些文件。

打开主目录下的detect.py文件。

然后找到主函数的入口,这里面有模型的主要参数,解析如下所示。

if __name__ == '__main__':
"""--weights:权重的路径地址--source:测试数据,可以是图片/视频路径,也可以是'0'(电脑自带摄像头),也可以是rtsp等视频流--output:网络预测之后的图片/视频的保存路径--img-size:网络输入图片大小--conf-thres:置信度阈值--iou-thres:做nms的iou阈值--device:是用GPU还是CPU做推理--view-img:是否展示预测之后的图片/视频,默认False--save-txt:是否将预测的框坐标以txt文件形式保存,默认False--classes:设置只保留某一部分类别,形如0或者0 2 3--agnostic-nms:进行nms是否也去除不同类别之间的框,默认False--augment:推理的时候进行多尺度,翻转等操作(TTA)推理--update:如果为True,则对所有模型进行strip_optimizer操作,去除pt文件中的优化器等信息,默认为False--project:推理的结果保存在runs/detect目录下--name:结果保存的文件夹名称
"""parser = argparse.ArgumentParser()parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)')parser.add_argument('--source', type=str, default='data/images', help='source')  # file/folder, 0 for webcamparser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--view-img', action='store_true', help='display results')parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')parser.add_argument('--nosave', action='store_true', help='do not save images/videos')parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')parser.add_argument('--augment', action='store_true', help='augmented inference')parser.add_argument('--update', action='store_true', help='update all models')parser.add_argument('--project', default='runs/detect', help='save results to project/name')parser.add_argument('--name', default='exp', help='save results to project/name')parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')opt = parser.parse_args()

将刚刚训练好的最好的权重传入到推理函数中去。然后就可以对测试图像进行推理了。

parser.add_argument('--weights', nargs='+', type=str, default='runs/train/exp2/weights/best.pt', help='model.pt path(s)')

对图片进行测试推理,将如下参数修改成图片的路径,然后运行detect.py就可以进行测试了。

parser.add_argument('--source', type=str, default='VOCdevkit/yanzheng/', help='source')  # file/folder, 0 for webcam


推理测试结束以后,在run下面会生成一个detect目录,推理结果会保存在exp2目录下。如图所示。
图片的推理结果如下所示。效果还是很不错的。

上传ModelArts打榜:

接下去需要将本地训练的YOLOv5模型上传至ModelArts中进行打榜。
现在需要解决的问题是:需要将哪些文件导入至ModelArts的模型中,导入时的文件目录结构是又怎样的,

我们查阅了华为ModelArts的官方说明文档,了解上传自己模型时需要的注意点。由于水平有限,实现弄得有点吃力。
后来我们想到了如下的方法:
1、先用ModelArts内置的YOLOv5算法训练一次,生成的模型文件在OBS桶中,我们将OBS桶中模型文件(一个目录)导出至本地,尝试寻找其中需要替换成我们本地训练的YOLOv5模型的文件。
2、通过对比后,发现有5个文件需要替换。
3、替换后,将模型文件(一个目录)从OBS桶中导入至ModelArts,再打榜,是不是就解决问题了?
尝试后,的确是这样,打榜成功了,如下图所示。

精益求精:

如上的方法,我们第一次的打榜成绩为:0.5958。事后用了YOLOv5的x+300轮的迭代,取得了我们打榜的最高分0.6771,排在高中组的第一名。
后来我们尝试了其他的一些算法,如内置的Fast-RCNN,结果不甚理想。

高手的确很多,都是深藏不漏,在临近截止时间前,有许多高分出现,绝大多数都是初中组的,真是惭愧啊。
最后我们的成绩依旧在0.6771,高中组第四,全体排名的第13名。


说明:SH-HI 表示高中组;SH-MID表示初中组;图片中的第9名sh-mid-019不是官方的参赛队,不计入排名。

9月25日我们组的三位同学,还参加了在线的答辩。无论结果是什么,更重要的是过程,我们在这次的比赛中真的学到了很多很多。

最后附上我们的模型在ModelArts中在“部署上线”后的“在线服务”的测试截图。

首届长三角青少年人工智能擂台赛全记录(YOLOv5+Win10+Anaconda+Pycharm+ModelArts)相关推荐

  1. 【EISCI征稿中】上海 · 首届长三角人工智能产业发展论坛AINIT2020

    大会官网:www.ainit.org 截稿时间:2020年9月18日 大会时间:2020年9月18日-20日 大会地点:中国•上海 录用通知时间:3-5个工作日 收录检索:EI .SCOPUS检索 会 ...

  2. 2022世界人工智能大会全记录

    分享一个unity的云元宇宙视频论坛: 2022世界人工智能大会全记录 2022世界人工智能大会记录

  3. 【异地贷款】长三角住房公积金异地贷款流程记录

    [异地贷款]长三角住房公积金异地贷款 购房和贷款的坑 背景 申请异贷款证明 首次现场办理 申请注销后再次办理 结尾 购房和贷款的坑 写在前面,购房和贷款的坑: 1.外联通地下室公积金不贷款(内联通的贷 ...

  4. 元”启长三角 共享新未来!长三角数字干线元宇宙创新发展论坛暨第一届长三角元宇宙日在长三角绿洲智谷·赵巷成功举办

    5月30日下午,由工信部网络安全产业发展中心(工信部信息中心).长三角投资(上海)有限公司.青浦区经济委员会.青浦区科学技术委员会.青浦区科学技术协会指导,北京大数据协会元宇宙专委会主办,长三角赵巷新 ...

  5. 长三角农业一体化,从“大闸蟹联盟”开始

    秋风渐起,又到了一年中吃蟹的季节. 正如每年都会发生的一幕:电商巨头和物流老玩家们再度上演了一场大闸蟹争夺战,被消费者戏称为 "纸螃蟹"的蟹券再度进入消费旺季,围绕真假" ...

  6. 星淘惠跨境—长三角跨境电商行业发展峰会助推跨境电商发展

    两年的疫情,既带给我们困境,又在某些方面创造了机遇.可能这就是所谓的"上帝给你关上了一扇门,又会给你打开一扇窗".在过去两年,受疫情的影响,消费者的消费习惯发生变化,大量的消费者转 ...

  7. 区块链+长三角一体化国家战略+科创板,上海向全球区块链行业发出邀请

    区块链行业是2018年 全球当之无愧的"最热门"科技,然而在最近却进入了"寒冬 ".诸多区块链创业团队反应融资越来越难,自己从几个月前的资本宠儿摇身一变不吃香了 ...

  8. DL之RNN:人工智能为你写周董歌词——基于TF利用RNN算法实现【机器为你作词】、训练测试过程全记录

    DL之RNN:人工智能为你写周董歌词--基于TF利用RNN算法实现~机器为你作词~.训练&测试过程全记录 目录 输出结果 模型监控 训练.测试过程全记录 训练的数据集 输出结果 1.test0 ...

  9. DL之RNN:人工智能为你写代码——基于TF利用RNN算法实现生成编程语言代码(C++语言)、训练测试过程全记录

    DL之RNN:基于TF利用RNN算法实现生成编程语言代码(C语言).训练&测试过程全记录 目录 输出结果 监控模型 训练&测试过程全记录 训练的数据集展示 输出结果 1.test01 ...

最新文章

  1. 前端实例练习 - 轮播图
  2. IO口多路查理复用:三个单片机IO口控制六个LED
  3. dedecms 页面无刷新调取
  4. Spring 中的 bean 为什么默认单例?
  5. dz论坛ucenter打不开mysql_Discuz论坛搬家 ucenter info:can not connect to MySQL server解决办法...
  6. 黑客教父龚蔚演讲:钓鱼WiFi 也能照用不误
  7. Android使用自定义字体(自定义view)
  8. 机器学习基础算法27-聚类实战
  9. FPGA 闪烁LED
  10. 高德地图--水波雷达动画
  11. IPv6 address示例
  12. Spring Security如何防止会话固定攻击(session fixation attack)
  13. 3D游戏编程与设计作业六
  14. PS176.PD转HDMI芯片简介以及封装
  15. 双开助手多开分身版 v5.1.8
  16. 线上引流压测工具Meteor
  17. 蓝桥杯 算法训练 - 连续正整数的和 78这个数可以表示为连续正整数的和,1+2+3,18+19+20+21,25+26+27。   输入一个正整数 n(<=10000)   输出 m 行(n有m
  18. 交公粮了:我经常逛的技术网站
  19. 我的java开发及桌面工具集合分享
  20. NasNet实践:图像识别领域最佳模型

热门文章

  1. java中什么算是重载,java中什么是重载
  2. java中微秒时间相减_Java计算时间差(两个时间相减)
  3. nas怎么做网站服务器,服务器怎么搭建网站NAS存储搭建网站服务器
  4. 分布式数据库中间件Mycat2
  5. 详细解读Modbus RTU、Modbus ASCII、Modbus TCP的区别
  6. JS验证码(不区分大小写)
  7. 微信小程序实现美团goods商品列表页开发
  8. ubuntu net-tools
  9. 招聘计算机教师面试自我介绍,教师招聘面试的自我介绍
  10. 使用js设置快捷键操作页面,js热键控制页面操作