faster-rcnn代码详解(3)

lib/faste_rcnn/config.py

# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------

"""Fast R-CNN config system.

This file specifies default config options for Fast R-CNN. You should not
change values in this file. Instead, you should write a config file (in yaml)
and use cfg_from_file(yaml_file) to load it and override the default options.

Most tools in $ROOT/tools take a --cfg option to specify an override file.
    - See tools/{train,test}_net.py for example code that uses cfg_from_file()
    - See experiments/cfgs/*.yml for example YAML config override files
"""

import os
import os.path as osp
import numpy as np
# `pip install easydict` if you don't have it
from easydict import EasyDict as edict #easydict的作用:可以使得以属性的方式去访问字典的值

__C = edict()
# Consumers can get config by:
#   from fast_rcnn_config import cfg
#在其他文件使用config,通过from fast_rcnn_config import cfg调用
cfg = __C

#
# Training options
#训练选项

__C.TRAIN = edict()

# Scales to use during training (can list multiple scales)
# Each scale is the pixel size of an image's shortest side
# 最短边scales300
__C.TRAIN.SCALES = (300,)

# Max pixel size of the longest side of a scaled input images
#输入图像缩放的最长边为330
__C.TRAIN.MAX_SIZE = 330

# Images to use per minibatch
# 一个minibatch包含两张图片

__C.TRAIN.IMS_PER_BATCH = 2

# Minibatch size (number of regions of interest [ROIs])
# minibatch大小(感兴趣区域的数量[ROI的数量])
__C.TRAIN.BATCH_SIZE = 128

# Fraction of minibatch that is labeled foreground (i.e. class > 0)
# minibatch中前景样本所占的比例(即类>0)
__C.TRAIN.FG_FRACTION = 0.25

# Overlap threshold for a ROI to be considered foreground (if >= FG_THRESH)
# 与前景的重叠率大于0.5认为该ROI为前景样本(如果> = FGZ-THRESH)
__C.TRAIN.FG_THRESH = 0.5

# Overlap threshold for a ROI to be considered background (class = 0 if
# overlap in [LO, HI))
# ROI与前景的重叠阈值在[0.1,0.5]之间认为该ROI是背景样本
__C.TRAIN.BG_THRESH_HI = 0.5
__C.TRAIN.BG_THRESH_LO = 0.1

# Use horizontally-flipped images during training?
# 训练时使用水平翻转,增加数据量
__C.TRAIN.USE_FLIPPED = True

# Train bounding-box regressors
# 训练bb(包围框)回归器
__C.TRAIN.BBOX_REG = True

# Overlap required between a ROI and ground-truth box in order for that ROI to
# be used as a bounding-box regression training example
# bbox阈值,ROI与ground-truth的重叠率符合要求,这个ROI作为一个bb(包围框)回归的训练例子
__C.TRAIN.BBOX_THRESH = 0.5

# Iterations between snapshots
# 每迭代1000次产生一次snapshot
__C.TRAIN.SNAPSHOT_ITERS = 10000

# solver.prototxt specifies the snapshot path prefix, this adds an optional
# infix to yield the path: <prefix>[_<infix>]_iters_XYZ.caffemodel
# 为产生的snapshot文件名称添加一个可选的中缀(插入词). solver.prototxt指定了snapshot名称的前缀
__C.TRAIN.SNAPSHOT_INFIX = ''

# Use a prefetch thread in roi_data_layer.layer
# So far I haven't found this useful; likely more engineering work is required
# 在roi_data_layer.layer使用预取线程,作者认为不太有效,因此设为False
__C.TRAIN.USE_PREFETCH = False

# Normalize the targets (subtract empirical mean, divide by empirical stddev)
#  归一化目标BBOX_NORMALIZE_TARGETS,减去经验均值,除以标准差
__C.TRAIN.BBOX_NORMALIZE_TARGETS = True
# Deprecated (inside weights)
# 弃用
__C.TRAIN.BBOX_INSIDE_WEIGHTS = (1.0, 1.0, 1.0, 1.0)
# Normalize the targets using "precomputed" (or made up) means and stdevs
# (BBOX_NORMALIZE_TARGETS must also be True)
# 在BBOX_NORMALIZE_TARGETS为True时,BBOX_NORMALIZE_TARGETS也必须是true,归一化targets,使用经验均值和方差
__C.TRAIN.BBOX_NORMALIZE_TARGETS_PRECOMPUTED = False
__C.TRAIN.BBOX_NORMALIZE_MEANS = (0.0, 0.0, 0.0, 0.0)#均值
__C.TRAIN.BBOX_NORMALIZE_STDS = (0.1, 0.1, 0.2, 0.2)#方差

# Train using these proposals
# 使用'selective_search'的proposal训练!注意该文件来自fast rcnn,下文提到RPN
__C.TRAIN.PROPOSAL_METHOD = 'selective_search'

# Make minibatches from images that have similar aspect ratios (i.e. both
# tall and thin or both short and wide) in order to avoid wasting computation
# on zero-padding.
# minibatch的两个图片应该有相似的宽高比,以避免冗余的zero-padding计算
__C.TRAIN.ASPECT_GROUPING = True

# Use RPN to detect objects
#使用RPN检测目标
__C.TRAIN.HAS_RPN = False
# IOU >= thresh: positive example
# RPN正样本阈值IOU>=0.7是正样本
__C.TRAIN.RPN_POSITIVE_OVERLAP = 0.7
# IOU < thresh: negative example
# RPN负样本阈值IOU<0.3是负样本

__C.TRAIN.RPN_NEGATIVE_OVERLAP = 0.3
# If an anchor statisfied by positive and negative conditions set to negative
# 如果一个anchor同时满足正负样本,设置为负样本

__C.TRAIN.RPN_CLOBBER_POSITIVES = False
# Max number of foreground examples
# 前景的最大样本比例
__C.TRAIN.RPN_FG_FRACTION = 0.5
# Total number of examples
# batch size最大大小
__C.TRAIN.RPN_BATCHSIZE = 256
# NMS threshold used on RPN proposals
# 非极大值抑制的阈值
__C.TRAIN.RPN_NMS_THRESH = 0.7
# Number of top scoring boxes to keep before apply NMS to RPN proposals
# 在对RPN proposals应用NMS之前保留的top scoring的box数量
__C.TRAIN.RPN_PRE_NMS_TOP_N = 12000
# Number of top scoring boxes to keep after applying NMS to RPN proposals
#  在对RPN proposals应用NMS之后保留的top scoring的box数量

__C.TRAIN.RPN_POST_NMS_TOP_N = 2000
# Proposal height and width both need to be greater than RPN_MIN_SIZE (at orig image scale)
# proposal的高和宽都应该大于RPN_MIN_SIZE,否则,映射到conv5上不足一个像素点
__C.TRAIN.RPN_MIN_SIZE = 16
# Deprecated (outside weights)
__C.TRAIN.RPN_BBOX_INSIDE_WEIGHTS = (1.0, 1.0, 1.0, 1.0)
# Give the positive RPN examples weight of p * 1 / {num positives}
# and give negatives a weight of (1 - p)
# Set to -1.0 to use uniform example weighting
# 这里正负样本使用相同权重
__C.TRAIN.RPN_POSITIVE_WEIGHT = -1.0


#
# Testing options
# 测试选项
#

__C.TEST = edict()

# Scales to use during testing (can list multiple scales)
# Each scale is the pixel size of an image's shortest side
# 最短边scales300

__C.TEST.SCALES = (300,)

# Max pixel size of the longest side of a scaled input image
#输入图像缩放的最长边为330

__C.TEST.MAX_SIZE = 330

# Overlap threshold used for non-maximum suppression (suppress boxes with
# IoU >= this threshold)
#重叠率大于重叠阈值(0.3),使用非极大值抑制
__C.TEST.NMS = 0.3

# Experimental: treat the (K+1) units in the cls_score layer as linear
# predictors (trained, eg, with one-vs-rest SVMs).
#分类时是否使用SVM,这里是否
__C.TEST.SVM = False

# Test using bounding-box regressors
# 测试时使用bb回归器
__C.TEST.BBOX_REG = True

# Propose boxes
# 不使用RPN生成proposal
__C.TEST.HAS_RPN = False

# Test using these proposals
# 测试时使用selective_search生成proposal
__C.TEST.PROPOSAL_METHOD = 'selective_search'

## NMS threshold used on RPN proposals
#测试时在RPN使用NMS的阈值
__C.TEST.RPN_NMS_THRESH = 0.7
## Number of top scoring boxes to keep before apply NMS to RPN proposals
# 测试时 在对RPN proposals应用NMS之前保留的top scoring的box数量

__C.TEST.RPN_PRE_NMS_TOP_N = 6000
## Number of top scoring boxes to keep after applying NMS to RPN proposals
#  测试时在对RPN proposals应用NMS之后保留的top scoring的box数量

__C.TEST.RPN_POST_NMS_TOP_N = 300
# Proposal height and width both need to be greater than RPN_MIN_SIZE (at orig image scale)
# proposal的高和宽都应该大于RPN_MIN_SIZE,否则,映射到conv5上不足一个像素点

__C.TEST.RPN_MIN_SIZE = 16


#
# MISC
#

# The mapping from image coordinates to feature map coordinates might cause
# 从原图到feature map的坐标映射,可能会造成在原图上不同的box到了feature map坐标系上变得相同了
# some boxes that are distinct in image space to become identical in feature
# coordinates. If DEDUP_BOXES > 0, then DEDUP_BOXES is used as the scale factor
# for identifying duplicate boxes.
# 1/16 is correct for {Alex,Caffe}Net, VGG_CNN_M_1024, and VGG16
#缩放因子
__C.DEDUP_BOXES = 1./16.

# Pixel mean values (BGR order) as a (1, 1, 3) array
# We use the same pixel mean for all networks even though it's not exactly what
# they were trained with
# 所有network所用的像素均值设为相同
__C.PIXEL_MEANS = np.array([[[102.9801, 115.9465, 122.7717]]])

# For reproducibility可重复性
__C.RNG_SEED = 3

# A small number that's used many times
# 极小的数
__C.EPS = 1e-14

# Root directory of project
# 项目根路径 返回path规范化的绝对路径
__C.ROOT_DIR = osp.abspath(osp.join(osp.dirname(__file__), '..', '..'))

# Data directory
# 数据路径
__C.DATA_DIR = osp.abspath(osp.join(__C.ROOT_DIR, 'data'))

# Model directory
# 模型路径
__C.MODELS_DIR = osp.abspath(osp.join(__C.ROOT_DIR, 'models', 'pascal_voc'))

# Name (or path to) the matlab executable
# MATLAB可执行文件的名称(或路径)
__C.MATLAB = 'matlab'

# Place outputs under an experiments directory
# 输出在experiments路径下 默认路径
__C.EXP_DIR = 'default'

# Use GPU implementation of non-maximum suppression
# 用GPU实施非极大值抑制抑制
__C.USE_GPU_NMS = True

# Default GPU device id
#默认GPU id
__C.GPU_ID = 0


def get_output_dir(imdb, net=None):    #返回输出路径,在experiments路径下
    """Return the directory where experimental artifacts are placed.
    If the directory does not exist, it is created.

    A canonical path is built using the name from an imdb and a network
     使用IMDB和网络的名称构建规范路径。
    (if not None).
    """
    outdir = osp.abspath(osp.join(__C.ROOT_DIR, 'output', __C.EXP_DIR, imdb.name))
    if net is not None:
        outdir = osp.join(outdir, net.name)
    if not os.path.exists(outdir):
        os.makedirs(outdir)
    return outdir

def _merge_a_into_b(a, b):  #两个配置文件融合
    """Merge config dictionary a into config dictionary b, clobbering the
    options in b whenever they are also specified in a.
    """
    if type(a) is not edict: #判断a的类别是否是EasyDict(字典)
        return

    for k, v in a.iteritems():#iteritems()返回一个迭代器,迭代a中的所有元素
        # a must specify keys that are in b
        if not b.has_key(k):
#Python 字典(Dictionary) has_key() 函数用于判断键是否存在于字典中,如果键在字典dict里返回true,否则返回false。
            raise KeyError('{} is not a valid config key'.format(k))

        # the types must match, too
        old_type = type(b[k])
        if old_type is not type(v):
            if isinstance(b[k], np.ndarray):#判断b[k]的类型是否为np.ndarray,是则返回True,否则是false
                v = np.array(v, dtype=b[k].dtype)
            else:
                raise ValueError(('Type mismatch ({} vs. {}) '
                                'for config key: {}').format(type(b[k]),
                                                            type(v), k))

        # recursively merge dicts
        #递归地合并字典
        if type(v) is edict:
            try:
                _merge_a_into_b(a[k], b[k])
            except:
                print('Error under config key: {}'.format(k))
                raise
        #用配置a更新配置b的对应项
        else:
            b[k] = v

def cfg_from_file(filename):
    """Load a config file and merge it into the default options."""
    # 导入配置文件并与默认选项融合
    import yaml  #YAML与XML处于对立面,YAML没有自己的数据类型定义,
    # 而是使用实现语言的数据类型且是一种直观的能够被电脑识别的数据序列化格式
    with open(filename, 'r') as f:#以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式
        yaml_cfg = edict(yaml.load(f))#将f中的元素序列到Python的dict中,并使得以属性的的方式去访问字典

    _merge_a_into_b(yaml_cfg, __C)#将导入的配置文件与默认选项融合

def cfg_from_list(cfg_list):    # 命令行设置config
    """Set config keys via通过 list (e.g., from command line)."""
    from ast import literal_eval#ast模块就是帮助Python应用来处理抽象的语法解析的。
    # 而该模块下的literal_eval()函数:则会判断需要计算的内容计算后是不是合法的python类型,
    # 如果是则进行运算,否则就不进行运算
    assert len(cfg_list) % 2 == 0
    for k, v in zip(cfg_list[0::2], cfg_list[1::2]):
        #zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
        key_list = k.split('.')
        d = __C
        for subkey in key_list[:-1]:
            assert d.has_key(subkey)
            d = d[subkey]
        subkey = key_list[-1]
        assert d.has_key(subkey)
        try:
            value = literal_eval(v)
        except:
            # handle the case when v is a string literal
            value = v
        assert type(value) == type(d[subkey]), \
            'type {} does not match original type {}'.format(
            type(value), type(d[subkey]))
        d[subkey] = value

猜你喜欢

转载自blog.csdn.net/l_ml_m_lm_m/article/details/81269929