适用于Windows和Linux的Yolo-v3和Yolo-v2(下)

适用于WindowsLinuxYolo-v3Yolo-v2(下)

如何训练(检测自定义对象):

(培养老YOLO V2 yolov2-voc.cfg,yolov2-tiny-voc.cfg,yolo-voc.cfg,yolo-voc.2.0.cfg,... 通过链接点击

训练Yolo v3:

1.      创建yolo-obj.cfg内容与中相同的文件yolov3.cfg(或复制yolov3.cfg到yolo-obj.cfg)和:

因此,如果classes=1应该filters=18。如果classes=2再写filters=21。

(不要写在cfg文件中:filters =classs + 5x3

(通常filters取决于classes,coords和的数量mask,即filters = (classes + coords + 1)*<number of mask>,其中maskanchor的索引。如果mask不存在,则filters = (classes + coords + 1)*num)

因此,例如,对于2个对象,文件yolo-obj.cfg应该yolov3.cfg在3 [yolo]层中的每一行中与以下行不同:

[convolutional]

filters=21

[region]

classes=2

2.      obj.names在目录中创建文件build\darknet\x64\data\,并带有对象名称-每个都在新行中

3.      obj.data在目录中创建文件build\darknet\x64\data\,其中包含(其中class =对象数):

classes= 2

train  = data/train.txt

valid  = data/test.txt

names = data/obj.names

backup = backup/

4.      将对象的图像文件(.jpg)放在目录中 build\darknet\x64\data\obj\

5.      应该在数据集中的图像上标记每个对象。使用此可视化GUI软件标记对象的边界框并为Yolo v2和v3生成注释文件:https : //github.com/AlexeyAB/Yolo_mark

将.txt为.jpg同一目录中具有相同名称但具有.txt-extension的每个-image-file- 创建一个-file ,并将其放置到文件中:该图像上的对象编号和对象坐标,用于新行中的每个对象:

<object-class> <x_center> <y_center> <width> <height>

哪里:

  • <object-class>-从0到的整数对象编号(classes-1)
  • <x_center> <y_center> <width> <height>-浮动值对于图片的宽度和高度,可以等于(0.0 to 1.0]
  • 例如:<x> = <absolute_x> / <image_width>或<height> = <absolute_height> / <image_height>
  • 注意:<x_center> <y_center>-矩形的中心(不是左上角)

例如,将为img1.jpg创建img1.txt包含:

1 0.716797 0.395833 0.216406 0.147222

0 0.687109 0.379167 0.255469 0.158333

1 0.420312 0.395833 0.140625 0.166667

6.      train.txt在directory中创建文件build\darknet\x64\data\,其中包含图像的文件名,每个文件名都换行,并具有相对于的路径darknet.exe,例如包含:

data/obj/img1.jpg

data/obj/img2.jpg

data/obj/img3.jpg

7.      下载卷积层的预训练权重并放入目录 build\darknet\x64

o   for csresnext50-panet-spp.cfg(133 MB):csresnext50-panet-spp.conv.112

o   对于yolov3.cfg, yolov3-spp.cfg(154 MB):darknet53.conv.74

o   for yolov3-tiny-prn.cfg , yolov3-tiny.cfg(6 MB):yolov3-tiny.conv.11

o   对于enet-coco.cfg (EfficientNetB0-Yolov3)(14 MB):enetb0-coco.conv.132

8.      使用命令行开始训练: darknet.exe detector train data/obj.data yolo-obj.cfg darknet53.conv.74

要在Linux上训练,请使用以下命令:(./darknet detector train data/obj.data yolo-obj.cfg darknet53.conv.74仅使用./darknet代替darknet.exe)

o   (文件每100次迭代yolo-obj_last.weights将保存到中build\darknet\x64\backup\)

o   (文件每1000次迭代yolo-obj_xxxx.weights将保存到中build\darknet\x64\backup\)

o   (darknet.exe detector train data/obj.data yolo-obj.cfg darknet53.conv.74 -dont_show如果在没有监视器的计算机(如云EC2)上训练,则可以禁用Loss-Window的使用)

o   (要在没有GUI的远程服务器上进行训练时查看mAP和损失图,请使用命令,darknet.exe detector train data/obj.data yolo-obj.cfg darknet53.conv.74 -dont_show -mjpeg_port 8090 -map然后http://ip-address:8090在Chrome / Firefox浏览器中打开URL )

8.1。对于每4个纪元(设置valid=valid.txt或train.txt在obj.data文件中)使用mAP(平均平均精度)计算进行训练并运行:darknet.exe detector train data/obj.data yolo-obj.cfg darknet53.conv.74 -map

9.      训练完成后- yolo-obj_final.weights从路径中获取结果build\darknet\x64\backup\

  • 每进行100次迭代后,可以停止,然后从这一点开始训练。例如,经过2000次迭代后,可以停止训练,之后再开始使用以下方法开始训练:darknet.exe detector train data/obj.data yolo-obj.cfg backup\yolo-obj_2000.weights

(在原始存储库https://github.com/pjreddie/darknet中,权重文件每1万次迭代仅保存一次if(iterations > 1000))

  • 同样,可以比所有45000次迭代更早地获得结果。

注意:如果在训练过程中看到(损失)字段的nan值avg-则训练有误,但如果出现nan在其行中-则训练进行得很好。

注意:如果在cfg文件中更改了width =或height =,则新的宽度和高度必须被32整除。

注意:训练后,请使用以下命令进行检测:darknet.exe detector test data/obj.data yolo-obj.cfg yolo-obj_8000.weights

注意:如果Out of memory发生错误,.cfg则应在-file文件中增加subdivisions=1632或64:链接

如何训练tiny-yolo(检测自定义对象):

执行与上述完整yolo模型相同的所有步骤。除了:

  • 下载yolov3-tiny的默认权重文件:https ://pjreddie.com/media/files/yolov3-tiny.weights
  • yolov3-tiny.conv.15使用以下命令获取预先训练的权重:darknet.exe partial cfg/yolov3-tiny.cfg yolov3-tiny.weights yolov3-tiny.conv.15 15
  • 使自定义模型yolov3-tiny-obj.cfg基于cfg/yolov3-tiny_obj.cfg而不是yolov3.cfg
  • 开始训练: darknet.exe detector train data/obj.data yolov3-tiny-obj.cfg yolov3-tiny.conv.15

要基于其模型(DenseNet201-YoloResNet50-Yolo)训练Yolo,可以下载并获取此文件中所示的预训练权重:https : //github.com/AlexeyAB/darknet/blob/master/build/ darknet / x64 / partial.cmd 如果创建的自定义模型不基于其模型,则可以在不预先训练权重的情况下对其进行训练,然后将使用随机初始权重。

什么时候应该停止训练:

通常,每个类(对象)需要进行2000次迭代,但总计不少于4000次迭代。但是对于何时停止训练的更精确定义,请使用以下手册:

1.      在训练期间,将看到各种错误指示,并且当不再减小0.XXXXXXX avg时应停止:

区域平均IOU:0.798363,类:0.893232,对象:0.700808,无对象:0.004567,平均调用率:1.000000,计数:8区域平均IOU:0.800677,类:0.892181,对象:0.701590,无对象:0.004574,平均调用率:1.000000 ,数:8

9002:0.211667,0.60730 平均,0.001000速率,3.868000秒,576128图像加载:0.000000秒

  • 9002-迭代编号(批处理数量)
  • 0.60730平均 -平均损失(错误)- 越低越好

当发现平均损失0.xxxxxx平均不再在许多次迭代中减少时,应该停止训练。最终平均损失可能从0.05(对于小模型和简单数据集)到3.0(对于大模型和困难数据集)之间。

2.      训练停止后,应该从中获取一些最新.weights文件,darknet\build\darknet\x64\backup并从中选择最好的文件:

例如,在9000次迭代后停止了训练,但最佳结果可以给出以前的权重之一(7000、8000、9000)。可能由于过度拟合而发生。过度拟合 -这种情况是可以从训练数据集中检测图像上的对象,但无法检测其图像上的对象的情况。应该从Early Stopping Point获得权重:

要从提前停止点获取重量:

2.1.首先,obj.data必须在文件中指定验证数据集的路径valid = valid.txt(格式valid.txt为中的train.txt),如果没有验证图像,则只需复制data\train.txt到即可data\valid.txt。

2.2如果在9000次迭代后停止训练,要验证以前的权重,请使用以下命令:

(如果使用另一个GitHub存储库,请使用darknet.exe detector recall...而不是darknet.exe detector map...)

  • darknet.exe detector map data/obj.data yolo-obj.cfg backup\yolo-obj_7000.weights
  • darknet.exe detector map data/obj.data yolo-obj.cfg backup\yolo-obj_8000.weights
  • darknet.exe detector map data/obj.data yolo-obj.cfg backup\yolo-obj_9000.weights

每个权重(7000、8000、9000)的comapre最后输出线:

选择具有最高mAP(平均平均精度)或IoU(与联合相交)的权重文件

例如,较大的mAP会赋予权重yolo-obj_8000.weights-然后使用此权重进行检测

或者只是用-map国旗训练:

darknet.exe detector train data/obj.data yolo-obj.cfg darknet53.conv.74 -map

因此,将在“损失图”窗口中看到“ mAP图”(红线)。将使用valid=valid.txt文件中指定的obj.data文件(1 Epoch = images_in_train_txt / batch迭代)为每个4个时期计算mAP

(将3类的最大x轴值更改max_batches=为-,将参数更改为2000*classesfe max_batches=6000)

 

自定义对象检测的示例: darknet.exe detector test data/obj.data yolo-obj.cfg yolo-obj_8000.weights

  • IoU(联合上方的相交)-对象联合上方的平均insectect和检测到的某个阈值= 0.24
  • mAP(平均平均精度)- average precisions每个类别的average precision平均值,其中是同一类别的每个可能阈值(每个检测概率)的PR曲线上11点的平均值(以PascalVOC表示的Precision-Recall,其中Precision = TP /(TP + FP)和Recall = TP /(TP + FN)),第11页:http//homepages.inf.ed.ac.uk/ckiw/postscript/ijcv_voc09.pdf

mAP是PascalVOC竞赛中默认的精度指标,与MS COCO竞赛中的AP50指标相同。在Wiki方面,指标Precision和Recall的含义与PascalVOC竞赛中的含义略有不同,但是IoU 始终具有相同的含义

如何在PascalVOC 2007上计算mAP

1.      要在PascalVOC-2007-test上计算mAP(平均平均精度):

                         i.         使用Darknet + Python:运行文件build/darknet/x64/calc_mAP_voc_py.cmd-将获得yolo-voc.cfg模型的mAP,mAP = 75.9%

                        ii.         使用Darknet的此分支:运行文件build/darknet/x64/calc_mAP.cmd-将获得yolo-voc.cfg模型的mAP,mAP = 75.8%

(本文指定YOLOv2 416×416:mAP的值为76.8%:https ://arxiv.org/pdf/1612.08242v1.pdf 。得出的值较低-可能是由于以下事实:该模型是在与进行检测的代码略有不同的源代码上训练的)

  • 如果要获取tiny-yolo-voc.cfg模型的mAP,则在.cmd文件中取消注释tiny-yolo-voc.cfg的注释行和yolo-voc.cfg的注释行
  • 如果Python 2.x的,而不是Python的3.x中,如果使用暗网+ Python的方式来获得地图,然后在CMD文件使用reval_voc.py和voc_eval.py替代reval_voc_py3.py,并voc_eval_py3.py从该目录:https://github.com/ AlexeyAB / darknet / tree / master / scripts

自定义对象检测:

自定义对象检测的示例: darknet.exe detector test data/obj.data yolo-obj.cfg yolo-obj_8000.weights

如何改善物体检测:

1.      训练前:

  • random=1在.cfg-file文件中设置标志-通过训练Yolo不同的分辨率来提高精度:链接
  • 提高网络分辨率.cfg-file( height=608,width=608或32任何价值倍数) -会增加精度
  • 检查要检测的每个对象是否在数据集中被强制标记-数据集中的任何对象都不应没有标签。在大多数训练问题中-数据集中有错误的标签(通过使用某些转换脚本标记了第三方工具,得到了标签,...)。始终使用以下方法检查数据集:https : //github.com/AlexeyAB/Yolo_mark
  • 损失非常高,而mAP却很低,训练错了吗? -show_imgs在training命令的末尾运行带有flag的训练,是否看到正确的有界对象框(在Windows或文件中aug_...jpg)?如果否-训练数据集有误。
  • 对于要检测的每个对象-训练数据集中必须至少有一个相似的对象,并且形状大致相同:形状,对象的侧面,相对大小,旋转角度,倾斜度,照明度。理想的是,训练数据集应包含不同对象的图像:比例,旋转,照明,不同侧面,不同背景的图像-每个班级或以上,最好拥有2000张不同的图像,并且应训练2000*classes迭代次数或更多
  • 希望训练数据集包含带有不想检测的未标记对象的图像-无边界框的负样本(空.txt文件)-使用与带有对象的图像一样多的负样本图像
  • 标记对象的最佳方法是:仅标记对象的可见部分,或标记对象的可见和重叠部分,或标记比整个对象多一点(有一点间隙)?根据需要进行标记-希望如何检测。
  • 要在每个图像中使用大量对象进行训练,请在cfg文件max=200的最后[yolo]一层或最后一层中添加参数或更高的值[region](YoloV3可以检测到的全局最大对象数0,0615234375*(width*height)是宽度和高度是[net]cfg文件中部分的参数)
  • 用于训练小对象(将图像调整为416x416后小于16x16)-设置layers = -1, 11为https://github.com/AlexeyAB/darknet/blob/6390a5a2ab61a0bdf6f1a9a6b4a739c16b36e0d7/cfg/yolov3.cfg#L720而stride=4不是https: //github.com/AlexeyAB/darknet/blob/6390a5a2ab61a0bdf6f1a9a6b4a739c16b36e0d7/cfg/yolov3.cfg#L717
  • 对于小型和大型物体的训练,请使用修改后的模型:
    • 完整模型:5个yolo层:https ://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov3_5l.cfg
    • 小模型:3个yolo层:https ://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov3-tiny_3l.cfg
    • 空间完整模型:3个yolo层:https ://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov3-spp.cfg
  • 如果训练模型以将左对象和右对象区分为单独的类(左/右手,左/右转道路标志,...),则用于禁用翻转数据增强-在flip=0此处添加:https : //github.com /AlexeyAB/darknet/blob/3d2d0a7c98dbc8923d9ff705b81ff4f7940ea6ff/cfg/yolov3.cfg#L17
  • 一般规则-训练数据集应包括一组想要检测的相对大小的对象:
    • train_network_width * train_obj_width / train_image_width ~= detection_network_width * detection_obj_width / detection_image_width
    • train_network_height * train_obj_height / train_image_height ~= detection_network_height * detection_obj_height / detection_image_height

也就是说,对于Test数据集中的每个对象,Training数据集中必须至少有1个对象具有相同的class_id和大约相同的相对大小:

object width in percent from Training dataset 〜= object width in percent from Test dataset

也就是说,如果训练集中仅存在占图像80-90%的对象,则受训练的网络将无法检测到占图像1-10%的对象。

  • 要加快训练速度(降低检测精度),请执行“微调”而不是“转移学习”,请stopbackward=1在此处设置参数:https : //github.com/AlexeyAB/darknet/blob/6d44529cf93211c319813c90e0c1adb34426abe5/cfg/yolov3.cfg#L548 然后执行此命令:./darknet partial cfg/yolov3.cfg yolov3.weights yolov3.conv.81 81将创建一个文件yolov3.conv.81,然后使用权重文件yolov3.conv.81代替darknet53.conv.74
  • 每个:model of object, side, illimination, scale, each 30 grad转角和倾斜角- 从神经网络的内部角度来看,是不同的对象。因此,要检测的对象越多,应使用越复杂的网络模型。
  • 为了使检测到的边界框更准确,可以ignore_thresh = .9 iou_normalizer=0.5 iou_loss=giou在每个[yolo]图层上添加3个参数并进行训练,将增加mAP@0.9,但减少mAP@0.5。
  • 仅当是神经检测网络专家时-才为cfg文件width和height从cfg文件重新计算数据集的锚点: darknet.exe detector calc_anchors data/obj.data -num_of_clusters 9 -width 416 -height 416 然后在cfg文件anchors的3 [yolo]层中的每一层都设置相同的9 。但是,应该masks=为每个[yolo]层更改锚点的索引,以便第一个[yolo]层的锚点大于60x60,第二个层大于30x30,剩下第3个。同样,应该filters=(classes + 5)*<number of mask>在每个[yolo]层之前更改。如果许多计算出的锚不适合在适当的图层下-则只需尝试使用所有默认锚即可。

2.      训练后-用于检测:

  • 通过在.cfg-file(height=608和width=608)或(height=832和width=832)或(32的任意倍数)中设置来提高网络分辨率-这可以提高精度,并可以检测小对象:link
    • 无需再次训练网络,只需使用.weights已针对416x416分辨率进行训练的-file
    • 但是要获得更高的精度,应该使用更高分辨率的608x608或832x832进行训练,请注意:如果Out of memory发生错误,.cfg则应在-file文件中增加subdivisions=16,32或64:链接

如何标记对象的边界框并创建注释文件:

在这里,可以找到带有GUI软件的存储库,用于标记对象的有界框并为Yolo v2和v3生成注释文件:https : //github.com/AlexeyAB/Yolo_mark

与示例的:train.txt,obj.names,obj.data,yolo-obj.cfg,air1-6 .txt,bird1-4 .txt为2类的对象(空气,鸟)和train_obj.cmd与实施例如何培养这个图像组具有YOLO v2和v3

标记图像中对象的不同工具:

1.      在C ++中:https//github.com/AlexeyAB/Yolo_mark

2.      在Python中:https//github.com/tzutalin/labelImg

3.      在Python中:https//github.com/Cartucho/OpenLabeling

4.      在C ++中:https//www.ccoderun.ca/darkmark/

5.      在JavaScript中:https//github.com/opencv/cvat

使用Yolo9000

同时检测和分类9000个对象: darknet.exe detector test cfg/combine9k.data cfg/yolo9000.cfg yolo9000.weights data/dog.jpg

如何将Yolo用作DLLSO

  • 在Linux上
    • 使用build.sh或
    • darknet使用cmake或建立
    • 设置LIBSO=1在Makefile做make
  • 在Windows上
    • 使用build.ps1或
    • darknet使用cmake或建立
    • 编译build\darknet\yolo_cpp_dll.sln解决方案或build\darknet\yolo_cpp_dll_no_gpu.sln解决方案

有2个API:


1.      要将Yolo编译为C ++ DLL文件yolo_cpp_dll.dll-打开解决方案build\darknet\yolo_cpp_dll.sln,设置x64Release,然后执行以下操作:Build-> Build yolo_cpp_dll

o   应该已经安装了CUDA 10.0

o   要使用cuDNN,请执行以下操作:(右键单击项目)->属性-> C / C ++->预处理程序->预处理程序定义,然后在行的开头添加: CUDNN;

2.      要将Yolo用作C ++控制台应用程序中的DLL文件,请打开解决方案build\darknet\yolo_console_dll.sln,设置x64Release,然后执行以下操作:构建->构建yolo_console_dll

o   可以build\darknet\x64\yolo_console_dll.exe 使用以下命令从Windows资源管理器运行控制台应用程序:yolo_console_dll.exe data/coco.names yolov3.cfg yolov3.weights test.mp4

o   启动控制台应用程序并输入图像文件名后,将看到每个对象的信息: <obj_id> <left_x> <top_y> <width> <height> <probability>

o   要使用简单的OpenCV-GUI,应该//#define OPENCV在yolo_console_dll.cpp-file:链接中取消注释行

o   可以在视频文件上看到用于检测的简单示例的源代码:链接

yolo_cpp_dll.dll-API:链接

struct bbox_t {

    unsigned int x, y, w, h;    // (x,y) - top-left corner, (w, h) - width & height of bounded box

    float prob;                    // confidence - probability that the object was found correctly

    unsigned int obj_id;        // class of object - from range [0, classes-1]

    unsigned int track_id;        // tracking id for video (0 - untracked, 1 - inf - tracked object)

    unsigned int frames_counter;// counter of frames on which the object was detected

};

class Detector {

public:

        Detector(std::string cfg_filename, std::string weight_filename, int gpu_id = 0);

        ~Detector();

        std::vector<bbox_t> detect(std::string image_filename, float thresh = 0.2, bool use_mean = false);

        std::vector<bbox_t> detect(image_t img, float thresh = 0.2, bool use_mean = false);

        static image_t load_image(std::string image_filename);

        static void free_image(image_t m);

 

#ifdef OPENCV

        std::vector<bbox_t> detect(cv::Mat mat, float thresh = 0.2, bool use_mean = false);

            std::shared_ptr<image_t> mat_to_image_resize(cv::Mat mat) const;

#endif

};

posted @ 2020-07-16 17:49  吴建明wujianming  阅读(775)  评论(0编辑  收藏  举报