diff --git a/examples/yolov3/darknet.py b/examples/yolov3/darknet.py index e03b1f705e0ba2d50e1a58a9689b5357150346f7..ca7bd7dc3c59b4fd5a82e6d83eb47795aabbf883 100644 --- a/examples/yolov3/darknet.py +++ b/examples/yolov3/darknet.py @@ -12,12 +12,11 @@ #See the License for the specific language governing permissions and #limitations under the License. -import math import paddle.fluid as fluid from paddle.fluid.param_attr import ParamAttr from paddle.fluid.regularizer import L2Decay -from paddle.fluid.dygraph.nn import Conv2D, BatchNorm, Pool2D, Linear +from paddle.fluid.dygraph.nn import Conv2D, BatchNorm from paddle.incubate.hapi.model import Model from paddle.incubate.hapi.download import get_weights_path_from_url @@ -25,10 +24,9 @@ from paddle.incubate.hapi.download import get_weights_path_from_url __all__ = ['DarkNet', 'darknet53'] # {num_layers: (url, md5)} -model_urls = { - 'darknet53': - ('https://paddle-hapi.bj.bcebos.com/models/darknet53.pdparams', - 'ca506a90e2efecb9a2093f8ada808708') +pretrain_infos = { + 53: ('https://paddlemodels.bj.bcebos.com/hapi/darknet53.pdparams', + '2506357a5c31e865785112fc614a487d') } @@ -68,14 +66,17 @@ class ConvBNLayer(fluid.dygraph.Layer): def forward(self, inputs): out = self.conv(inputs) out = self.batch_norm(out) - if self.act == 'leaky': out = fluid.layers.leaky_relu(x=out, alpha=0.1) return out - class DownSample(fluid.dygraph.Layer): - def __init__(self, ch_in, ch_out, filter_size=3, stride=2, padding=1): + def __init__(self, + ch_in, + ch_out, + filter_size=3, + stride=2, + padding=1): super(DownSample, self).__init__() @@ -86,45 +87,46 @@ class DownSample(fluid.dygraph.Layer): stride=stride, padding=padding) self.ch_out = ch_out - def forward(self, inputs): out = self.conv_bn_layer(inputs) return out - class BasicBlock(fluid.dygraph.Layer): def __init__(self, ch_in, ch_out): super(BasicBlock, self).__init__() self.conv1 = ConvBNLayer( - ch_in=ch_in, ch_out=ch_out, filter_size=1, stride=1, padding=0) + ch_in=ch_in, + ch_out=ch_out, + filter_size=1, + stride=1, + padding=0) self.conv2 = ConvBNLayer( ch_in=ch_out, - ch_out=ch_out * 2, + ch_out=ch_out*2, filter_size=3, stride=1, padding=1) - def forward(self, inputs): conv1 = self.conv1(inputs) conv2 = self.conv2(conv1) out = fluid.layers.elementwise_add(x=inputs, y=conv2, act=None) return out - class LayerWarp(fluid.dygraph.Layer): def __init__(self, ch_in, ch_out, count): - super(LayerWarp, self).__init__() + super(LayerWarp,self).__init__() self.basicblock0 = BasicBlock(ch_in, ch_out) self.res_out_list = [] - for i in range(1, count): + for i in range(1,count): res_out = self.add_sublayer("basic_block_%d" % (i), - BasicBlock(ch_out * 2, ch_out)) + BasicBlock( + ch_out*2, + ch_out)) self.res_out_list.append(res_out) self.ch_out = ch_out - - def forward(self, inputs): + def forward(self,inputs): y = self.basicblock0(inputs) for basic_block_i in self.res_out_list: y = basic_block_i(y) @@ -140,100 +142,78 @@ class DarkNet(Model): Args: num_layers (int): layer number of DarkNet, only 53 supported currently, default: 53. - num_classes (int): output dim of last fc layer. If num_classes <=0, last fc layer - will not be defined. Default: 1000. - with_pool (bool): use pool before the last fc layer or not. Default: True. - classifier_activation (str): activation for the last fc layer. Default: 'softmax'. - + ch_in (int): channel number of input data, default 3. """ - def __init__(self, - num_layers=53, - num_classes=1000, - with_pool=True, - classifier_activation='softmax'): + def __init__(self, num_layers=53, ch_in=3): super(DarkNet, self).__init__() assert num_layers in DarkNet_cfg.keys(), \ "only support num_layers in {} currently" \ .format(DarkNet_cfg.keys()) self.stages = DarkNet_cfg[num_layers] self.stages = self.stages[0:5] - self.num_classes = num_classes - self.with_pool = True - ch_in = 3 + self.conv0 = ConvBNLayer( - ch_in=ch_in, ch_out=32, filter_size=3, stride=1, padding=1) + ch_in=ch_in, + ch_out=32, + filter_size=3, + stride=1, + padding=1) - self.downsample0 = DownSample(ch_in=32, ch_out=32 * 2) + self.downsample0 = DownSample( + ch_in=32, + ch_out=32 * 2) self.darknet53_conv_block_list = [] self.downsample_list = [] - ch_in = [64, 128, 256, 512, 1024] + ch_in = [64,128,256,512,1024] for i, stage in enumerate(self.stages): - conv_block = self.add_sublayer("stage_%d" % (i), - LayerWarp( - int(ch_in[i]), 32 * (2**i), - stage)) + conv_block = self.add_sublayer( + "stage_%d" % (i), + LayerWarp( + int(ch_in[i]), + 32*(2**i), + stage)) self.darknet53_conv_block_list.append(conv_block) - for i in range(len(self.stages) - 1): downsample = self.add_sublayer( "stage_%d_downsample" % i, DownSample( - ch_in=32 * (2**(i + 1)), ch_out=32 * (2**(i + 2)))) + ch_in = 32*(2**(i+1)), + ch_out = 32*(2**(i+2)))) self.downsample_list.append(downsample) - if self.with_pool: - self.global_pool = Pool2D( - pool_size=7, pool_type='avg', global_pooling=True) - - if self.num_classes > 0: - stdv = 1.0 / math.sqrt(32 * (2**(i + 2))) - self.fc_input_dim = 32 * (2**(i + 2)) - - self.fc = Linear( - self.fc_input_dim, - num_classes, - act='softmax', - param_attr=fluid.param_attr.ParamAttr( - initializer=fluid.initializer.Uniform(-stdv, stdv))) - - def forward(self, inputs): - + def forward(self,inputs): + out = self.conv0(inputs) out = self.downsample0(out) - + blocks = [] for i, conv_block_i in enumerate(self.darknet53_conv_block_list): out = conv_block_i(out) + blocks.append(out) if i < len(self.stages) - 1: out = self.downsample_list[i](out) - - if self.with_pool: - out = self.global_pool(out) - if self.num_classes > 0: - out = fluid.layers.reshape(out, shape=[-1, self.fc_input_dim]) - out = self.fc(out) - return out + return blocks[-1:-4:-1] -def _darknet(arch, num_layers=53, pretrained=False, **kwargs): - model = DarkNet(num_layers, **kwargs) +def _darknet(num_layers=53, input_channels=3, pretrained=True): + model = DarkNet(num_layers, input_channels) if pretrained: - assert arch in model_urls, "{} model do not have a pretrained model now, you should set pretrained=False".format( - arch) - weight_path = get_weights_path_from_url(*(model_urls[arch])) + assert num_layers in pretrain_infos.keys(), \ + "DarkNet{} do not have pretrained weights now, " \ + "pretrained should be set as False".format(num_layers) + weight_path = get_weights_path_from_url(*(pretrain_infos[num_layers])) assert weight_path.endswith('.pdparams'), \ "suffix of weight must be .pdparams" - model.load(weight_path) + model.load(weight_path[:-9]) return model -def darknet53(pretrained=False, **kwargs): +def darknet53(input_channels=3, pretrained=True): """DarkNet 53-layer model Args: input_channels (bool): channel number of input data, default 3. pretrained (bool): If True, returns a model pre-trained on ImageNet, default True. - """ - return _darknet('darknet53', 53, pretrained, **kwargs) + return _darknet(53, input_channels, pretrained) diff --git a/examples/yolov3/main.py b/examples/yolov3/main.py index f90ae4fe11a18fa040b7c0492eda930a242253aa..5d44967e30863bb627cc3c26fecd4473072196fe 100644 --- a/examples/yolov3/main.py +++ b/examples/yolov3/main.py @@ -215,7 +215,7 @@ if __name__ == '__main__': metavar='LR', help='initial learning rate') parser.add_argument( - "-b", "--batch_size", default=8, type=int, help="batch size") + "-b", "--batch_size", default=16, type=int, help="batch size") parser.add_argument( "-j", "--num_workers", diff --git a/examples/yolov3/modeling.py b/examples/yolov3/modeling.py index 3beb977849787d007418599a95e6ae5539212bae..4bebe2359565fb697c074455e577b4ba516e2d36 100644 --- a/examples/yolov3/modeling.py +++ b/examples/yolov3/modeling.py @@ -20,9 +20,9 @@ from paddle.fluid.dygraph.nn import Conv2D, BatchNorm from paddle.fluid.param_attr import ParamAttr from paddle.fluid.regularizer import L2Decay -from hapi.model import Model -from hapi.loss import Loss -from hapi.download import get_weights_path_from_url +from paddle.incubate.hapi.model import Model +from paddle.incubate.hapi.loss import Loss +from paddle.incubate.hapi.download import get_weights_path_from_url from darknet import darknet53 __all__ = ['YoloLoss', 'YOLOv3', 'yolov3_darknet53'] @@ -158,10 +158,7 @@ class YOLOv3(Model): self.nms_posk = 100 self.draw_thresh = 0.5 - self.backbone = darknet53( - pretrained=(model_mode == 'train'), - with_pool=False, - num_classes=-1) + self.backbone = darknet53(pretrained=(model_mode == 'train')) self.block_outputs = [] self.yolo_blocks = [] self.route_blocks = [] @@ -300,7 +297,7 @@ class YoloLoss(Loss): anchors=self.anchors, class_num=self.num_classes, ignore_thresh=self.ignore_thresh, - use_label_smooth=True) + use_label_smooth=False) loss = fluid.layers.reduce_mean(loss) losses.append(loss) downsample //= 2 diff --git a/hapi/vision/models/__init__.py b/hapi/vision/models/__init__.py index 4150cb5d88278e7e29575b771f956c3ac8abbd4d..70ff0df8462068bfdf6c8c156175b7b0a548dba5 100644 --- a/hapi/vision/models/__init__.py +++ b/hapi/vision/models/__init__.py @@ -16,19 +16,16 @@ from . import resnet from . import vgg from . import mobilenetv1 from . import mobilenetv2 -from . import darknet from . import lenet from .resnet import * from .mobilenetv1 import * from .mobilenetv2 import * from .vgg import * -from .darknet import * from .lenet import * __all__ = resnet.__all__ \ + vgg.__all__ \ + mobilenetv1.__all__ \ + mobilenetv2.__all__ \ - + darknet.__all__\ + lenet.__all__ diff --git a/hapi/vision/models/darknet.py b/hapi/vision/models/darknet.py deleted file mode 100755 index 993d0ca6b70aa90d7599967f5654c71055bd1f15..0000000000000000000000000000000000000000 --- a/hapi/vision/models/darknet.py +++ /dev/null @@ -1,256 +0,0 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve. -# -#Licensed under the Apache License, Version 2.0 (the "License"); -#you may not use this file except in compliance with the License. -#You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -#Unless required by applicable law or agreed to in writing, software -#distributed under the License is distributed on an "AS IS" BASIS, -#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -#See the License for the specific language governing permissions and -#limitations under the License. - -import math -import paddle.fluid as fluid -from paddle.fluid.param_attr import ParamAttr -from paddle.fluid.regularizer import L2Decay - -from paddle.fluid.dygraph.nn import Conv2D, BatchNorm, Pool2D, Linear - -from hapi.model import Model -from hapi.download import get_weights_path_from_url - -__all__ = ['DarkNet', 'darknet53'] - -# {num_layers: (url, md5)} -model_urls = { - 'darknet53': - ('https://paddle-hapi.bj.bcebos.com/models/darknet53.pdparams', - 'ca506a90e2efecb9a2093f8ada808708') -} - - -class ConvBNLayer(fluid.dygraph.Layer): - def __init__(self, - ch_in, - ch_out, - filter_size=3, - stride=1, - groups=1, - padding=0, - act="leaky"): - super(ConvBNLayer, self).__init__() - - self.conv = Conv2D( - num_channels=ch_in, - num_filters=ch_out, - filter_size=filter_size, - stride=stride, - padding=padding, - groups=groups, - param_attr=ParamAttr( - initializer=fluid.initializer.Normal(0., 0.02)), - bias_attr=False, - act=None) - self.batch_norm = BatchNorm( - num_channels=ch_out, - param_attr=ParamAttr( - initializer=fluid.initializer.Normal(0., 0.02), - regularizer=L2Decay(0.)), - bias_attr=ParamAttr( - initializer=fluid.initializer.Constant(0.0), - regularizer=L2Decay(0.))) - - self.act = act - - def forward(self, inputs): - out = self.conv(inputs) - out = self.batch_norm(out) - # out = fluid.layers.relu(out) - if self.act == 'leaky': - out = fluid.layers.leaky_relu(x=out, alpha=0.1) - return out - - -class DownSample(fluid.dygraph.Layer): - def __init__(self, ch_in, ch_out, filter_size=3, stride=2, padding=1): - - super(DownSample, self).__init__() - - self.conv_bn_layer = ConvBNLayer( - ch_in=ch_in, - ch_out=ch_out, - filter_size=filter_size, - stride=stride, - padding=padding) - self.ch_out = ch_out - - def forward(self, inputs): - out = self.conv_bn_layer(inputs) - return out - - -class BasicBlock(fluid.dygraph.Layer): - def __init__(self, ch_in, ch_out): - super(BasicBlock, self).__init__() - - self.conv1 = ConvBNLayer( - ch_in=ch_in, ch_out=ch_out, filter_size=1, stride=1, padding=0) - self.conv2 = ConvBNLayer( - ch_in=ch_out, - ch_out=ch_out * 2, - filter_size=3, - stride=1, - padding=1) - - def forward(self, inputs): - conv1 = self.conv1(inputs) - conv2 = self.conv2(conv1) - out = fluid.layers.elementwise_add(x=inputs, y=conv2, act=None) - return out - - -class LayerWarp(fluid.dygraph.Layer): - def __init__(self, ch_in, ch_out, count): - super(LayerWarp, self).__init__() - - self.basicblock0 = BasicBlock(ch_in, ch_out) - self.res_out_list = [] - for i in range(1, count): - res_out = self.add_sublayer("basic_block_%d" % (i), - BasicBlock(ch_out * 2, ch_out)) - self.res_out_list.append(res_out) - self.ch_out = ch_out - - def forward(self, inputs): - y = self.basicblock0(inputs) - for basic_block_i in self.res_out_list: - y = basic_block_i(y) - return y - - -DarkNet_cfg = {53: ([1, 2, 8, 8, 4])} - - -class DarkNet(Model): - """DarkNet model from - `"YOLOv3: An Incremental Improvement" `_ - - Args: - num_layers (int): layer number of DarkNet, only 53 supported currently, default: 53. - num_classes (int): output dim of last fc layer. If num_classes <=0, last fc layer - will not be defined. Default: 1000. - with_pool (bool): use pool before the last fc layer or not. Default: True. - classifier_activation (str): activation for the last fc layer. Default: 'softmax'. - - Examples: - .. code-block:: python - - from hapi.vision.models import DarkNet - - model = DarkNet() - """ - - def __init__(self, - num_layers=53, - num_classes=1000, - with_pool=True, - classifier_activation='softmax'): - super(DarkNet, self).__init__() - assert num_layers in DarkNet_cfg.keys(), \ - "only support num_layers in {} currently" \ - .format(DarkNet_cfg.keys()) - self.stages = DarkNet_cfg[num_layers] - self.stages = self.stages[0:5] - self.num_classes = num_classes - self.with_pool = True - ch_in = 3 - self.conv0 = ConvBNLayer( - ch_in=ch_in, ch_out=32, filter_size=3, stride=1, padding=1) - - self.downsample0 = DownSample(ch_in=32, ch_out=32 * 2) - self.darknet53_conv_block_list = [] - self.downsample_list = [] - ch_in = [64, 128, 256, 512, 1024] - for i, stage in enumerate(self.stages): - conv_block = self.add_sublayer("stage_%d" % (i), - LayerWarp( - int(ch_in[i]), 32 * (2**i), - stage)) - self.darknet53_conv_block_list.append(conv_block) - - for i in range(len(self.stages) - 1): - downsample = self.add_sublayer( - "stage_%d_downsample" % i, - DownSample( - ch_in=32 * (2**(i + 1)), ch_out=32 * (2**(i + 2)))) - self.downsample_list.append(downsample) - - if self.with_pool: - self.global_pool = Pool2D( - pool_size=7, pool_type='avg', global_pooling=True) - - if self.num_classes > 0: - stdv = 1.0 / math.sqrt(32 * (2**(i + 2))) - self.fc_input_dim = 32 * (2**(i + 2)) - - self.fc = Linear( - self.fc_input_dim, - num_classes, - act='softmax', - param_attr=fluid.param_attr.ParamAttr( - initializer=fluid.initializer.Uniform(-stdv, stdv))) - - def forward(self, inputs): - - out = self.conv0(inputs) - out = self.downsample0(out) - - for i, conv_block_i in enumerate(self.darknet53_conv_block_list): - out = conv_block_i(out) - if i < len(self.stages) - 1: - out = self.downsample_list[i](out) - - if self.with_pool: - out = self.global_pool(out) - if self.num_classes > 0: - out = fluid.layers.reshape(out, shape=[-1, self.fc_input_dim]) - out = self.fc(out) - return out - - -def _darknet(arch, num_layers=53, pretrained=False, **kwargs): - model = DarkNet(num_layers, **kwargs) - if pretrained: - assert arch in model_urls, "{} model do not have a pretrained model now, you should set pretrained=False".format( - arch) - weight_path = get_weights_path_from_url(*(model_urls[arch])) - assert weight_path.endswith('.pdparams'), \ - "suffix of weight must be .pdparams" - model.load(weight_path) - return model - - -def darknet53(pretrained=False, **kwargs): - """DarkNet 53-layer model - - Args: - input_channels (bool): channel number of input data, default 3. - pretrained (bool): If True, returns a model pre-trained on ImageNet, - default True. - - Examples: - .. code-block:: python - - from hapi.vision.models import darknet53 - - # build model - model = darknet53() - - #build model and load imagenet pretrained weight - model = darknet53(pretrained=True) - - """ - return _darknet('darknet53', 53, pretrained, **kwargs)