飞机检测之practise_YOLOv2+自己改写

图片最后crop的大小为352x352;
看YOLOv2对于训练样本,都是维持原来比例进行resize的
我crop训练样本的标准:
(1)长宽都小于352的用原图
(2)大于的或者某个大于的,以所有物体的中心点去crop 352x352大小的图片块
(3)再以上面图像块的四个脚为中心点,再crop 352x352大小的图片块。由此一张图像要么是原图,要么生成5个另外的图像块作为训练样本。

代码见:

注意:对于原图中的框,暂时没有考虑边缘的情况,只考虑了,IOU>=0.5的目标(即原来对象的框和要crop的图像块之间的IOU),最后生成0001.jpg-1852.jpg来自原来训练样本;1853.jpg-2659.jpg来自原来的测试样本。

命令:
1)训练:./darknet detector train /home/echo/EXERCISEs/airplaneDetec/yolov3/voc.data /home/echo/EXERCISEs/airplaneDetec/yolov3/yolo-voc.cfg darknet19.conv.23 2>1 | tee /home/echo/EXERCISEs/airplaneDetec/yolov3/paul_train_log.txt

2)测试:./darknet detector recall /home/echo/EXERCISEs/airplaneDetec/yolov3/voc.data /home/echo/EXERCISEs/airplaneDetec/yolov3/yolo-voc.cfg /home/echo/EXERCISEs/airplaneDetec/yolov3/backup/yolo-voc_final.weights

结果,太差啦,得检查到底哪里出现问题,暂停:

飞机检测之practise_YOLOv2+自己改写_第1张图片

而用训练样本去测试,结果也只是如下:

飞机检测之practise_YOLOv2+自己改写_第2张图片

问题出现在哪里呢???

检查数据的生成是否有误,撸一遍:

(1)creat_list.py,生成train.txt(1000条), test.txt(195条)——》无误!!
(2)voc_label_change.py,生成相应的infrared_train.txt与infrared_test.txt,其中包含的都是路径,并且在labels文件夹下生成每张图片对应的.txt文件(注意都单位化了,并且原点在左上角。类别 中心点x坐标 中心点y坐标 宽 高)——》无误!!
(3)main_jpgxml.m,生成train.txt(1000条), test.txt(195条),其中包含图片路径以及xml文件路径——》无误!!
(4)create_list.sh,去生成 test_name_size.txt和trainval_name_size.txt,其中包含名字 高 宽——》随机检查,无误!!
(5)getImageSize.m,去验证这些训练以及测试图片的大小范围——》无误!!
(6)voc_label_change_no352.py只是生成label_orgin文件夹下面的,每张图片没有单位化的.txt文件。

以上都无误,检查:
(7)genTrainImage_352.m,第一部分无误,第二部分getLabel有误,应该是:

dw = 1/(max_x-min_x);
dh = 1/(max_y-min_y);

抽样,test.m文件检查。现在貌似都是对的了~~~

(8)creat_list1.py重新打乱生成train_final.txt以及test_final.txt;
(9)voc_label_change1.py重新生成infrared_train1.txt与infrared_test1.txt

代码:github.com/EchoIR/airplaneDetec/tree/yolov2_crop 

训练

/home/echo/darknet-master/darknet detector train /home/echo/EXERCISEs/airplaneDetec/yolov3/voc.data /home/echo/EXERCISEs/airplaneDetec/yolov3/yolo-voc.cfg /home/echo/darknet-master/darknet19.conv.23 2>1 | tee /home/echo/EXERCISEs/airplaneDetec/yolov3/paul_train_log2.txt

注意:加上tee之后,错误信息不会报错了(突然停止不知道是啥原因)。还是没错之后再加上比较好

批量测试

首先修改detect.c中validate_detector_recall下的代码:

list *plist = get_paths("/home/echo/EXERCISEs/airplaneDetec/yolov3/infrared_test1.txt");

/home/echo/darknet-master/darknet detector recall /home/echo/EXERCISEs/airplaneDetec/yolov3/voc.data /home/echo/EXERCISEs/airplaneDetec/yolov3/yolo-voc.cfg /home/echo/EXERCISEs/airplaneDetec/yolov3/backup/yolo-voc_final.weights,结果如下:

飞机检测之practise_YOLOv2+自己改写_第3张图片

这个结果还可以的嘛(但是经过很多的单张测试之后发现,很多明明只有飞机的一点点的,都认为是飞机了,不过事实上也就是,可能是在别的图像块中有这个飞机的出现,最后导致召回率很高,但是准确率与其相差好几个百分点)~~之前整体训练的结果是(比较差的咯~~):

ID:  194 Correct:  578 Total:  916RPs/Img: 3.91IOU: 51.65%Recall:63.10%proposals:  762Precision:75.85%

单张测试(之前的darkNet有点显示不好了,其实是必须在darknet-master主文件夹下才可以正常显示)

/home/echo/code_modify/darknet-master/darknet detector test /home/echo/EXERCISEs/airplaneDetec/yolov3/voc.data /home/echo/EXERCISEs/airplaneDetec/yolov3/yolo-voc.cfg /home/echo/EXERCISEs/airplaneDetec/yolov3/backup/yolo-voc_final.weights /home/echo/EXERCISEs/airplaneDetec/yolov3/JPEGImages/1669.jpg

LOSS曲线

只需改行数,后面的一行中的取余:

lines =10980
result = pd.read_csv('/home/echo/EXERCISEs/airplaneDetec/yolov3/paul_train_log2.txt', skiprows=[x for x in range(lines) if (x%6!=5)] ,error_bad_lines=False, names=['loss', 'avg', 'rate', 'seconds', 'images'])

运行以及结果:

python train_loss_visualization.py

飞机检测之practise_YOLOv2+自己改写_第4张图片

代码见:github.com/EchoIR/airplaneDetec/tree/yolov2_crop

写crop测试样本的代码:

在改代码想去记录每个位置出的图片块以及位置,后面出现“段错误(核心已转储)”的情况,经过错误审查发现,是因为栈溢出的错误。

后面自己把实现的函数写成location.c单独一个文件,编译的时候总是提醒,get_patchLocations
函数未定义,实际上只要在Makefile中添加location.o即可:

飞机检测之practise_YOLOv2+自己改写_第5张图片

具体修改代码见:github.com/EchoIR/airplaneDetec/tree/yolov2_crop

修改detector.c,添加locations.h以及locations.c文件。

改完代码之后看结果对比,单张图片命令:

echo@echo-PC:~/code_modify/darknet-master$ /home/echo/code_modify/darknet-master/darknet detector test /home/echo/EXERCISEs/airplaneDetec/yolov3/voc.data /home/echo/EXERCISEs/airplaneDetec/yolov3/yolo-voc.cfg /home/echo/EXERCISEs/airplaneDetec/yolov3/backup/yolo-voc_final.weights -out compar_test/23_crop compar_test/23.jpg

出现的问题:

(1)框没有进行一定的融合,比如:

飞机检测之practise_YOLOv2+自己改写_第6张图片

大框吃小框尽量给他吃掉。

解决:这个我估计是训练样本中有这种IOU很小,但是我也算成正样本的框,估计还不少。这个可以去检查正样本,把之前所有检测的都检测画出图来,分析!!!dete_all.sh:github.com/EchoIR/airplaneDetec/tree/yolov2_crop 


1.保存之前crop过的测试图像的结果进行分析:
1) 可能是训练样本中很多用部件训练,以至于有点像翅膀的也认为是飞机了
2) 有边缘的也认为是...

2.还原训练样本的xml文件,去掉一些不是正样本的样本。
不好还原,则draw_boxes.m去画框:github.com/EchoIR/airplaneDetec/tree/yolov2_crop去除训练样本中的某些可能会影响训练结果的正样本,再次进行训练

echo@echo-PC:~/darknet-master$ /home/echo/darknet-master/darknet detector train /home/echo/EXERCISEs/airplaneDetec/yolov3/voc.data /home/echo/EXERCISEs/airplaneDetec/yolov3/yolo-voc.cfg /home/echo/EXERCISEs/airplaneDetec/yolov3/backup/yolo-voc_final1.weights 2>1 | tee /home/echo/EXERCISEs/airplaneDetec/yolov3/paul_train_log3.txt

注意:这个再次进行训练会记得上次训练到多少,比如这是从1001batches开始训练的

同时也去掉测试图片(crop之后的)中的某些不合格的正样本,批量测试结果:

飞机检测之practise_YOLOv2+自己改写_第7张图片

上面设置的thresh = 0.25,前面也是,现在设置成0.5,则:

飞机检测之practise_YOLOv2+自己改写_第8张图片

看来上面去调整正样本还是很有效果的,哈哈!!突然想起,之前改了网络输入,这也可能是由于网络的输入大小的问题,改回352,thresh 依旧0.5,则

飞机检测之practise_YOLOv2+自己改写_第9张图片

thresh 保持0.25,则:

飞机检测之practise_YOLOv2+自己改写_第10张图片

证明之前的去掉一些不好的训练样本,以及测试样本中去掉个别只是飞机很小部件的正样本,再继续训练3000次,还是有效果的。thresh =0.4,则:

飞机检测之practise_YOLOv2+自己改写_第11张图片

(2)crop去检测的优势在于可以检测到或者更准地检测到大图中的小物体,而对于大图中的大物体,还是不进行crop好

解决:不用crop将原来的网络大小从352改成608会稍微好点:

飞机检测之practise_YOLOv2+自己改写_第12张图片

变成:

飞机检测之practise_YOLOv2+自己改写_第13张图片

用crop时,有啥变化呢:差不多,看不出来啥,也许是我本来crop下来的就是352,细节上本来就不欠缺啥。

(3)也不知道为啥,crop的反而喜欢检测一些无中生有的东西,比如:

飞机检测之practise_YOLOv2+自己改写_第14张图片

也可能是因为不进行crop的话,大图中的这些细节就看不清楚,所以不去检测出来而已

上面三个问题,只是针对问题(1)做了一些调整,现在去测试两个情况:

(1)把原来图当做测试样本去测试;
(2)把原来测试图采用crop的办法去测试。

以此对比两种方法:

1、去掉原图中某些不合格的正样本,放入Annotations重新生成labels
2、利用这个更改训练样本和个别测试样本,继续训练的模型,全部在针对之前crop好的测试图片进行测试一遍,结果保存于/home/echo/EXERCISEs/airplaneDetec/yolov3/YOLOv3_results_1000new(尺度还是用的352,不过thresh设置成0.4了,不管,继续),之前的在/home/echo/EXERCISEs/airplaneDetec/yolov3/YOLOv3_results中。

对比之后,效果是有的,部分假正样本少了一些,就算是thresh设置成0.4的有一部分原因,但是从上面批测试的结果来看,去除训练集合中的某些IUO不是很高的正样本,还是有些效果的~~

3、原图结果(352,0.4):

飞机检测之practise_YOLOv2+自己改写_第15张图片

测试样本采用crop的结果(352,crop_size = 352,0.4):

飞机检测之practise_YOLOv2+自己改写_第16张图片

结果是如此的不尽人意,召回率高,准确率低,应该就是出现了很多那种小的错框。

测试样本采用crop的结果(352,crop_size = 352,0.6):

飞机检测之practise_YOLOv2+自己改写_第17张图片

原图结果(352,0.25):

飞机检测之practise_YOLOv2+自己改写_第18张图片


补充:这边补充一个改批量测试中进行crop的代码,见detector1.c的validate_detector_recall函数部分。

github.com/EchoIR/airplaneDetec/tree/yolov2_crop


补充:test_detector函数解析

(1)layer l = net.layers[net.n-1];即最后一层的输出形式:

l.outputs = h*w*n*(classes + coords + 1);//每个框对应4个点的位置,classes +1类,就是一张图像有outputs个输出
l.output = calloc(batch*l.outputs, sizeof(float));

int obj_index = entry_index(l, 0, n*l.w*l.h + i, 4);//第i个格点第n层框的自信度起始位置
int box_index = entry_index(l, 0, n*l.w*l.h + i, 0);//第i个格点第n层框的预测的位置的起始位置,由此可见output中结果分布是,所有格点第一层框的h*w*(classes + coords + 1)个信息,第二层框的h*w*(classes + coords + 1)个信息,第三层...而每一层中首先存储的是所有格点那一层框的位置信息,再就是自信度信息。

注意:网络返回的不是直接的位置信息,位置信息是后面间接计算出来的:
box b;
b.x = (i + x[index + 0*stride]) / w;
b.y = (j + x[index + 1*stride]) / h;
b.w = exp(x[index + 2*stride]) * biases[2*n]  / w;
b.h = exp(x[index + 3*stride]) * biases[2*n+1] / h;
return b;

把船的那部分引进来

训练命令:

echo@echo-PC:~/darknet-master$ ./darknet detector train /home/echo/EXERCISEs/airplaneDetec/AirBoats/voc.data /home/echo/EXERCISEs/airplaneDetec/AirBoats/yolo-voc.cfg /home/echo/darknet-master/darknet19.conv.23 2>1 | tee /home/echo/EXERCISEs/airplaneDetec/AirBoats/paul_train_log.txt

注意:这边总是出现段错误,原因最后找到是steps=8000,12000和scales=.1,.1后面最好不要有注释。

批量测试结果:

飞机检测之practise_YOLOv2+自己改写_第19张图片

继续训练至25000万次,结果:

飞机检测之practise_YOLOv2+自己改写_第20张图片

nms = .2(之前是.4):

飞机检测之practise_YOLOv2+自己改写_第21张图片

thresh = 0.6(前面两次是0.25)nms = .2:

./darknet detector recall /home/echo/EXERCISEs/airplaneDetec/AirBoats/voc.data /home/echo/EXERCISEs/airplaneDetec/AirBoats/yolo-voc.cfg /home/echo/EXERCISEs/airplaneDetec/backup/yolo-voc_final.weights,结果:

飞机检测之practise_YOLOv2+自己改写_第22张图片

thresh = 0.6,nms = .4:

飞机检测之practise_YOLOv2+自己改写_第23张图片

thresh = 0.5,nms =0.6:

飞机检测之practise_YOLOv2+自己改写_第24张图片

thresh = 0.5,nms =0.8:

飞机检测之practise_YOLOv2+自己改写_第25张图片

挑选几张图片出来检测:
注意:若想用前面感知野更大的,则修改yolo-voc.cfg中的配置即可,即route和reorg层即可,但是估计显卡内存不够了,则把batch改小一点

你可能感兴趣的:(飞机检测之practise_YOLOv2+自己改写)