RuntimeWarning: invalid value encountered in log targets_dw = np.log(gt_widths / ex_widths)
这个错误是你自己制作了数据集后,多出现在没有控制好边界的情况。我参考了csdn上大多数的解决方案都还没有成功,但是感觉知道了问题出现在哪了,没有能力解决。
先来列举网上的一些解决方法:
- 第一种
修改lib/datasets/pascal_voc.py中_load_pascal_annotation函数,该函数是读取pascal_voc格式标注文件的,下面几句中的-1全部去掉(pascal_voc标注是1-based,所以需要-1转化成0-based,如果我们的数据标注是0-based,再-1就可能溢出,所以要去掉),找到208行,将208行至211行每一行后面的-1删除,如下所示:
x1 = float(bbox.find(‘xmin’).text)
y1 = float(bbox.find(‘ymin’).text)
x2 = float(bbox.find(‘xmax’).text)
y2 = float(bbox.find(‘ymax’).text)
原因是因为我们制作的xml文件中有些框的坐标是从左上角开始的,也就是(0,0)如果再减一就会出现log(-1)的情况
如果这样之后还是出现类似的报错,那么说明依然有-1或者其他负数的情况出现。解决方法是打开./lib/model/config.py文件,找到flipp选项,将其置为False
__C.TRAIN.USE_FLIPPED = False
- 第二种:修改学习率
网上有人说可以通过修改学习率来解决,这个我感觉是没有用的,自己也修改过几次实验,没有用继续报错。因为此问题的本质还是在进行数据增强(进行水平翻转)标记坐标为负数或者超出图像范围。时
- 第三种
在图像增强的时候,在对图片坐标取值,没有考虑到坐标出现为0和标记坐标超图图像范围。但是数据集量又太大,不可能进行一一查找。解决方案如下:
修改lib/datasets/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
认为溢出只有可能是 boxes[b][0],我试验过,没有啥作用。
- 我自己认为,但是不会解决
希望前面各位大神们的方法就帮助你们解决问题。
下面是我认为的问题所在,就是在使用数据增强(水平翻转)的时候,没有控制好边界,使反转后的坐标中有负数。举一个小例子:
假如原来坐标 左上角 = (10,10),右下角=(50,30),所以
xmin = 10, xmax=50,
weight = 40, height=20
则进过翻转后的坐标:
新的xmin =weight-xmax=40-50= -10
新的xman = weight-xmin=40-10= 30
会出现负数。
# 数据增强的代码详解,上面的例子计算公式通过此代码进行的。
def append_flipped_images(self):
num_images = self.num_images
#格式:list
widths = self._get_widths()
#self.roidb最后调用到pascal_voc.gt_roidb.最后返回的是一个列表,列表中存图像信息dict
for i in xrange(num_images):
#如果不用.copy()则会出现对应同一个存储区域的异名参数,如引用,copy则会另分出一个储存空间,对原数据无影响
#boxes为([猫1的四个bbox值],[猫2的四个bbox值]..)
boxes = self.roidb[i]['boxes'].copy()
#取出该幅图片所含bbox的xmin、xmax,存在oldx1.oldx2的np.array里
#e.g.boxes为([1,2,3,4],[7,8,9,10])则oldx1(1,7)oldx2(3,9)
oldx1 = boxes[:, 0].copy()
oldx2 = boxes[:, 2].copy()
#记录反转后的boxes信息,ymin,ymax没变,width-oldx2对应新的xmin,width-oldx1对应新的xmax
boxes[:, 0] = widths[i] - oldx2 - 1
boxes[:, 2] = widths[i] - oldx1 - 1
#插入一个异常,如果该式子不是所有都成立,则数据读取有异常
#.all()函数如果对应iterable中有一个false,则返回false
assert (boxes[:, 2] >= boxes[:, 0]).all()
#将新的boxes信息存入 entry字典
entry = {'boxes' : boxes,
'gt_overlaps' : self.roidb[i]['gt_overlaps'],
'gt_classes' : self.roidb[i]['gt_classes'],
'flipped' : True}
#将entry依次加入roidb列表,回忆一下roidb列表中存的是图片信息dict,图片信息引索与self.image_index引索相对应
self.roidb.append(entry)
#由于数据增强(添加了水平反转数据),且水平反转数据还是按照image_index的顺序,所以只需要执行image_insex=image_index*2
self._image_index = self._image_index * 2
我尝试在
boxes[:, 0] = widths[i] - oldx2
boxes[:, 2] = widths[i] - oldx1
的后面加上不同的值,使反转后的坐标不为负数。但是试了好多数还是出现最开始的报错。没有办法了,希望有大佬解救!
参考大佬博客:
https://blog.csdn.net/hongxingabc/article/details/79048531
https://blog.csdn.net/l297969586/article/details/78026206
https://blog.csdn.net/ksws0292756/article/details/80702704
https://blog.csdn.net/weixin_37203756/article/details/79939093