學習率
lr = (base_lr / 8) x num_gpus x (img_per_gpu/2)
其中 base_lr 是源碼中給定的 學習率,這是在 8張GPU上面,每張GPU上面放2張圖片得到的學習率,所以當對應的GPU數目和每張GPU上的圖片數目發生改變時,學習率成正比例變化。
選用新的backbone來訓練
這里選用 res2net_26w_6s 作為backbone;
以cascade_rcnn_r50_fpn_1x.py 作為config文件
-
在
mmdetection-master\mmdet\models\backbones
中新建一個 res2net.py文件,並將模型代碼復制進去 https://github.com/Res2Net/Res2Net-PretrainedModels/blob/master/res2net.py -
由於這里需要多尺度特征圖,可參考 原有的
resnet.py
,返回的是stage1,stage2,stage3,stage4組成的list,因此新增的res2net.py
的代碼需要進行修改- 1). 源碼:
class Res2Net(nn.Module): def __init__(self, block, layers, baseWidth = 26, scale = 4, num_classes=1000):
修改:添加一個register;需要再import
from ..registry import BACKBONES
; 同時把block中的參數先寫上默認參數,不然后面的config文件中傳 block名字時比較麻煩@BACKBONES.register_module class Res2Net(nn.Module): def __init__(self, block=Bottle2neck, layers=[3,4,6,3], baseWidth=26, scale=6, num_classes=1000):
-
2). 源碼:class Res2Net下面的 forward
def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu(x) x = self.maxpool(x) x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) x = self.avgpool(x) x = x.view(x.size(0), -1) x = self.fc(x) return x
修改:返回stage1, stage2,stage3,stage4
def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu(x) x = self.maxpool(x) x1 = self.layer1(x) x2 = self.layer2(x1) x3 = self.layer3(x2) x4 = self.layer4(x3) #x = self.avgpool(x) #x = x.view(x.size(0), -1) #x = self.fc(x) return [x1,x2,x3,x4]
-
3). 增加一個 init_weights函數(這邊是不添加就報錯,所以就直接從 resnet.py 中復制過來了),如resnet.py中一樣,修改對應的block名稱
def init_weights(self, pretrained=None): if isinstance(pretrained, str): from mmdet.apis import get_root_logger logger = get_root_logger() load_checkpoint(self, pretrained, strict=False, logger=logger) elif pretrained is None: for m in self.modules(): if isinstance(m, nn.Conv2d): kaiming_init(m) elif isinstance(m, (_BatchNorm, nn.GroupNorm)): constant_init(m, 1) if self.dcn is not None: for m in self.modules(): if isinstance(m, Bottle2neck) and hasattr( m, 'conv2_offset'): constant_init(m.conv2_offset, 0) if self.zero_init_residual: for m in self.modules(): if isinstance(m, Bottle2neck): constant_init(m.norm3, 0) # elif isinstance(m, BasicBlock): # constant_init(m.norm2, 0) else: raise TypeError('pretrained must be a str or None')
-
修改 config 文件,cascade_rcnn_r50_fpn_1x.py
源碼:
# model settings
model = dict(
type='CascadeRCNN',
num_stages=3,
pretrained='torchvision://resnet50',
backbone=dict(
type='ResNet',
depth=50,
num_stages=4,
out_indices=(0, 1, 2, 3),
frozen_stages=1,
style='pytorch'),
修改:
model = dict(
type='CascadeRCNN',
num_stages=3,
#pretrained='torchvision://resnet50',
pretrained='/media/mtc/dac70756-6922-445c-9cbe-58847ebdc56f/zql/mmdetection/pretrained_models/res2net50_26w_6s-19041792.pth',
backbone=dict(
type='Res2Net',
layers=[3,4,6,3], baseWidth=26, scale=6, num_classes=1000,
),