用ImageNet的数据集训练Faster R-CNN
2016-06-20 09:54
351 查看
用ImageNet的数据集训练Faster R-CNN问题汇总
一 有些xml文件有问题,需要修改二 object的长宽比有要求,否则训练过程中报错
anchor_target_layer.py”, line 137, in forward
gt_argmax_overlaps = overlaps.argmax(axis=0)
ValueError: attempt to get argmax of an empty sequence
object的bounding box的宽高比:
VOC2007:在0.117-15.500之间
ImageNet(ILSVRC2014):在0.03-48.50之间
把数据的宽高比至少约束在0.117-15.500才能保证训练
三 对图片的大小也有要求,不能太小
解决方法:
1.不是所有图片都有xml,所以我先根据Imagenet 数据集中bbox_train_v2中的xml文件把对应的图片复制出来。下面是matlab代码%根据xml(在多个文件夹下)的名字找到该图片,保存这个图片
clc;
clear;
maindir = '/media/zc/A/Imagenet2012/bbox_train_v2'; %标签路径
maindir2 = '/media/zc/A/Imagenet2012/img_train'; %图片路径
a = dir(maindir); % a 里面包括多个文件夹
b = a(3:end); % a 中三个隐藏的文件夹不要
n = size(b); % n 就是1000个文件夹
%num = 1; %xml一共有50多万个,如果不需要全部的,可以打开这几行注释,例如:从每个文件夹中拿出300个
for m = 1:n
name = b(m).name; % bbox_train_v2下的第一个文件名
str1 = strcat(maindir,'/',name); % 第一个文件下的所有xml 文件
dirs = dir(str1);
c = dirs(3:end); %有2个隐藏文件
for num = 1: length(c)
name2 = c(num).name; % bbox_train_v2下的第一个文件中的第一个xml文件
name3 = name2(1:end-4); % 去掉后缀
str2 = strcat(maindir2,'/',b(m).name,'/',name3,'.JPEG'); % 找到这个图片的位置
outpath = '<span style="font-family: 'microsoft yahei';">/media/zc/A/Imagenet2012/img_train_all</span><span style="font-family: 'microsoft yahei';">'; % 输出位置</span>
out = [outpath,'/',name3,'.JPEG'];
disp(out);
copyfile(str2,out);
% num = num + 1;
% if num == 300;
% break;
%end
end
end
2.把bbox_train_v2中1000个xml文件夹合并成一个allAnnotations文件夹
matlab代码如下,和上面的代码功能差不多%复制xml(在多个文件夹下)到一个文件夹下
clc;
clear;
maindir = '/media/zc/A/Imagenet2012/bbox_train_v2'; %标签路径
a = dir(maindir); % a 里面包括多个文件夹
b = a(3:end); % a 中三个隐藏的文件夹不要
n = size(b); % n 就是多个文件夹
for m = 1:n
name = b(m).name; % bbox_train_v2下的第一个文件名
str1 = strcat(maindir,'/',name); % 第一个文件下的所有xml 文件
dirs = dir(str1);
c = dirs(3:end);
for num = 1: length(c)
name2 = c(num).name;
str2 = strcat(maindir,'/',b(m).name,'/',name2);
outpath = '/media/zc/A/Imagenet2012/allAnnotations'; % 输出位置
out = [outpath,'/',name2];
disp(out);
copyfile(str2,out);
end
end
3.修改xml,挑出符合上述三个问题的xml
%更改xml中的name属性,顺便选取符合对象长宽比,图片不能太小的xml
clc;
clear;
path = '/media/zc/A/Imagenet2012/allAnnotations/'; %第二步中的文件
path2 = '/home/zc/py/data/VOCdevkit2007/VOC2007/Annotations'; %保存路径
str1 = strcat(path,'/','*.xml'); % 第一个文件夹下的所有xml 文件
dirs = dir(str1);
n = size(dirs);
for m = 1:n
name = dirs(m).name; % 一个xml文件名字
name2 = name(1:9); %这个名字的前九位,即类名
str2 = [path,'/',name]; %xml的读取绝对路径
str3 = [path2,'/',name]; %xml的保存绝对路径
xmlDoc = xmlread(str2); % 读取这个xml文件
%% Extract ID
IDArray = xmlDoc.getElementsByTagName('filename'); % 将所有filename节点放入数组IDArray
nodeContent = char(IDArray.item(0).getFirstChild.getData) % 提取当前节点的内容
Size = xmlDoc.getElementsByTagName('size'); %将所有size节点放入数组IDArray
thisItemS = Size.item(0);
childNodeS = thisItemS.getFirstChild ;
childNodeS = childNodeS.getNextSibling;
childNodeNm = char(childNodeS.getTagName) % 当前节点的名字,width
width = char(childNodeS.getFirstChild.getData) % 当前节点的内容 ,500
childNodeSS = childNodeS.getNextSibling.getNextSibling; %下一个属性
childNodeNm = char(childNodeSS.getTagName) % 当前节点的名字,height
height = char(childNodeSS.getFirstChild.getData) % 当前节点的内容 ,353
FDsObject = xmlDoc.getElementsByTagName('object'); % 将所有objetc节点放入数组FDsArray
A = [];
x = 0;
z = 0;
for i = 0 : FDsObject.getLength-1 % object有的xml文件中不止一个
thisItem = FDsObject.item(i);
childNode = thisItem.getFirstChild ;
childNode = childNode.getNextSibling;
childNodeNm = char(childNode.getTagName) % 当前节点的名字,name
childNodeData = char(childNode.getFirstChild.getData) % 当前节点的内容,n02111889,这个实例本身是正确的。有的内容是dog,需要改成对应的n0xxxxxxx
childNode.setTextContent(name2); %把n02111889 改成文件名字的前九位
FDsB = xmlDoc.getElementsByTagName('bndbox');
thisItemB = FDsB.item(0);
childNodeB = thisItemB.getFirstChild ;
childNodeB = childNodeB.getNextSibling;
childNodeNm = char(childNodeB.getTagName) % 当前节点的名字,xmin
xmin = char(childNodeB.getFirstChild.getData) % 当前节点的内容,177
childNodeC = childNodeB.getNextSibling.getNextSibling;
childNodeNm = char(childNodeC.getTagName) % 当前节点的名字,ymin
ymin = char(childNodeC.getFirstChild.getData) % 当前节点的内容,100
childNodeD = childNodeB.getNextSibling.getNextSibling.getNextSibling.getNextSibling;
childNodeNm = char(childNodeD.getTagName) % 当前节点的名字,xmax
xmax = char(childNodeD.getFirstChild.getData) % 当前节点的内容,274
childNodeE = childNodeB.getNextSibling.getNextSibling.getNextSibling.getNextSibling.getNextSibling.getNextSibling;
childNodeNm = char(childNodeE.getTagName) % 当前节点的名字,ymax
ymax = char(childNodeE.getFirstChild.getData) % 当前节点的内容,289
A = [A,(str2num(xmax) -str2num(xmin)) / (str2num(ymax) - str2num(ymin))]; % 把每个object的长宽比计算出来 保存在A 中
x = x + 1;
end
for y = 1 : x
if A(y) >0.177 && A(y) <15.5 && str2num(width) >200 && str2num(height) >200; %根据这几行 把object 长宽比正确的 以及 图片大小符合要求的保存到新的文件中
z = z + 1;
end
end
if x == z
xmlwrite(str3,xmlDoc);
end
end4.再根据Annotations找到对应的图片
%根据xml(在一个文件夹下)的名字找到该图片,保存这个图片
clc;
clear;
maindir = '/home/zc/py/data/VOCdevkit2007/VOC2007/Annotations/*.xml'; %标签路径
<span style="font-family: 'microsoft yahei';">maindir2 = '/media/zc/A/Imagenet2012/img_train_all'; </span> %第一步得到的
a = dir(maindir);
n = size(a);
for m = 1:n
name = a(m).name;
name2 = name(1:end-4);
str2 = strcat(maindir2,'/',name2,'.JPEG');
outpath = '/home/zc/py/data/VOCdevkit2007/VOC2007/JPEGImages/'; % 输出位置
out = [outpath,name2,'.JPEG'];
disp(out);
copyfile(str2,out);
end
5.我知道上面步骤比较麻烦,有的步骤可以合并,还能减少内存占用,但时间比较短,懒得把代码合并了。好了,经过修改,且满足要求的xml和对应的图片都选出来了,下面生成四个txt文件。我把图片,xml直接替换到VOC2007中。就像这篇博客中所说的那样http://blog.csdn.net/qq_26569761/article/details/51398656
有什么不懂,就把这篇博客看仔细点
把图片的名字保存到txt中 在shell中用这条语句
find /home/zc/py/data/VOCdevkit2007/VOC2007/JPEGImage -type f -exec echo {} \; > /home/zc/py/data/VOCdevkit2007/VOC2007/ImageSets/Main/all.txt
第一条路径是图片位置,第二条是txt保存位置
Main 下应该是train.txt val.txt trainval.txt test.txt
all.txt有几十万行,我是这样做的,把奇数行给test.txt.偶数行给trainval.txt
再把trainval.txt中的奇数行给train.txt.偶数行给val.txt
%把一个txt中的奇偶行分开保存到新的txt中
clc;
clear;
fidin=fopen('/home/zc/py/data/VOCdevkit2007/VOC2007/ImageSets/Main/trainval.txt');
fidout=fopen('/home/zc/py/data/VOCdevkit2007/VOC2007/ImageSets/Main/val.txt','w');
i = 0; %-1是奇 0是偶
while ~feof(fidin) % 判断是否为文件末尾
tline=fgetl(fidin); % 从文件读行
i = i + 1;
if rem(i,2) == 0;
fprintf(fidout,'%s\n',tline);
end
end
fclose(fidout);
fclose(fidin);然后就是修改其他文件,上面博客中都有。
有两个文件要改,要不然会出现assert (boxes[:, 2] >= boxes[:, 0]).all() 报错
一个是pascal_voc.py
在
x1 = float(bbox.find('xmin').text) - 1
y1 = float(bbox.find('ymin').text) - 1
x2 = float(bbox.find('xmax').text) - 1
y2 = float(bbox.find('ymax').text) - 1
的下面添加
if x1 < 0:
x1 = 0
if y1 < 0:
y1 = 0
另一个imdb.py
在
boxes[:, 2] = widths[i] - oldx1 - 1
的下面添加
for b in range(len(boxes)):
if boxes[b][2] < boxes[b][0]:
boxes[b][0] = 0
相关文章推荐
- MySQL 拼接成一个字符串
- 自动车牌识别(ANPR)练习项目学习笔记4(基于opencv)
- huststore - 高性能分布式存储服务
- 2016.6.20短期计划
- 基于MFC对话框程序中添加菜单栏 (CMenu)
- 第三方apk文件编译到系统文件(system.img)中的方法
- Win10系统电脑开机黑屏只有鼠标的终极解决方法图文教程
- 为什么要使用NoSQL
- 第十六周项目2—阅读程序(3)
- java下载文件中文文件名乱码问题(ie,谷歌,火狐)
- 取随机数据
- 树莓派上安装firefox
- Python中fileinput模块
- C2572 重定义默认参数 错误的几种情况
- PHP解决问题总结
- [Android] 使用Cookie保持会话
- 【经验总结】编写JavaScript代码时应遵循的14条规律
- 欢迎使用CSDN-markdown编辑器
- Android studio常用插件
- Linux下修改文件创建时间(修改文件更改时间)