diff --git a/hapi/model.py b/hapi/model.py index ed891f58a95f399d02475bfec16c53d9c82e8422..4d27355603f111dfc637d68e7efa9695369b504b 100644 --- a/hapi/model.py +++ b/hapi/model.py @@ -798,7 +798,7 @@ class Model(fluid.dygraph.Layer): "{} receives a shape {}, but the expected shape is {}.". format(key, list(state.shape), list(param.shape))) return param, state - + def _strip_postfix(path): path, ext = os.path.splitext(path) assert ext in ['', '.pdparams', '.pdopt', '.pdmodel'], \ @@ -936,35 +936,35 @@ class Model(fluid.dygraph.Layer): Args: train_data (Dataset|DataLoader): An iterable data loader is used for train. An instance of paddle paddle.io.Dataset or - paddle.io.Dataloader is recomended. + paddle.io.Dataloader is recomended. Default: None. eval_data (Dataset|DataLoader): An iterable data loader is used for evaluation at the end of epoch. If None, will not do evaluation. An instance of paddle.io.Dataset or paddle.io.Dataloader - is recomended. + is recomended. Default: None. batch_size (int): Integer number. The batch size of train_data and eval_data. When train_data and eval_data are both the instance of Dataloader, this - parameter will be ignored. - epochs (int): Integer number. The number of epochs to train the model. + parameter will be ignored. Default: 1. + epochs (int): Integer number. The number of epochs to train the model. Default: 1. eval_freq (int): The frequency, in number of epochs, an evalutation - is performed. + is performed. Default: 1. log_freq (int): The frequency, in number of steps, the training logs - are printed. + are printed. Default: 10. save_dir(str|None): The directory to save checkpoint during training. - If None, will not save checkpoint. - save_freq (int): The frequency, in number of epochs, to save checkpoint. + If None, will not save checkpoint. Default: None. + save_freq (int): The frequency, in number of epochs, to save checkpoint. Default: 1. verbose (int): The verbosity mode, should be 0, 1, or 2. - 0 = silent, 1 = progress bar, 2 = one line per epoch. + 0 = silent, 1 = progress bar, 2 = one line per epoch. Default: 2. drop_last (bool): whether drop the last incomplete batch of train_data when dataset size is not divisible by the batch size. When train_data - is an instance of Dataloader, this parameter will be ignored. + is an instance of Dataloader, this parameter will be ignored. Default: False. shuffle (bool): whther to shuffle train_data. When train_data is an instance - of Dataloader, this parameter will be ignored. + of Dataloader, this parameter will be ignored. Default: True. num_workers (int): the number of subprocess to load data, 0 for no subprocess used and loading data in main process. When train_data and eval_data are - both the instance of Dataloader, this parameter will be ignored. + both the instance of Dataloader, this parameter will be ignored. Default: 0. callbacks (Callback|None): A list of `Callback` instances to apply during training. If None, `ProgBarLogger` and `ModelCheckpoint` - are automatically inserted. + are automatically inserted. Default: None. """ assert train_data is not None, \ @@ -1066,18 +1066,20 @@ class Model(fluid.dygraph.Layer): evaluation. An instance of paddle.io.Dataset or paddle.io.Dataloader is recomended. batch_size (int): Integer number. The batch size of train_data and eval_data. - When train_data and eval_data are both the instance of Dataloader, this - parameter will be ignored. + When eval_data is the instance of Dataloader, this argument will be ignored. + Default: 1. log_freq (int): The frequency, in number of steps, the eval logs - are printed. + are printed. Default: 10. verbose (int): The verbosity mode, should be 0, 1, or 2. - 0 = silent, 1 = progress bar, 2 = one line per epoch. + 0 = silent, 1 = progress bar, 2 = one line per epoch. Default: 2. num_workers (int): The number of subprocess to load data, 0 for no subprocess used and loading data in main process. When train_data and eval_data are - both the instance of Dataloader, this parameter will be ignored. + both the instance of Dataloader, this parameter will be ignored. Default: 0. callbacks (Callback|None): A list of `Callback` instances to apply during training. If None, `ProgBarLogger` and `ModelCheckpoint` - are automatically inserted. + are automatically inserted. Default: None. + Returns: + dict: Result of metric. """ if fluid.in_dygraph_mode(): @@ -1142,16 +1144,18 @@ class Model(fluid.dygraph.Layer): is recomended. batch_size (int): Integer number. The batch size of train_data and eval_data. When train_data and eval_data are both the instance of Dataloader, this - parameter will be ignored. + argument will be ignored. Default: 1. num_workers (int): the number of subprocess to load data, 0 for no subprocess used and loading data in main process. When train_data and eval_data are - both the instance of Dataloader, this parameter will be ignored. + both the instance of Dataloader, this argument will be ignored. Default: 0. stack_output (bool): whether stack output field like a batch, as for an output filed of a sample is in shape [X, Y], test_data contains N samples, predict output field will be in shape [N, X, Y] if stack_output is True, and will be a length N list in shape [[X, Y], [X, Y], ....[X, Y]] if stack_outputs is False. stack_outputs as False is used for LoDTensor output situation, - it is recommended set as True if outputs contains no LoDTensor. Default False + it is recommended set as True if outputs contains no LoDTensor. Default: False. + Returns: + list: output of models. """ if fluid.in_dygraph_mode(): diff --git a/hapi/vision/models/mobilenetv1.py b/hapi/vision/models/mobilenetv1.py index ff27cb9c5d7745361858c3f6ec13e5865fafa605..31c0acbee2fdc107b0d776605c296c2c9296bcfd 100644 --- a/hapi/vision/models/mobilenetv1.py +++ b/hapi/vision/models/mobilenetv1.py @@ -263,7 +263,7 @@ class MobileNetV1(Model): def _mobilenet(arch, pretrained=False, **kwargs): - model = MobileNetV1(num_classes=1000, with_pool=True, **kwargs) + model = MobileNetV1(**kwargs) if pretrained: assert arch in model_urls, "{} model do not have a pretrained model now, you should set pretrained=False".format( arch) @@ -276,12 +276,13 @@ def _mobilenet(arch, pretrained=False, **kwargs): return model -def mobilenet_v1(pretrained=False, scale=1.0): +def mobilenet_v1(pretrained=False, scale=1.0, **kwargs): """MobileNetV1 Args: pretrained (bool): If True, returns a model pre-trained on ImageNet. Default: False. scale: (float): scale of channels in each layer. Default: 1.0. """ - model = _mobilenet('mobilenetv1_' + str(scale), pretrained, scale=scale) + model = _mobilenet( + 'mobilenetv1_' + str(scale), pretrained, scale=scale, **kwargs) return model diff --git a/hapi/vision/models/mobilenetv2.py b/hapi/vision/models/mobilenetv2.py index 02db68e569cea06dac876dd3b7bc044cd15542f7..d624625bcda1b763a0b3e511b6146776245e2fd5 100644 --- a/hapi/vision/models/mobilenetv2.py +++ b/hapi/vision/models/mobilenetv2.py @@ -237,7 +237,7 @@ class MobileNetV2(Model): def _mobilenet(arch, pretrained=False, **kwargs): - model = MobileNetV2(num_classes=1000, with_pool=True, **kwargs) + model = MobileNetV2(**kwargs) if pretrained: assert arch in model_urls, "{} model do not have a pretrained model now, you should set pretrained=False".format( arch) @@ -250,12 +250,13 @@ def _mobilenet(arch, pretrained=False, **kwargs): return model -def mobilenet_v2(pretrained=False, scale=1.0): +def mobilenet_v2(pretrained=False, scale=1.0, **kwargs): """MobileNetV2 Args: pretrained (bool): If True, returns a model pre-trained on ImageNet. Default: False. scale: (float): scale of channels in each layer. Default: 1.0. """ - model = _mobilenet('mobilenetv2_' + str(scale), pretrained, scale=scale) + model = _mobilenet( + 'mobilenetv2_' + str(scale), pretrained, scale=scale, **kwargs) return model diff --git a/hapi/vision/models/resnet.py b/hapi/vision/models/resnet.py index 804cc3534ad4c3cda4f800b41d8567922450e037..ac0944ee651224b106db71d0c87e9e5c29fd14d9 100644 --- a/hapi/vision/models/resnet.py +++ b/hapi/vision/models/resnet.py @@ -30,8 +30,18 @@ __all__ = [ ] model_urls = { + 'resnet18': ('https://paddle-hapi.bj.bcebos.com/models/resnet18.pdparams', + '0ba53eea9bc970962d0ef96f7b94057e'), + 'resnet34': ('https://paddle-hapi.bj.bcebos.com/models/resnet34.pdparams', + '46bc9f7c3dd2e55b7866285bee91eff3'), 'resnet50': ('https://paddle-hapi.bj.bcebos.com/models/resnet50.pdparams', - '0884c9087266496c41c60d14a96f8530') + '0884c9087266496c41c60d14a96f8530'), + 'resnet101': + ('https://paddle-hapi.bj.bcebos.com/models/resnet101.pdparams', + 'fb07a451df331e4b0bb861ed97c3a9b9'), + 'resnet152': + ('https://paddle-hapi.bj.bcebos.com/models/resnet152.pdparams', + 'f9c700f26d3644bb76ad2226ed5f5713'), } @@ -252,8 +262,8 @@ class ResNet(Model): return x -def _resnet(arch, Block, depth, pretrained): - model = ResNet(Block, depth, num_classes=1000, with_pool=True) +def _resnet(arch, Block, depth, pretrained, **kwargs): + model = ResNet(Block, depth, **kwargs) if pretrained: assert arch in model_urls, "{} model do not have a pretrained model now, you should set pretrained=False".format( arch) @@ -265,46 +275,46 @@ def _resnet(arch, Block, depth, pretrained): return model -def resnet18(pretrained=False): +def resnet18(pretrained=False, **kwargs): """ResNet 18-layer model Args: pretrained (bool): If True, returns a model pre-trained on ImageNet """ - return _resnet('resnet18', BasicBlock, 18, pretrained) + return _resnet('resnet18', BasicBlock, 18, pretrained, **kwargs) -def resnet34(pretrained=False): +def resnet34(pretrained=False, **kwargs): """ResNet 34-layer model Args: pretrained (bool): If True, returns a model pre-trained on ImageNet """ - return _resnet('resnet34', BasicBlock, 34, pretrained) + return _resnet('resnet34', BasicBlock, 34, pretrained, **kwargs) -def resnet50(pretrained=False): +def resnet50(pretrained=False, **kwargs): """ResNet 50-layer model Args: pretrained (bool): If True, returns a model pre-trained on ImageNet """ - return _resnet('resnet50', BottleneckBlock, 50, pretrained) + return _resnet('resnet50', BottleneckBlock, 50, pretrained, **kwargs) -def resnet101(pretrained=False): +def resnet101(pretrained=False, **kwargs): """ResNet 101-layer model Args: pretrained (bool): If True, returns a model pre-trained on ImageNet """ - return _resnet('resnet101', BottleneckBlock, 101, pretrained) + return _resnet('resnet101', BottleneckBlock, 101, pretrained, **kwargs) -def resnet152(pretrained=False): +def resnet152(pretrained=False, **kwargs): """ResNet 152-layer model Args: pretrained (bool): If True, returns a model pre-trained on ImageNet """ - return _resnet('resnet152', BottleneckBlock, 152, pretrained) + return _resnet('resnet152', BottleneckBlock, 152, pretrained, **kwargs) diff --git a/hapi/vision/models/vgg.py b/hapi/vision/models/vgg.py index 5ef09bd665e4308739651d868203a4a56b14de38..41cf34eddf7d4d379f9ea3a6bc5490f9763919dc 100644 --- a/hapi/vision/models/vgg.py +++ b/hapi/vision/models/vgg.py @@ -137,7 +137,7 @@ def _vgg(arch, cfg, batch_norm, pretrained, **kwargs): return model -def vgg11(pretrained=False, batch_norm=False): +def vgg11(pretrained=False, batch_norm=False, **kwargs): """VGG 11-layer model Args: @@ -147,10 +147,10 @@ def vgg11(pretrained=False, batch_norm=False): model_name = 'vgg11' if batch_norm: model_name += ('_bn') - return _vgg(model_name, 'A', batch_norm, pretrained) + return _vgg(model_name, 'A', batch_norm, pretrained, **kwargs) -def vgg13(pretrained=False, batch_norm=False): +def vgg13(pretrained=False, batch_norm=False, **kwargs): """VGG 13-layer model Args: @@ -160,10 +160,10 @@ def vgg13(pretrained=False, batch_norm=False): model_name = 'vgg13' if batch_norm: model_name += ('_bn') - return _vgg(model_name, 'B', batch_norm, pretrained) + return _vgg(model_name, 'B', batch_norm, pretrained, **kwargs) -def vgg16(pretrained=False, batch_norm=False): +def vgg16(pretrained=False, batch_norm=False, **kwargs): """VGG 16-layer model Args: @@ -173,10 +173,10 @@ def vgg16(pretrained=False, batch_norm=False): model_name = 'vgg16' if batch_norm: model_name += ('_bn') - return _vgg(model_name, 'D', batch_norm, pretrained) + return _vgg(model_name, 'D', batch_norm, pretrained, **kwargs) -def vgg19(pretrained=False, batch_norm=False): +def vgg19(pretrained=False, batch_norm=False, **kwargs): """VGG 19-layer model Args: @@ -186,4 +186,4 @@ def vgg19(pretrained=False, batch_norm=False): model_name = 'vgg19' if batch_norm: model_name += ('_bn') - return _vgg(model_name, 'E', batch_norm, pretrained) + return _vgg(model_name, 'E', batch_norm, pretrained, **kwargs) diff --git a/hapi/vision/transforms/transforms.py b/hapi/vision/transforms/transforms.py index 79926f811fcac0844d3290bbbccd4a5d389c626e..3d974171ce0d6f5a80f2af6a272a4250d771fb4d 100644 --- a/hapi/vision/transforms/transforms.py +++ b/hapi/vision/transforms/transforms.py @@ -71,7 +71,7 @@ class Compose(object): except Exception as e: stack_info = traceback.format_exc() print("fail to perform transform [{}] with error: " - "{} and stack:\n{}".format(f, e, str(stack_info))) + "{} and stack:\n{}".format(f, e, str(stack_info))) raise e return data @@ -92,6 +92,7 @@ class BatchCompose(object): these transforms perform on batch data. """ + def __init__(self, transforms=[]): self.transforms = transforms @@ -102,7 +103,7 @@ class BatchCompose(object): except Exception as e: stack_info = traceback.format_exc() print("fail to perform batch transform [{}] with error: " - "{} and stack:\n{}".format(f, e, str(stack_info))) + "{} and stack:\n{}".format(f, e, str(stack_info))) raise e # sample list to batch data @@ -112,7 +113,7 @@ class BatchCompose(object): class Resize(object): - """Resize the input PIL Image to the given size. + """Resize the input Image to the given size. Args: size (int|list|tuple): Desired output size. If size is a sequence like @@ -130,13 +131,6 @@ class Resize(object): self.interpolation = interpolation def __call__(self, img, lbl): - """ - Args: - img (PIL Image): Image to be scaled. - - Returns: - PIL Image: Rescaled image. - """ return F.resize(img, self.size, self.interpolation), lbl @@ -328,18 +322,22 @@ class Permute(object): Input image should be HWC mode and an instance of numpy.ndarray. Args: - mode: Output mode of input. Use "CHW" mode by default. + mode: Output mode of input. Default: "CHW". + to_rgb: convert 'bgr' image to 'rgb'. Default: True. """ - def __init__(self, mode="CHW"): + def __init__(self, mode="CHW", to_rgb=True): assert mode in [ "CHW" ], "Only support 'CHW' mode, but received mode: {}".format(mode) self.mode = mode + self.to_rgb = to_rgb def __call__(self, img, lbl): + if self.to_rgb: + img = img[..., ::-1] if self.mode == "CHW": - return img.transpose((2, 0, 1))[::-1, ...], lbl + return img.transpose((2, 0, 1)), lbl return img, lbl