前几天在百度的aistudio上使用yolov4训练了一下人脸检测的模型,今天看见有人留言希望我写一篇在aistudio上如何使用yolov4的教程,纠结了一下,因为这玩意的操作流程其实在我那篇yolov4的文章以及其他人的文章中都有,只不过那些文章不是针对aistudio,想了想,最近也是好久没有更新csdn了,正好有人有这个需求,那么就写吧。

如何在aistudio上注册上的我就不说了,反正注册后进入个人中心,然后点击项目创建项目,取名添加数据集这些,如下:
我们这里是进行人脸检测,所以需要添加的数据集叫wider_face,添加完后启动项目进入系统,进去之后选择终端,输入nvidia-smi命令,输入之后可以看见下面效果:
如果出现红色部分,根据我的经验,因为系统中默认安装的是cuda9.2,如果在这种情况下进行yolov4的编译会出现问题,此时我们要停止这个项目,然后再重新启动这个项目。进去之后,再在终端输入nvidia-smi命令,如果红色边框部分不存在了,那么基本上就可以编译成功了,可以进行下一步操作了。我这刚刚停止试了一下,还是存在,算了,我就不折腾了,反正之前都已经编译好了的。

我们可以看看整个文件结构了,如下:
data文件夹里面就是加载的数据集,work文件夹里面默认啥都没有,我们将yolov4的文件放到这里面就行,至于yolov4的源文件和预训练模型,yolov4源代码和预训练模型,点击它就可以下载,这里要注意一下,aistudio里面只能最大上传150m的数据,而预训练模型超过了150m,所以我们可以采取第一张图片中的创建数据集的方法将这些预训练模型放到data里面,然后添加自己的数据集。

当我们将yolov4的源代码和预训练模型通过创建自己的数据集的方式放到系统的data文件夹里面之后,我们要使用cd进入文件夹,和使用uzip来解压文件,类型下面这张:
然后我们再使用cp命令将yolov4的数据拷贝到work文件里面,哎,算了,我就不操作这一步了,相信这些基本操作对于玩aistudio的你都是小问题,是我累述了。

接下来,我们进入yolov4的文件夹,cd ~/work/darknet-master,类似这命令行,进去之后,使用ls,我们可以看见一个makefile文件,我们使用vim命令打开这个文件,打开之后,改成下面这种:
先附上作者多这些的解释:

其中第三行你可以改也可以不改,这是针对特斯拉还有啥显卡的忘记了,恰好aistudio上就是特斯拉显卡。LIBSO也可以不改,修改完后,按esc然后:,然后输入wq,enter退出,这是vim的基本操作,大家没使用过的可以参考一下,如果使用过程出现啥问题,建议百度。修改保存后,我们又回到了yolov4的文件夹,然后直接在终端输入make,注意终端要在yolov4的文件夹下面输入make,然后就开始编译了,一般来说,编译会很正常,我遇到的编译异常就是上面那红色边框里面会显示cuda-10.1的情况,在那种情况下,我是没有成功编译成功过的,只能停止这个项目再进入,看红色边框的内容会不会消失,只要一次编译成功,后面再进入项目,不管有不有红色边框的内容,都无所谓了,反正之前就编译好了。

编译成功后,你使用ls或者直接在左端的界面打开yolov4的文件夹,会看见一个darknet程序,如果能看见,那么就代表编译成功了,接下来,我们就可以进行数据的预处理了,我们利用cd命令进入到wider_face数据存放的文件夹,我这里wider_face是放到:
我们在命令行进入到这个文件夹,然后使用unzip命令进行解压,类似下面这种:

我们主要将下面三个文件进行解压:
解压之后会生成下面几个文件夹:

接下来我们就可以生成voc数据集和生成yolov4需要的数据类型了,直接给你们处理的源代码吧,也是我根据他人的源代码改的,到时候把这两个py文件放到你想放到的地方,我是放到~/work/darknet-master/data/wider_face/下面的,你到时候只需要在文件中改一两个地方然后直接运行即可:

# -*- coding: utf-8 -*-,这是转化为voc数据import shutil
import random
import os
import string
import cv2headstr = """\
<annotation><folder>VOC2007</folder><filename>%06d.jpg</filename><source><database>My Database</database><annotation>PASCAL VOC2007</annotation><image>flickr</image><flickrid>NULL</flickrid></source><owner><flickrid>NULL</flickrid><name>company</name></owner><size><width>%d</width><height>%d</height><depth>%d</depth></size><segmented>0</segmented>
"""
objstr = """\<object><name>%s</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>%d</xmin><ymin>%d</ymin><xmax>%d</xmax><ymax>%d</ymax></bndbox></object>
"""tailstr = '''\
</annotation>
'''def writexml(idx, head, bbxes, tail):filename = ("Annotations/%06d.xml" % (idx))f = open(filename, "w")f.write(head)for bbx in bbxes:f.write(objstr % ('face', bbx[0], bbx[1], bbx[0] + bbx[2], bbx[1] + bbx[3]))f.write(tail)f.close()def clear_dir():if shutil.os.path.exists(('Annotations')):shutil.rmtree(('Annotations'))if shutil.os.path.exists(('ImageSets')):shutil.rmtree(('ImageSets'))if shutil.os.path.exists(('JPEGImages')):shutil.rmtree(('JPEGImages'))shutil.os.mkdir(('Annotations'))shutil.os.makedirs(('ImageSets/Main'))shutil.os.mkdir(('JPEGImages'))def excute_datasets(idx, datatype):f = open(('ImageSets/Main/' + datatype + '.txt'), 'a')f_bbx = open(('/home/aistudio/data/data4336/wider_face_split/wider_face_' + datatype + '_bbx_gt.txt'), 'r') # 这里需要改一下,主要是data4336这里,要对应到你的加载的wider_face对应的文件夹while True:filename = f_bbx.readline().strip('\n')if not filename:breakim = cv2.imread(('/home/aistudio/data/data4336/WIDER_' + datatype + '/images/' + filename))head = headstr % (idx, im.shape[1], im.shape[0], im.shape[2])nums = f_bbx.readline().strip('\n')bbxes = []if nums=='0':bbx_info= f_bbx.readline()continuefor ind in range(int(nums)):bbx_info = f_bbx.readline().strip(' \n').split(' ')bbx = [int(bbx_info[i]) for i in range(len(bbx_info))]# x1, y1, w, h, blur, expression, illumination, invalid, occlusion, poseif bbx[7] == 0:bbxes.append(bbx)writexml(idx, head, bbxes, tailstr)shutil.copyfile(('/home/aistudio/data/data4336/WIDER_' + datatype + '/images/' + filename), ('JPEGImages/%06d.jpg' % (idx)))f.write('%06d\n' % (idx))idx += 1f.close()f_bbx.close()return idxif __name__ == '__main__':clear_dir()idx = 1idx = excute_datasets(idx, 'train')idx = excute_datasets(idx, 'val')print('Complete...')

接下来是转化为yolov4需要的数据,这个文件里面没有啥需要改的,直接运行:

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join# sets=[('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007_test', 'test')]#
sets=[('face', 'train'), ('face', 'val')]#
#
# classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]classes = ["face"]def convert(size, box):dw = 1./size[0]dh = 1./size[1]x = (box[0] + box[1])/2.0y = (box[2] + box[3])/2.0w = box[1] - box[0]h = box[3] - box[2]x = x*dww = w*dwy = y*dhh = h*dhif x == 0.0:x = 0.001if y == 0.0:y = 0.001return (x,y,w,h)def convert_annotation(year, image_id):in_file = open('./Annotations/%s.xml'%(image_id))out_file = open('./labels/%s.txt'%(image_id), 'w')tree=ET.parse(in_file)root = tree.getroot()size = root.find('size')w = int(size.find('width').text)h = int(size.find('height').text)for obj in root.iter('object'):difficult = obj.find('difficult').textcls = obj.find('name').textif cls not in classes or int(difficult) == 1:continuecls_id = classes.index(cls)xmlbox = obj.find('bndbox')b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))bb = convert((w,h), b)out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')if __name__=='__main__':wd = getcwd()for year, image_set in sets:if not os.path.exists('labels/'):os.makedirs('labels/')image_ids = open('./ImageSets/Main/%s.txt' % (image_set)).read().strip().split()list_file = open('%s_%s.txt' % (year, image_set), 'w')for image_id in image_ids:list_file.write('%s/JPEGImages/%s.jpg\n' % (wd, image_id))convert_annotation(year, image_id)list_file.close()

先运行第一个文件,然后运行第二个文件,运行完后,我们可以看见生成类型下面的文件夹结构:
你按照上面操作,也会生成这种结构,接下来,我们使用cd …这个命令进入到darknet里面的data文件夹,然后使用touch face.data命令行创建一个文件,然后使用vim face.data命令打开这个文件,在这个文件里面输入下面的文字:
classes= 1
train = data/wider_face/face_train.txt
valid = data/wider_face/face_val.txt
#difficult = data/difficult_2007_test.txt
names = data/face.names
backup = backup/

然后再保存退出后使用touch face.names命令行,然后用vim face.names打开这个文件,然后再这个文件里面输入:
face

就这几个单词,而且就这一行,因为这代表你的类别。

好了,数据预处理我们已经处理完了,接下来,我们开始修改cfg文件,我们cd 进入yolov4的cfg文件夹,你可以使用cp命令行复制yolov4.cfg然后再修改,也可以直接修改,随你,我们这里复制然后修改名字为face.cfg,然后使用vim命令打开这个cfg,打开之后开始修改,修改的地方有:classes=80修改为classes=1, filters=255修改为filters=18,还有batch和subdivisions根据显存实际情况来修改,我这里是修改为了batch=64 ,subdivisions=16(显存为32g,如果显存为16g,将16改为32),在就是将test部分注释掉(一般cfg里面是注释掉了的,注意看一下,这里是训练模型必须操作,不然训练模型的时候会出错),类似下面这种:
使用vim可以通过/classes这种/加上搜索的内容 来定位目标然后修改。还有一个地方要修改,mosaic=1改为mosaic=0,这里应该是跟opencv相联系的,但是在服务器上,我们没有配置opencv,所以我们这里改为0,不需要图形界面显示效果,如果不改,后面训练会出错。

ok,准备工作都做完了,我们接下来,回到yolov4的文件夹,然后使用./darknet detector train data/face.data cfg/face.cfg yolov4.conv.137命令,就会出现下面的情况了:
训练过程的输出很可能会出现nan的情况,只要红色边框里面的内容不出现nan,就代表训练正常。

好了,当我的avg loss 在3左右徘徊的时候我停止了训练,然后把跑下来的模型face_lastweight拿到我自己的电脑上测试,使用命令:./darknet detector test data/face.data cfg/face.cfg face_lastweight 测试了一下,测试的效果如下:


后面这张有一个预测错了,其余的人脸都预测到了,我后面又去训练了一下这个模型,对于第二张照片,还多预测错了一个,我怀疑是过拟合了,yolov4的作者也有专门介绍如何优化调参让模型更好的,大家有兴趣可以去看看:yolov4原作者,这篇文章,大家应该能看懂如何操作了,至于linux系统下的命令行这些,文章中说的有些潦草,感觉认真说起来就会让这篇文章太繁杂了。

2020 5.13

ps:今天又去训练了一下其它数据,然后又遇到了几个问题,写一下:
1:在aistudio上运行py文件,这个文件里面涉及到有些路径文件的读取,但是运行这个py文件的时候,一直在提示某些文件夹不存在,我以为是权限的问题,用chmod 777还是无法解决,然后我以为是绝对路径相对路径的问题,然后改成了~/work。。。。这种,但是还是不行,最后发现,的确是路径问题,但是,不能写成 ~/work这种,要写成/home/aistudio/work。。。这种绝对路径。

2:今天运行darknet来跑模型的时候,提示:Can’t open label file. (This can be normal only if you use MSCOCO),这个问题,我最开始以为是文件编码的问题,搞了很久,但是依旧存在,后面百度了一下,发现有大佬提供解决方案:我们不是有一个labels文件夹嘛,我们将这个文件夹里面的所有txt文件全部copy一份到 跑模型过程读取照片的文件夹下面,然后这个问题就解决了。
2020 6.20

百度aistudio上使用yolov4训练人脸检测模型相关推荐

  1. WiderFace数据集用于训练人脸检测模型

    下载链接: http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/ 该数据集可用于进行人脸检测模型的训练 如果做训练,可以点击网页中的 (国内还是百度吧,会快一 ...

  2. 目标检测 YOLO v3 训练 人脸检测模型

    YOLO,是You Only Look Once的缩写,一种基于深度卷积神经网络的物体检测算法,YOLO v3是YOLO的第3个版本,检测算法更快更准. 本文源码:https://github.com ...

  3. 使用卷积神经网络(CupCnn)训练人脸检测模型

    结果展示 最近尝试做了下人脸检测,先上两张效果图吧: 这已经是跳出来的效果比较好的图片了,表现的确是有点差. 我用了4000(19*19)多张人脸图片和8000(19*19)多张非人脸图片训练出了这个 ...

  4. yolo3训练人脸检测模型

    YOLOv3-model-pruning 用 YOLOv3 模型在一个开源的人手检测数据集 oxford hand 上做人手检测,并在此基础上做模型剪枝.对于该数据集,对 YOLOv3 进行 chan ...

  5. 百度开源业内首个口罩人脸检测及分类模型,携手开发者共同抗疫

    2020-02-13 15:33:32 允中 发自 凹非寺 量子位 编辑 | 公众号 QbitAI 抗击疫情,众志成城,人工智能技术正被应用到疫情防控中来. 2月13日,百度宣布免费开源业内首个口罩人 ...

  6. 百度开源业内首个口罩人脸检测及分类模型,携手开发者共同“抗疫”

    点击我爱计算机视觉标星,更快获取CVML新技术 允中 发自 凹非寺 量子位 编辑 | 公众号 QbitAI 抗击疫情,众志成城,人工智能技术正被应用到疫情防控中来. 2月13日,百度宣布免费开源业内首 ...

  7. 百度开源业内首个口罩人脸检测及分类模型

    抗击疫情,众志成城,人工智能技术正被应用到疫情防控中来. 2月13日,百度宣布免费开源业内首个口罩人脸检测及分类模型.该模型可以有效检测在密集人流区域中携带和未携戴口罩的所有人脸,同时判断该者是否佩戴 ...

  8. 大小仅1MB,超轻量级通用人脸检测模型登上GitHub趋势榜

    机器之心报道 项目作者:Linzaer 近日,用户 Linzaer 在 Github 上推出了一款适用于边缘计算设备.移动端设备以及 PC 的超轻量级通用人脸检测模型,该模型文件大小仅 1MB,320 ...

  9. java rfb,github上开源的超轻量级人脸检测模型及github地址。

    该模型设计是针对边缘计算设备或低算力设备(如用ARM推理)设计的实时超轻量级通用人脸检测模型,可以在低算力设备中如用ARM进行实时的通用场景的人脸检测推理,同样适用于移动端.PC.在模型大小上,默认F ...

最新文章

  1. 今日头条新员工哀叹:要抑郁了!入职没人带,需求不知道,名词不解,测试去哪儿不知道!...
  2. 【学时总结】◆学时·VIII◆ 树形DP
  3. 云计算之路-阿里云上:2013年4月7日14:15~18:35服务器故障经过
  4. Fiori Launchpad Tile点击后跳转的调试技巧
  5. linux下搜狗输入法无法输入中文解决方法
  6. 江苏师范大学计算机全国排名,国内131所二本师范大学最新排名(按录取分数线)...
  7. 知名的开源apm(Application Performance Management)工具
  8. 【Python玩转自动化运维】Python-基础1
  9. XTU 1236 Fibonacci
  10. php实现文件下载的几种方式
  11. 英特尔核显驱动hd630_英特尔首款独显 Xe Max 评测出炉:低于移动端 GTX 1050 Ti - 英特尔...
  12. 重装系统后计算机无法启动,Win7纯净版系统重装后无法开机的原因和解决方法...
  13. stm32闪存的理解
  14. 【恩墨学院】原来银行都在用这些数据库
  15. Python从无到有搭建接口(API)自动化测试框架
  16. Array数组方法-mdn
  17. 听故事的男同学,没了666
  18. 按键精灵--------后台插件
  19. 江苏工程职业技术学院计算机专业,江苏工程职业技术学院
  20. OSI(开放系统互联基本参考模型)七层结构及TCP/IP协议栈

热门文章

  1. java 使用 jacob 实现 将 freemarker 导出的 XML 格式的 excel 转 xls、xlsx 格式
  2. 3款最好用的甘特图软件有哪些?
  3. 多视图几何笔记(二)射影变换
  4. 求解n阶方阵的行列式
  5. 快应用信息流列表组件
  6. 凡人修真3D(4)神装
  7. 3.Python-复杂数据类型之列表、元组
  8. go-redis 使用
  9. 报名成功冲向高级软件工程师之路开始了
  10. DigiPCBA设计工具初体验!!!