zoukankan      html  css  js  c++  java
  • py-faster-rcnn

    踩坑:

    1. 服务器上训练:

    sh ./experiments/scripts/faster_rcnn_end2end.sh

    会各种报错

    有说是因为#!/bin/bash的问题,改过,不行。

    改成如下ok

    sudo ./experiments/scripts/faster_rcnn_end2end.sh

    2. __C.DEDUP_BOXES = 1./16. 取决于网络结构,就是之前pool和stride的大小。关于这个参数,大神git上有回复#34。

    3. KeyError: 'max_overlaps' 删除两个cache目录下的.pkl #501

    4. 编译好的py-faster-rcnn,编译好以后测试demo.py跑起来了,复制一份打算同时训练,发生了hdf5错误,在复制的faster rcnn里make clean, 重新make就没问题了。

    5.

     File "pascal_voc.py", line 269, in _write_voc_results_file
        with open(filename, 'w+') as f:
    IOError: [Errno 2] No such file or directory: '~/wkspace/caffe_wk/branch_faster_rcnn/data/VOCdevkit2007/results/VOC2007/Main/comp4_a4f85e93-deaa-4519-ae71-969f285f439e_det_test_heart.txt'

    报错是因为VOCdevkit2007这个目录下没有results/VOC2007/Main/

    6. 用VGG finetune自己的模型,首先是类别不一样的话不能用默认的VGG.v2.caffemodel,那个带了后面的21分类。用VGG_ILSVRC_16_layers.caffemodel  

    然后会报错:TypeError: slice indices must be integers or None or have an __index__ method,仍旧大神博客解决#480,用:

    After line 126,
    start=int(start)
    end=int(end)
    After line 166,
    fg_rois_per_this_image=int(fg_rois_per_this_image)

     7. 迭代到一万多报错:keep = np.where((ws >= min_size) & (hs >= min_size))[0],修改lr=0.0001

    8. assert(boxes[:,2]>=boxes[:,0].all()

    去掉-1操作,躲过了框在边界上的坑,没有躲过标注标反的坑,最后修改lib/dataset/pascal_voc.py如下:

    9. 

    9. 1 输入改小为144*256以后出现的问题,自己设计的网络第一次迭代就报了这个错误,训VGG16,迭代5万次后也出现这个问题。中间试过换Adam为SGD、删除data/cache,各种折腾未果,改为600,好了,锁定就是改小输入尺度的原因(前两天忙着搞别的,没顾上训练,忘记上次的配置了,这样很不好,按说应该每次只改动一处,就不需要定位问题。但这个比较特殊,因为之前在别的服务器上改过这个尺度当时训练没问题)

    看代码lib/rpn/anchor_target_layer.py:

    1 anchor_scales = layer_params.get('scales', (8, 16, 32))
    2 self._anchors = generate_anchors(scales=np.array(anchor_scales))

    这里会生成一个这样的anchor(尺寸映射回原图):

    #array([[ -83.,  -39.,  100.,   56.],
    #       [-175.,  -87.,  192.,  104.],
    #       [-359., -183.,  376.,  200.],
    #       [ -55.,  -55.,   72.,   72.],
    #       [-119., -119.,  136.,  136.],
    #       [-247., -247.,  264.,  264.],
    #       [ -35.,  -79.,   52.,   96.],
    #       [ -79., -167.,   96.,  184.],
    #       [-167., -343.,  184.,  360.]])

    猜测是因为输入尺寸改小了,anchors还是那么大,faster rcnn又设置在训练的时候超出边界的候选框一律不要,导致返回到原图上没有多少候选框了,最后导致overlaps空了

    修改第二行:

    self._anchors = generate_anchors(scales=np.array( scales=np.array([2,4,8]) ))
    或者:
    anchor_scales = layer_params.get( 'scales', (2, 4, 8) )
    self._anchors = generate_anchors(scales=np.array(anchor_scales)

    对应anchor如下,因为是在setup函数里,所以会在模型初始化的时候打印:

    同时修改lib/fast_rcnn/config.py里的RPN_PRE_NMS_TOP_N、RPN_POST_NMS_TOP_N。改小输入尺寸后stride16,提rpn的特征层只有9*16那么大,只能提到9*16*9=1296个anchor,再去掉超出边界的,就没有多少可用了,这里默认的还是1.2万,2千,明显不合理。边改边看代码,发现proposal layer.py也有相同操作:

    def setup(self, bottom, top):
            # parse the layer parameter string, which must be valid YAML
            layer_params = yaml.load(self.param_str_)
    
            self._feat_stride = layer_params['feat_stride']
            anchor_scales = layer_params.get( 'scales', (8, 16, 32) )

    这个笔记是良心分享

    9.2 stride设错会导致这个问题,开始训练的时候就会看到loss大于3、4,迭代到几千或一万次就报这个错误了

    10. 绘制loss曲线,去掉if line.find('Solving') != -1的判断,参考这里  frcnn专用,更详细的版本,备用

    11. 训练完AP全是0,通常是因为test.prototxt和train.prototxt不一致导致的,比如某一层的stride,train里面改成2,test里面还是4,导致最后特征图大小都不一样,画出来的框位置全错。

        这个问题是刚上手搞faster rcnn就遇到了,那时候一脸懵,以为模型训废了,直到看了大半代码,并且自己把模型拉到本地跑过一次,发现还能捡出来不少,中间迂回几次,基本可以锁定是这个原因。

    12. 一个端午假期回来,之前的命令全不能跑,ssd还可以训练,faster rcnn下的一切都崩溃,全是这个错误:

    syncedmem.cpp:78 Check failed: error == cudaSuccess (2 vs. 0) out of memory #5353

    重新caffe-fast-rcnn make过也不行,幸好没有重装驱动各种,参考这里,杀死两个占用gpu 0 的进程,test搞定,训练还是不行,事实证明还是显存不足的问题,batchsize从256改成64就可以训练了。

    13. 增加分类数量后原来的模型不能用来finetune了,一种方案是修改layer名字,但是涉及到pred_bbox,参考12,在py-faster-rcnn/tools目录下新建python文件

     1 # -*- coding: utf-8 -*-
     2 #!/usr/bin/env python
     4 # --------------------------------------------------------
     5 # 直接复制文件头部 9 # --------------------------------------------------------16 import _init_paths
    17 from fast_rcnn.config import cfg
    18 from fast_rcnn.test import im_detect
    19 from fast_rcnn.test import vis_detections
    20 from fast_rcnn.nms_wrapper import nms
    21 from utils.timer import Timer
    22 import matplotlib.pyplot as plt
    23 import numpy as np
    24 import scipy.io as sio
    25 import os, sys
    26 # Make sure that caffe is on the python path:
    27 caffe_root = './caffe-fast-rcnn/'
    28 os.chdir(caffe_root)
    29 sys.path.insert(0, os.path.join(caffe_root, 'python'))
    30 import caffe
    31 import cv2
    32 import argparse
    33 if __name__ == "__main__":
    34     caffe.set_mode_cpu
    35     net = caffe.Net("/Users/_/wkspace/caffe_space/detection/py-faster-rcnn/models/pascal_voc/_/faster_rcnn_end2end/deploy.prototxt",
    36                     "/Users/_/wkspace/caffe_space/detection/py-faster-rcnn/data/_.v2.caffemodel", 
    37                     caffe.TEST)
    38     #第一个卷基层的权值
    39     conv1_w = net.params['conv1_small'][0].data[0]
    40     #第一个卷基层的偏置值
    41     conv1_b = net.params['conv1_small'][1].data[0]
    42     #可以打印相应的参数和参数的维度等信息
    43     print conv1_w,'
    '
    44     print conv1_b,'
    '
    45     print conv1_w.size,conv1_b.size
    46     net.save('/Users/_/Desktop/out/rm_pred_box_layer.caffemodel')

    保存一个删除最后两层的caffemodel。诸多证据表明,faster rcnn里的pred_box层名字是不能随意修改的:

    14. 赶deadline一个工程复制了8份全线开工,ln -s ~/VOCdevkit VOCdevkit2007 共用同一段数据,这种情况下8个工程是共享trainval.txt和test.txt的,如果其中一个工程修改过trainval.txt,其他工程重新开始训练时候要删除工程目录下的data/cache和data/VOCdevkit2007/anotation_cache。

    15. 一个诡异的python问题,可能和faster rcnn无关,在tools目录下自己写了一个准确率测试脚本,加载model,累计计算loss求和,求均值:

    src/tcmalloc.cc:331] Attempt to free invalid pointer 0x7fcb4aa7e2e0
    [1]    74204 abort      python tools/mtcnnAccTest.py

    百度谷歌说啥的都有,最后发现abort的节点和读入图片数、图片大小有直接关系,于是注释掉脚本开头的import matplotlib.pyplot as plt这一句就好了。

    16. 测误检,手工加了一批测试集,name标为'__background__',报错如下:

    Evaluating detections
    VOC07 metric? Yes
    Traceback (most recent call last):
      File "./tools/test_net.py", line 90, in <module>
        test_net(net, imdb, max_per_image=args.max_per_image, vis=args.vis)
      File "/home/song/branch_faster_rcnn/tools/../lib/fast_rcnn/test.py", line 300, in test_net
        imdb.evaluate_detections(all_boxes, output_dir)
      File "/home/song/branch_faster_rcnn/tools/../lib/datasets/pascal_voc.py", line 344, in evaluate_detections
        self._do_python_eval(output_dir)
      File "/home/song/branch_faster_rcnn/tools/../lib/datasets/pascal_voc.py", line 307, in _do_python_eval
        use_07_metric=use_07_metric)
      File "/home/song/branch_faster_rcnn/tools/../lib/datasets/voc_eval.py", line 126, in voc_eval
        R = [obj for obj in recs[imagename] if obj['name'] == classname]
    KeyError: '20180626_dzf_shortV_1_00006_f183'

    解决方案: 删掉data/VOCdevkit2007/目录下的annotations_cache。

     17. test阶段,如果模型什么都检测不出来会这样:

    训练:

     1 ./experiments/scripts/faster_rcnn_end2end.sh
     2  tools/train_net..py
     3     args.cfg_file
     4     caffe.set_mode_gpu, set_gpuid
     5     lib/datasets/factory.py: get_imdb
    #实例化pascal_voc类,imdb = pascal_voc(trainval, 2007) --lib/datasets/pascal_voc.py
    6 lib/datasets/imdb.py: get_proposal_method 7 lib/fast_rcnn/train.py: get_training_roidb 8 lib/datasets/imdb.py: append_flipped_images 9 lib/roi_data_layer/roidb.py: prepare_roidb #至此,图片地址和信息保存到imdb里了 10 lib/fast_rcnn/config.py: get_output_dir #caffemodel输出目录 11 lib/fast_rcnn/train.py 12

        关于imdb参考python面向对象,从此可以通过imdb.gt_roidb()访问pascal_voc类方法

        imdb是pascal_voc类的一个实例,roidb是一个list

        imdb.append_flipped_images()是直接将水平翻转后的图append到roidb后面,所以水平翻转操作是对所有数据进行,该操作使训练数据翻倍。

        以上,全是初始化。

     pascal_voc.py:

    gt_roidb()
    selective_search_roidb()

    gt_roidb()中调用_load_pascal_annotation,会解析xml,返回如下内容:

    利用cPickle写入data/cache/voc_2007_trainval_gt_roidb.pkl,如果trainval.txt不变,下次就可以直接加载了,第一次会等在这里很久,以后加载就不会了。

    读写pkl用到了python cPickle:对任意类型的python对象进行序列化操作。所谓的序列化,我的粗浅的理解就是为了能够完整的保存并能够完全可逆的恢复

    实际的训练数据读入开始于lib/fast_rcnn/train.py:

    1 def train_net(solver_prototxt, roidb, output_dir, pretrained_model=None, max_iters=40000):
        sw = SolverWrapper(solver_prototxt, roidb, output_dir, pretrained_model=pretrained_model) :init
    2 self.solver.net.layers[0].set_roidb(roidb) 3 lib/roi_data_layer/layer.py : BlobFetcher 4 lib/roi_data_layer/lminibatch.py: blobs = get_minibatch(minibatch_db, self._num_classes) 5

    初始化在此,选择solver:SGD,读入事先训练好的caffemodel,加载roidb,其中第46行会掉roi_data_layer,返回图示blob:

    至此,带有roi的训练数据给到网络第一层。

    lib/fast_rcnn/train.py:

    sw.train_model(max_iters)

    调caffe里的solver开始迭代训练,step(1)表示forward+backward 1次。

    NET_FINAL=`grep -B 1 "done solving" ${LOG} | grep "Wrote snapshot" | awk '{print $4}'`

    这句话的详细解释见这里,就是把训练好的caffemodel完整路径读入NET_FINAL,下一步test_net.py参数--net ${NET_FINAL}会用到。

    细节:

    fast rcnn的roi pooling: 先把roi中的坐标映射到feature map上,映射规则比较简单,就是把各个坐标除以“输入图片与feature map的大小的比值”,得到了feature map上的box坐标后,使用Pooling得到输出。详解1 详解2

    知识点:

    由于ImageNet数以百万计带标签的训练集数据,使得如CaffeNet之类的预训练的模型具有非常强大的泛化能力,这些预训练的模型的中间层包含非常多一般性的视觉元素,我们只需要对他的后几层进行微调,在应用到我们的数据上,通常就可以得到非常好的结果。最重要的是,在目标任务上达到很高performance所需要的数据的量相对很少。 from: fine-tuning:利用已有模型训练其他数据集

    其他:

    来自这里,先存着,回头验证下,现在用的Adam, fixed lr=1e-05

  • 相关阅读:
    Install Java on Ubuntu server
    Java 空引用访问静态不会发生空指针异常
    Java 什么时候使用static
    Java 空指针异常
    java 方法的返回值
    python中直接复制,浅拷贝,深拷贝
    python 操作ppt转换为pdf
    数组排序
    qooxdoo框架环境搭建
    python 链表实现 双向链表和单向循环链表
  • 原文地址:https://www.cnblogs.com/zhengmeisong/p/9102059.html
Copyright © 2011-2022 走看看