• Faster-RCNN用于场景文字检测训练测试过程记录(转)


    [训练测试过程记录]Faster-RCNN用于场景文字检测

    原创 2017年11月06日 20:09:00
            <ul class="article_tags clearfix csdn-tracking-statistics tracking-click" data-mod="popu_377" style="display: none;">
                <li class="tit">标签:</li>
    
                <!--          [endarticletags]-->
            </ul>
            <ul class="right_bar">
                <li><button class="btn-noborder"><i class="icon iconfont icon-read"></i><span class="txt">609</span></button></li>
                <li class="edit" style="display: none;">
                    <a class="btn-noborder" href="https://mp.csdn.net/postedit/78457624">
                        <i class="icon iconfont icon-bianji"></i><span class="txt">编辑</span>
                    </a>
                </li>
                <li class="del" style="display: none;">
                    <a class="btn-noborder" onclick="javascript:deleteArticle(fileName);return false;">
                        <i class="icon iconfont icon-shanchu"></i><span class="txt">删除</span>
                    </a>
                </li>
            </ul>
        </div>
        <div id="article_content" class="article_content csdn-tracking-statistics tracking-click" data-mod="popu_519" data-dsm="post" style="overflow: hidden;">
                            <div class="htmledit_views">
    

    写在前面:github上面的Text-Detection-with-FRCN项目是基于py-faster-rcnn项目在场景文字识别领域的扩展。

    和py-faster-rcnn相比,该项目的主要改动为:将检测类别换成了背景和文字,并且更改了数据集。

    对于初学者而言,要实现一个自己的baseline,第一步可以尝试训练别人已经实现了的网络,看看整个的运行流程是怎么样的。那么,接下来,我就记录一下我自己在训练和测试过程中遇到的问题。大家在参考的时候可以参照Text-Detection-with-FRCN项目中的README.md文件。

    一.编译部分

    在编译caffe的时候,可能会遇到一些问题,这里,我来介绍一下我遇到的问题。

    1.Makefile.config.example文件修改问题

    切换到caffe目录:cd $Text-Detection-with-FRCN/py-faster-rcnn/caffe-fast-rcnn

    修改Makefile.config.example文件:

    (1)去掉USE_CUDNN := 1的注释

    # cuDNN acceleration switch (uncomment to build with cuDNN).
    USE_CUDNN := 1

    (2)去掉WITH_PYTHON_LAYER := 1的注释

    # Uncomment to support layers written in Python (will link against Python libs)
    WITH_PYTHON_LAYER := 1


    2.CUDNN版本问题

    在上一步中,修改了Makefile.config.example问题,再执行如下指令:

    cp Makefile.config.example Makefile.config

    make -16 && make pycaffe

    在make的过程中,可能出现由于CUDNN版本问题导致的错误:

    1. In file included from ./include/caffe/util/device_alternate.hpp:40:0,    
    2.                      from ./include/caffe/common.hpp:19,    
    3.                      from src/caffe/common.cpp:7:    
    4.     ./include/caffe/util/cudnn.hpp: In function ‘void caffe::cudnn::createPoolingDesc(cudnnPoolingStruct**, caffe::PoolingParameter_PoolMethod, cudnnPoolingMode_t*, int, int, int, int, int, int)’:    
    5.     ./include/caffe/util/cudnn.hpp:127:41: error: too few arguments to function ‘cudnnStatus_t cudnnSetPooling2dDescriptor(cudnnPoolingDescriptor_t, cudnnPoolingMode_t, cudnnNanPropagation_t, int, int, int, int, int, int)’    
    6.              pad_h, pad_w, stride_h, stride_w));    
    7.                                              ^    
    8.     ./include/caffe/util/cudnn.hpp:15:28: note: in definition of macro ‘CUDNN_CHECK’    
    9.          cudnnStatus_t status = condition;     
    10.                                 ^    
    11.     In file included from ./include/caffe/util/cudnn.hpp:5:0,    
    12.                      from ./include/caffe/util/device_alternate.hpp:40,    
    13.                      from ./include/caffe/common.hpp:19,    
    14.                      from src/caffe/common.cpp:7:    
    15.     /usr/local/cuda-7.5//include/cudnn.h:803:27: note: declared here    
    16.      cudnnStatus_t CUDNNWINAPI cudnnSetPooling2dDescriptor(    
    17.                                ^    
    18.     make: *** [.build_release/src/caffe/common.o] Error 1    

    这是由于当前版本的caffe的cudnn实现与系统所安装的cudnn的版本不一致引起的。

    解决办法:

    下载最新版的caffe

    1)将./include/caffe/util/cudnn.hpp换成最新版的caffe里的cudnn.hpp;

    2)将./include/caffe/layers里面,所有以cudnn开头的文件,都换成最新版的caffe里面相应的同名文件;

    3)将./src/caffe/layers里面,所有以cudnn开头的文件,都换成最新版的caffe里面相应的同名文件。

    tips:其他部分的以cudnn开头的文件,就不要动了。


    二.准备数据集

    在Text-Detection-with-FRCN项目的readme中,给出了coco-text数据集的制作方式。下面,就来具体说明。

    1.下载数据集

    切换目录:cd $Text-Detection-with-FRCN/datasets/script

    原指令为:./fetch_dataset.sh coco-text,可能会出现-bash: ./fetch_dataset.sh: Permission denied的错误。

    可先运行:chmod +x ./fetch_dataset.sh

    再运行: ./fetch_dataset.sh coco-text


    下载到的数据集包括:train2014.zip文件和COCO_Text.json,下面,需要将数据进行格式化,与原py-faster-rcnn中的pascal_voc的数据格式进行统一。


    2.数据格式化

    (1)pascal_voc数据集的格式为:

    --Annotations

    --*.xml

    --JPEGImages

    --*.jpg

    --ImageSets

    --Main

    ......

    图像文件夹(JPEGImages):例如2008_000200.jpg

    标记文件夹(Annotations):例如2008_000200.xml

    <annotation>

    <folder>VOC2012</folder>

    <filename>2008_000200.jpg</filename>

    <source>

    <database>TheVOC2008 Database</database>

    <annotation>PASCALVOC2008</annotation>

    <image>flickr</image>

    </source>

    <size>

    <width>500</width>

    <height>375</height>

    <depth>3</depth>

    </size>

    <segmented>0</segmented>

    <object>

    <name>person</name>

    <bndbox>

    <xmin>119</xmin>

    <ymin>76</ymin>

    <xmax>184</xmax>

    <ymax>311</ymax>

    </bndbox>

    </object>

    ......


    区分训练样本与测试样本(ImageSets):

    test.txt为例:

    2008_000001

    2008_000004

    2008_000005

    2008_000006


    (2)coco-text的格式为:

    图片集:Train2014.zip:COCO_train2014_000000378466.jpg

    文件标记:

    COCO_Text.json

    {"imgs":

    {"378466":{"width": 612, "file_name":"COCO_train2014_000000378466.jpg", "set":"train", "id": 378466, "height": 612},

    "370250":{"width": 427, "file_name":"COCO_train2014_000000370250.jpg", "set": "test","id": 370250, "height": 640},

    "36606":{"width": 640, "file_name":"COCO_train2014_000000036606.jpg", "set": "val","id": 36606, "height": 480}


    (3)将coco-text的数据集格式转换为pascal_voc的格式


    切换目录:cd $Text-Detection-with-FRCN/datasets/script

    运行指令:./format_annotation.py --dataset coco-text


    format_annotation.py中:

    1.format_coco_text函数,是利用coco-text.json中的信息,生成类似于pascal_voc的ImageSets文件夹中的信息。

    2.os.system('./ann2voc2007.sh ' + args.dataset),是调用相同文件夹下面的ann2voc2007.m文件,来生成类似于pascal_voc的Annotations文件夹中的信息。


    如果不想花时间安装matlib,可以将ann2voc2007.m改写为python文件,效果是一样的。


    改写后的代码如下:(具体原理可参考:利用python生成xml文件

    1. #coding:utf-8  
    2. from PIL import Image  
    3. from xml.dom.minidom import Document  
    4. import os  
    5.   
    6. def main():  
    7.     imgpath = 'JPEGImages/'  
    8.     txtpath = 'images.annotations'  
    9.     xmlpath_new = 'Annotations/'  
    10.     coco = {}  
    11.       
    12.     # 得到图像的标注信息  
    13.     file_object = open(txtpath,'rU')  
    14.     try:   
    15.         for line in file_object:  
    16.             line = line.rstrip(' ')  
    17.             strs = line.split(' ')  
    18.             print strs[0]  
    19.             foldername = 'VOC2007'  
    20.               
    21.             # 用xml替换jpg,得到同名文件  
    22.             xmlname = strs[0].replace('.jpg','.xml')  
    23.             info = Image.open(imgpath + strs[0])  
    24.             # read image size  
    25.             (width,height) = info.size  
    26.             strs[2] = max(int(strs[2]), 1)  
    27.             strs[3] = max(int(strs[3]), 1)  
    28.             strs[4] = min(int(strs[4]), width);  
    29.             strs[5] = min(int(strs[5]), height);  
    30.   
    31.             # 过滤异常  
    32.             if strs[2] >= strs[4or strs[3] >= strs[5or strs[2] <=0 or strs[3] <= 0 or strs[4] > width or strs[5] > height:  
    33.                 continue  
    34.               
    35.             if os.path.exists(imgpath + strs[0]):  
    36.                 if xmlname in coco:  
    37.                     Createnode = coco[xmlname]  
    38.                     object_node = Createnode.createElement('object')  
    39.                       
    40.                     Root = Createnode.getElementsByTagName('annotation')[0]  
    41.                     Root.appendChild(object_node)  
    42.                       
    43.                     node=Createnode.createElement('name')  
    44.                     node.appendChild(Createnode.createTextNode(strs[1]))  
    45.                     object_node.appendChild(node)  
    46.                       
    47.                     node=Createnode.createElement('pose')  
    48.                     node.appendChild(Createnode.createTextNode('Unspecified'))  
    49.                     object_node.appendChild(node)  
    50.                       
    51.                     node=Createnode.createElement('truncated')  
    52.                     node.appendChild(Createnode.createTextNode('0'))  
    53.                     object_node.appendChild(node)  
    54.                       
    55.                     node=Createnode.createElement('difficult')  
    56.                     node.appendChild(Createnode.createTextNode('0'))  
    57.                     object_node.appendChild(node)  
    58.                       
    59.                     bndbox_node=Createnode.createElement('bndbox')  
    60.                     object_node.appendChild(bndbox_node)  
    61.                       
    62.                     node=Createnode.createElement('xmin')  
    63.                     node.appendChild(Createnode.createTextNode(str(strs[2])))  
    64.                     bndbox_node.appendChild(node)  
    65.                       
    66.                     node=Createnode.createElement('ymin')  
    67.                     node.appendChild(Createnode.createTextNode(str(strs[3])))  
    68.                     bndbox_node.appendChild(node)  
    69.                       
    70.                     node=Createnode.createElement('xmax')  
    71.                     node.appendChild(Createnode.createTextNode(str(strs[4])))  
    72.                     bndbox_node.appendChild(node)  
    73.                       
    74.                     node=Createnode.createElement('ymax')  
    75.                     node.appendChild(Createnode.createTextNode(str(strs[5])))  
    76.                     bndbox_node.appendChild(node)  
    77.                 else:  
    78.                     Createnode=Document()  #创建DOM文档对象  
    79.                       
    80.                     Root=Createnode.createElement('annotation'#创建根元素  
    81.                     Createnode.appendChild(Root)  
    82.                       
    83.                     # folder  
    84.                     folder=Createnode.createElement('folder')  
    85.                     folder.appendChild(Createnode.createTextNode(foldername))  
    86.                     Root.appendChild(folder)  
    87.                       
    88.                     # filename  
    89.                     filename = Createnode.createElement('filename')  
    90.                     filename.appendChild(Createnode.createTextNode(strs[0]))  
    91.                     Root.appendChild(filename)  
    92.                       
    93.                     # source  
    94.                     source_node = Createnode.createElement('source')  
    95.                     Root.appendChild(source_node)  
    96.                       
    97.                     node = Createnode.createElement('database')  
    98.                     node.appendChild(Createnode.createTextNode('MS COCO-Text'))  
    99.                     source_node.appendChild(node)  
    100.                       
    101.                     node = Createnode.createElement('annotation')  
    102.                     node.appendChild(Createnode.createTextNode('MS COCO-Text 2014'))  
    103.                     source_node.appendChild(node)  
    104.               
    105.                     node=Createnode.createElement('image')  
    106.                     node.appendChild(Createnode.createTextNode('NULL'))  
    107.                     source_node.appendChild(node)  
    108.               
    109.                     node=Createnode.createElement('flickrid');  
    110.                     node.appendChild(Createnode.createTextNode('NULL'));  
    111.                     source_node.appendChild(node);  
    112.                       
    113.                     # owner  
    114.                     owner_node=Createnode.createElement('owner')  
    115.                     Root.appendChild(owner_node)  
    116.                       
    117.                     node=Createnode.createElement('flickrid')  
    118.                     node.appendChild(Createnode.createTextNode('NULL'))  
    119.                     owner_node.appendChild(node)  
    120.                       
    121.                     node=Createnode.createElement('name')  
    122.                     node.appendChild(Createnode.createTextNode('ligen'))  
    123.                     owner_node.appendChild(node)  
    124.                       
    125.                     # size  
    126.                     size_node=Createnode.createElement('size')  
    127.                     Root.appendChild(size_node)  
    128.                       
    129.                     node=Createnode.createElement('width')  
    130.                     node.appendChild(Createnode.createTextNode(str(width)))  
    131.                     size_node.appendChild(node)  
    132.                       
    133.                     node=Createnode.createElement('height');  
    134.                     node.appendChild(Createnode.createTextNode(str(height)))  
    135.                     size_node.appendChild(node)  
    136.                       
    137.                     node=Createnode.createElement('depth')  
    138.                     node.appendChild(Createnode.createTextNode('3'))  
    139.                     size_node.appendChild(node)  
    140.                       
    141.                     # segmented  
    142.                     node=Createnode.createElement('segmented')  
    143.                     node.appendChild(Createnode.createTextNode('0'))  
    144.                     Root.appendChild(node)  
    145.                       
    146.                     # object  
    147.                     object_node=Createnode.createElement('object')  
    148.                     Root.appendChild(object_node)  
    149.                       
    150.                     node=Createnode.createElement('name')  
    151.                     node.appendChild(Createnode.createTextNode(strs[1]))  
    152.                     object_node.appendChild(node)  
    153.                       
    154.                     node=Createnode.createElement('pose')  
    155.                     node.appendChild(Createnode.createTextNode('Unspecified'))  
    156.                     object_node.appendChild(node)  
    157.                       
    158.                     node=Createnode.createElement('truncated')  
    159.                     node.appendChild(Createnode.createTextNode('0'))  
    160.                     object_node.appendChild(node)  
    161.                       
    162.                     node=Createnode.createElement('difficult')  
    163.                     node.appendChild(Createnode.createTextNode('0'))  
    164.                     object_node.appendChild(node)  
    165.                       
    166.                     bndbox_node=Createnode.createElement('bndbox')  
    167.                     object_node.appendChild(bndbox_node)  
    168.                       
    169.                     node=Createnode.createElement('xmin')  
    170.                     node.appendChild(Createnode.createTextNode(str(strs[2])))  
    171.                     bndbox_node.appendChild(node)  
    172.                       
    173.                     node=Createnode.createElement('ymin')  
    174.                     node.appendChild(Createnode.createTextNode(str(strs[3])))  
    175.                     bndbox_node.appendChild(node)  
    176.                       
    177.                     node=Createnode.createElement('xmax')  
    178.                     node.appendChild(Createnode.createTextNode(str(strs[4])))  
    179.                     bndbox_node.appendChild(node)  
    180.                       
    181.                     node=Createnode.createElement('ymax')  
    182.                     node.appendChild(Createnode.createTextNode(str(strs[5])))  
    183.                     bndbox_node.appendChild(node)  
    184.                       
    185.                     coco[xmlname] = Createnode  
    186.               
    187.     finally:  
    188.          file_object.close()  
    189.     print 'begin load xml...'  
    190.     for key in coco:  
    191.         print key  
    192.         f = open(xmlpath_new + key,'w')  
    193.         f.write(coco[key].toprettyxml(indent = ' '))  
    194.         f.close()  
    195.   
    196. if __name__ == "__main__":  
    197.     main()  


    最后,再运行rm_headline.sh。就得到我们所需要的数据集。

    我得到的文件目录如下:


    在Annotations的目录下,


    在JPEGImages的目录下,


    在ImageSets的目录下,


    以train.txt为例,包含的内容为:

    COCO_train2014_000000351622
    COCO_train2014_000000058397
    COCO_train2014_000000282380
    COCO_train2014_000000223830
    ......

    均为文件名


    3.创建软链接

    软链接就是:ln -s  源文件 目标文件

    在代码中给出的数据集的目录为:train_data

    因此,需要将上面得到的coco-text的目录链接到train_data上。

    在github的readme中,给出的软链接操作为:

    # link your data folder to train_data
    cd $Text-Detection-with-FRCN/datasets/
    ln -s train_data coco-text    # $YOUR_DATA
    但是在我实际操作的时候,是需要:

    ln -s coco-text train_data 的。


    三.下载预训练模型

    首先,下载在imagenet上面预先训练好的模型。

    # finetune on this model, you can also use one model you train before
    cd $Text-Detection-with-FRCN/py-faster-rcnn
    ./data/scripts/fetch_imagenet_models.sh
    # download it takes long!
    可能由于这个项目clone “py-faster-rcnn” 的时间比较早,这里面/data/scripts文件夹下面,fetch_imagenet_models.sh中的下载url已经不能用了。该文件夹下面的其他.sh文件中的url应该也都失效了。

    新的py-faster-rcnn中已经对此做了更正。fetch_imagenet_models.sh中的url可改为:

    1. ......  
    2. 6 FILE=imagenet_models.tgz  
    3. 7 URL=https://dl.dropbox.com/s/gstw7122padlf0l/imagenet_models.tgz?dl=0  
    4. 8 CHECKSUM=ed34ca912d6782edfb673a8c3a0bda6d  
    5. .....  

    具体更改位置为第8行。

    注意:下载需要翻墙。


    三.开始训练

    切换目录:

    cd $Text-Detection-with-FRCN/py-faster-rcnn/

    运行指令:

    ./experiments/scripts/faster_rcnn_end2end.sh 0 VGG16 pascal_voc

    需要注意的是:在运行指令的时候,需要切换到指定的目录。

    运行的时候,可能会保错:

    1)TypeError: 'numpy.float64' object cannot be interpreted as an index


    2)TypeError: slice indices must be integers or None or have an index method

    这两个问题的出现,都是由于Numpy的版本问题。在numpy 1.12.0中,不支持float index。类似于x[1.0, 3.0],会被看作无效。

    解决这个问题,有如下可能的解决办法:

    1.对numpy进行降级

    sudo pip install -U numpy==1.11.0

    但是这种做法,可能会引入新的错误:

    ImportError: numpy.core.multiarray failed to import 

    解决这个问题是要升级numpy ,于是又升回去:pip install -U numpy 

    所以,只能逐个将float类型转换为int类型

    2.目前发现的几处需要进行修改的地方:

    1.添加astype(np.int)

    lib/roi_data_layer/minibatch.py line 26:将fg_rois_per_image = np.round(cfg.TRAIN.FG_FRACTION * rois_per_image)

    改为:fg_rois_per_image = np.round(cfg.TRAIN.FG_FRACTION * rois_per_image).astype(np.int)

    同理,其他需要在末尾添加.astype(np.int) 的地方:

    lib/datasets/ds_utils.py line 12 : hashes = np.round(boxes * scale).dot(v)

    lib/fast_rcnn/test.py line 129 : hashes = np.round(blobs['rois'] * cfg.DEDUP_BOXES).dot(v)

    lib/rpn/proposal_target_layer.py line 60 : fg_rois_per_image = np.round(cfg.TRAIN.FG_FRACTION * rois_per_image)

    2.强制转化为int类型

    lib/roi_data_layer/minibatch.py line173:将cls = clss[ind] 改为:cls = int(clss[ind])

    lib/rpn/proposal_target_layer.py line 124:将cls = clss[ind] 改为:cls = int(clss[ind])

    四.训练模型

    当解决了上面所有的问题,我们就可以开始训练了。

    具体训练过程:

    1.创建输入层

    layer_factory.hpp:77 Creatinglayer input-data

    net.cpp:106 CreatingLayer input-data

    net.cpp:411 input-data-> data

    net.cpp:411 input-data-> im_info

    net.cpp:411 input-data-> gt_boxes

    net.cpp:150 Settingup input-data

    net.cpp:157 Topshape: 1 3 600 1000 (1800000)

    net.cpp:157 Topshape: 1 3 (3)

    net.cpp:157 Topshape: 1 4 (4)

    net.cpp:165 Memoryrequired for data: 7200028

    ............


    2.创建卷积层

    layer_factory.hpp:77 Creatinglayer conv1_1

    net.cpp:106 CreatingLayer conv1_1

    net.cpp:454 conv1_1<- data_input-data_0_split_0

    net.cpp:411 conv1_1-> conv1_1

    net.cpp:150 Settingup conv1_1

    net.cpp:157 Topshape: 1 64 600 1000 (38400000)

    net.cpp:165 Memoryrequired for data: 175200084

    ............


    3.创建激活层

    layer_factory.hpp:77 Creatinglayer relu1_1

    net.cpp:106 CreatingLayer relu1_1

    net.cpp:454 relu1_1<- conv1_1

    net.cpp:397 relu1_1-> conv1_1 (in-place)

    net.cpp:150 Settingup relu1_1

    net.cpp:157 Topshape: 1 64 600 1000 (38400000)

    net.cpp:165 Memoryrequired for data: 328800084

    ............


    判断是否需要反向计算(back forward)

    部分需要反向计算:

    net.cpp:226 loss_bboxneeds backward computation.

    loss_clsneeds backward computation.

    bbox_predneeds backward computation.

    cls_scoreneeds backward computation.

    fc7_drop7_0_splitneeds backward computation.

    ............


    部分不需要反向计算:

    net.cpp:228pool2does not need backward computation.

    relu2_2does not need backward computation.

    conv2_2does not need backward computation.

    relu2_1does not need backward computation.

    conv2_1does not need backward computation.

    input-datadoes not need backward computation.

    ............


    整个网络初始化完毕:

    net.cpp:270 Thisnetwork produces output loss_bbox

    Thisnetwork produces output loss_cls

    Thisnetwork produces output rpn_cls_loss

    Thisnetwork produces output rpn_loss_bbox

    Networkinitialization done.

    solver.cpp:60 Solverscaffolding done.


    开始迭代,输出结果:

    solver.cpp:229 Iteration0, loss = 1.98441

    solver.cpp:245

    Trainnet output #0: loss_bbox = 0.00188451 (* 1 = 0.00188451 loss)

    Trainnet output #1: loss_cls = 0.484446 (* 1 = 0.484446 loss)

    Trainnet output #2: rpn_cls_loss = 0.766564 (* 1 = 0.766564 loss)

    Trainnet output #3: rpn_loss_bbox = 0.484638 (* 1 = 0.484638 loss)

    sgd_solver.cpp:106Iteration0, lr = 0.001


    solver.cpp:229 Iteration20, loss = 1.58353

    solver.cpp:245

    Trainnet output #0: loss_bbox = 0.00184912 (* 1 = 0.00184912 loss)

    Trainnet output #1: loss_cls = 0.213403 (* 1 = 0.213403 loss)

    Trainnet output #2: rpn_cls_loss = 0.444577 (* 1 = 0.444577 loss)

    Trainnet output #3: rpn_loss_bbox = 0.818097 (* 1 = 0.818097 loss)

    sgd_solver.cpp:106:Iteration20, lr = 0.001


    .......


    solver.cpp:229 Iteration69980, loss =0.374131

    solver.cpp:245

    Trainnet output #0: loss_bbox =0.00462239 (* 1 =0.00462239 loss)

    Trainnet output #1: loss_cls =0.00527413 (* 1 =0.00527413 loss)

    Trainnet output #2: rpn_cls_loss =0.0607663 (* 1 =0.0607663 loss)

    Trainnet output #3: rpn_loss_bbox =0.139714 (* 1 =0.139714 loss)

    sgd_solver.cpp:106:Iteration69980, lr = 0.001



    real 681m44.284s
    user 565m0.152s
    sys 115m29.578s


    生成的模型

    保存在:

    /Text-Detection-with-FRCN/py-faster-rcnn/output/faster_rcnn_end2end/voc_2007_trainval文件夹中。

    vgg16_faster_rcnn_iter_*.caffemodel中,其中*为迭代次数

    每迭代10000次,生成一个模型。迭代了70000次,共生成了7个模型。


    五.测试模型

    实际上,在./experiments/scripts/faster_rcnn_end2end.sh 中,训练完毕后会对模型进行测试。

    那么,怎样单独执行测试呢?

    切换目录:

    cd $Text-Detection-with-FRCN/py-faster-rcnn/

    运行指令:

    tools/test_net.py --gpu 0

     --def models/coco_text/VGG16/faster_rcnn_end2end/test.prototxt

    --netoutput/faster_rcnn_end2end/voc_2007_trainval/vgg16_faster_rcnn_iter_70000.caffemodel

    --imdb voc_2007_test

    --cfg experiments/cfgs/faster_rcnn_end2end.yml


    1.运行可能出现的错误:

    File "/Text-Detection-with-FRCN/py-faster-rcnn/tools/../lib/datasets/voc_eval.py", line 23, in parse_rec
        obj_struct['bbox'] = [int(bbox.find('xmin').text),
    ValueError: invalid literal for int() with base 10: '391.0'

    解决方案:改为:

    obj_struct['bbox'] = [int(float(bbox.find('xmin').text)),
                                  int(float(bbox.find('ymin').text)),
                                  int(float(bbox.find('xmax').text)),
                                  int(float(bbox.find('ymax').text))]


    2.测试运行结果:

    对于vgg16_faster_rcnn_iter_70000.caffemodel:

    AP for text = 0.3422
    Mean AP = 0.3422
    ~~~~~~~~
    Results:
    0.342
    0.342
    ~~~~~~~~


    对于github中已经训练好的vgg16_faster_rcnn_fine_tune_on_coco.caffemodel

    AP for text = 0.1013
    Mean AP = 0.1013
    ~~~~~~~~
    Results:
    0.101
    0.101
    ~~~~~~~~

    3.运行demo

    在/Text-Detection-with-FRCN/script目录下,有text_detect_demo.sh文件:

    ./py-faster-rcnn/tools/text_detect_demo.py
    --gpu 0
    --net models/deploy.prototxt
    --model models/vgg16_faster_rcnn_fine_tune_on_coco.caffemodel
    --dataset datasets/test


    通过修改其中的model,来指定模型。

    运行demo得到的结果:

    左边:vgg16_faster_rcnn_iter_70000.caffemodel的测试结果,右边:github中已经训练好的vgg16_faster_rcnn_fine_tune_on_coco.caffemodel的测试结果。





  • 相关阅读:
    saltstack之(九)配置管理源码部署Nginx
    saltstack之(八)配置管理部署LAMP
    saltstack之(七)配置管理系统初始化init
    saltstack之(六)配置管理state
    saltstack之(五)数据系统Grains和Pillar
    Visual Studio 2010 如何改用 Beyond Compare 作为 TFS 的比较工具
    C++名人的网站 转
    使用MAP文件快速定位程序崩溃代码行 (转)
    Mybatis自动生成实体类,映射文件,dao
    MinGW安装教程( MinGW
  • 原文地址:https://www.cnblogs.com/inception6-lxc/p/8944963.html
Copyright © 2020-2023  润新知