这部分是训练的配置参数,首先时父类Config,然后子类train_config,eval_config继承父类,这里跟Backbone的写法类似。
import ast
from typing import Tuple, List
from roi.pooler import Pooler# Pooler类 有两个方法 ROI pooling ROI Align
# config的父类
class Config(object):
#图像缩放的尺寸 短边缩放为600 长边为 1000
IMAGE_MIN_SIDE: float = 600.0
IMAGE_MAX_SIDE: float = 1000.0
# Anchor box的比例 faster-rcnn原文 [0.5,1,2.0] 这里写成元组的形式
ANCHOR_RATIOS: List[Tuple[int, int]] = [(1, 2), (1, 1), (2, 1)]
ANCHOR_SIZES: List[int] = [128, 256, 512]
POOLER_MODE: Pooler.Mode = Pooler.Mode.ALIGN # ROI pool的模式
@classmethod#python中cls代表的是类的本身
#cfg=Config() # 应为注释了pool类所以这里 打印少了一个 pool—mode的值
#print(cfg.describe())
# Config:
# ANCHOR_RATIOS = [(1, 2), (1, 1), (2, 1)]
# ANCHOR_SIZES = [128, 256, 512]
# IMAGE_MAX_SIDE = 1000.0
# IMAGE_MIN_SIDE = 600.0
def describe(cls):
text = 'nConfig:n'
#callable 用于检查是否可用 getattr获取对象的属性
attrs = [attr for attr in dir(cls) if not callable(getattr(cls, attr)) and not attr.startswith('__')]
text += 'n'.join(['t{:s} = {:s}'.format(attr, str(getattr(cls, attr))) for attr in attrs]) + 'n'
return text
# 配置函数 可以自定义配置 ast literal_eval()函数:则会判断需要计算的内容计算后是不是合法的python类型,如果是则进行运算,否则就不进行运算
#IMAGE_MIN_SIDE 短边
#IMAGE_MAX_SIDE 长边
#ANCHOR_RATIOS anchor的比例
#ANCHOR_SIZES anchor的大小
#POOLER_MODE roi pooling align
@classmethod
def setup(cls, image_min_side: float = None, image_max_side: float = None,
anchor_ratios: List[Tuple[int, int]] = None, anchor_sizes: List[int] = None, pooler_mode: str = None):
if image_min_side is not None:
cls.IMAGE_MIN_SIDE = image_min_side
if image_max_side is not None:
cls.IMAGE_MAX_SIDE = image_max_side
if anchor_ratios is not None:
cls.ANCHOR_RATIOS = ast.literal_eval(anchor_ratios)
if anchor_sizes is not None:
cls.ANCHOR_SIZES = ast.literal_eval(anchor_sizes)
if pooler_mode is not None:
# pass
cls.POOLER_MODE = Pooler.Mode(pooler_mode)
if __name__ == '__main__':
#调试时注释掉 请相关的pool类
cfg=Config()
print(cfg.describe())
train_config:
import ast
from typing import List, Tuple
from config.config import Config
#训练配置参数
class TrainConfig(Config):
RPN_PRE_NMS_TOP_N: int = 12000 #RPN 从20000+ anchor中预先挑选12000个 anchor
RPN_POST_NMS_TOP_N: int = 2000 # NMS后取的2000个
ANCHOR_SMOOTH_L1_LOSS_BETA: float = 1.0 # RPN计算 bbox 回归的 smooth L1 的参数
PROPOSAL_SMOOTH_L1_LOSS_BETA: float = 1.0 # RCNN计算 bbox 回归的 smooth L1 的参数
BATCH_SIZE: int = 1 # batch size的大小
LEARNING_RATE: float = 0.001 # 学习率 0.001
MOMENTUM: float = 0.9 #动量因子 0.9 加速SGD收敛用
WEIGHT_DECAY: float = 0.0005 #正则化项
STEP_LR_SIZES: List[int] = [50000, 70000] # 学习率在 50000 70000 时衰减一次
STEP_LR_GAMMA: float = 0.1 #
WARM_UP_FACTOR: float = 0.3333 #学习率 预热的因子 一般来说开头的训练不是很稳定,所以需要warm up
WARM_UP_NUM_ITERS: int = 500# 预热的iter 次数
NUM_STEPS_TO_DISPLAY: int = 20 # 每20 步 显示相关的信息
NUM_STEPS_TO_SNAPSHOT: int = 10000 #每10000 保存一下模型
NUM_STEPS_TO_FINISH: int = 90000 # 90000终止训练
@classmethod
def setup(cls, image_min_side: float = None, image_max_side: float = None,
anchor_ratios: List[Tuple[int, int]] = None, anchor_sizes: List[int] = None, pooler_mode: str = None,
rpn_pre_nms_top_n: int = None, rpn_post_nms_top_n: int = None,
anchor_smooth_l1_loss_beta: float = None, proposal_smooth_l1_loss_beta: float = None,
batch_size: int = None, learning_rate: float = None, momentum: float = None, weight_decay: float = None,
step_lr_sizes: List[int] = None, step_lr_gamma: float = None,
warm_up_factor: float = None, warm_up_num_iters: int = None,
num_steps_to_display: int = None, num_steps_to_snapshot: int = None, num_steps_to_finish: int = None):
super().setup(image_min_side, image_max_side, anchor_ratios, anchor_sizes, pooler_mode)
if rpn_pre_nms_top_n is not None:
cls.RPN_PRE_NMS_TOP_N = rpn_pre_nms_top_n
if rpn_post_nms_top_n is not None:
cls.RPN_POST_NMS_TOP_N = rpn_post_nms_top_n
if anchor_smooth_l1_loss_beta is not None:
cls.ANCHOR_SMOOTH_L1_LOSS_BETA = anchor_smooth_l1_loss_beta
if proposal_smooth_l1_loss_beta is not None:
cls.PROPOSAL_SMOOTH_L1_LOSS_BETA = proposal_smooth_l1_loss_beta
if batch_size is not None:
cls.BATCH_SIZE = batch_size
if learning_rate is not None:
cls.LEARNING_RATE = learning_rate
if momentum is not None:
cls.MOMENTUM = momentum
if weight_decay is not None:
cls.WEIGHT_DECAY = weight_decay
if step_lr_sizes is not None:
cls.STEP_LR_SIZES = ast.literal_eval(step_lr_sizes)
if step_lr_gamma is not None:
cls.STEP_LR_GAMMA = step_lr_gamma
if warm_up_factor is not None:
cls.WARM_UP_FACTOR = warm_up_factor
if warm_up_num_iters is not None:
cls.WARM_UP_NUM_ITERS = warm_up_num_iters
if num_steps_to_display is not None:
cls.NUM_STEPS_TO_DISPLAY = num_steps_to_display
if num_steps_to_snapshot is not None:
cls.NUM_STEPS_TO_SNAPSHOT = num_steps_to_snapshot
if num_steps_to_finish is not None:
cls.NUM_STEPS_TO_FINISH = num_steps_to_finish
eval_config
from typing import List, Tuple
from config.config import Config
class EvalConfig(Config):
RPN_PRE_NMS_TOP_N: int = 6000 # 推理时候 anchor挑选 6000
RPN_POST_NMS_TOP_N: int = 300 # NMS的为 300 个 加快推理的速度
@classmethod
def setup(cls, image_min_side: float = None, image_max_side: float = None,
anchor_ratios: List[Tuple[int, int]] = None, anchor_sizes: List[int] = None, pooler_mode: str = None,
rpn_pre_nms_top_n: int = None, rpn_post_nms_top_n: int = None):
super().setup(image_min_side, image_max_side, anchor_ratios, anchor_sizes, pooler_mode)
if rpn_pre_nms_top_n is not None:
cls.RPN_PRE_NMS_TOP_N = rpn_pre_nms_top_n
if rpn_post_nms_top_n is not None:
cls.RPN_POST_NMS_TOP_N = rpn_post_nms_top_n
References:
https://github.com/potterhsu/easy-faster-rcnn.pytorchgithub.com 【python基础笔记】cls含义及使用方法 - 一介蚍蜉 - 博客园www.cnblogs.com Python callable() 函数www.runoob.com Python中函数 eval 和 ast.literal_eval 的区别详解blog.csdn.net![f667c857e83c0649aa02f47d6a115c9d.png](https://i-blog.csdnimg.cn/blog_migrate/3a61a3b8f1f81073906eeeaaf2812894.jpeg)