未验证 提交 1210665a 编写于 作者: L lilithzhou 提交者: GitHub

Merge branch 'PaddlePaddle:develop' into develop

...@@ -7,29 +7,30 @@ VisualDL, a visualization analysis tool of PaddlePaddle, provides a variety of c ...@@ -7,29 +7,30 @@ VisualDL, a visualization analysis tool of PaddlePaddle, provides a variety of c
Now PaddleClas support use VisualDL to visualize the changes of learning rate, loss, accuracy in training. Now PaddleClas support use VisualDL to visualize the changes of learning rate, loss, accuracy in training.
### Set config and start training ### Set config and start training
You only need to set the `vdl_dir` field in train config: You only need to set the field `Global.use_visualdl` to `True` in train config:
```yaml ```yaml
# config.yaml # config.yaml
vdl_dir: "./vdl.log" Global:
...
use_visualdl: True
...
``` ```
`vdl_dir`: Specify the directory where VisualDL stores logs. PaddleClas will save the VisualDL logs to subdirectory `vdl/` under the output directory specified by `Global.output_dir`. And then you just need to start training normally:
Then normal start training:
```shell ```shell
python3 tools/train.py -c config.yaml python3 tools/train.py -c config.yaml
``` ```
### Start VisualDL ### Start VisualDL
After starting the training program, you can start the VisualDL service in the new terminal session: After starting the training program, you can start the VisualDL service in a new terminal session:
```shell ```shell
visualdl --logdir ./vdl.log visualdl --logdir ./output/vdl/
``` ```
In the above command, `--logdir` specify the logs directory. VisualDL will traverse and iterate to find the subdirectories of the specified directory to visualize all the experimental results. You can also use the following parameters to set the IP and port number of the VisualDL service: In the above command, `--logdir` specify the directory of the VisualDL logs produced in training. VisualDL will traverse and iterate to find the subdirectories of the specified directory to visualize all the experimental results. You can also use the following parameters to set the IP and port number of the VisualDL service:
* `--host`:ip, default is 127.0.0.1 * `--host`:ip, default is 127.0.0.1
* `--port`:port, default is 8040 * `--port`:port, default is 8040
......
...@@ -23,7 +23,7 @@ Among them, `-c` is used to specify the path of the configuration file, `-o` is ...@@ -23,7 +23,7 @@ Among them, `-c` is used to specify the path of the configuration file, `-o` is
`-o use_gpu=True` means to use GPU for training. If you want to use the CPU for training, you need to set `use_gpu` to `False`. `-o use_gpu=True` means to use GPU for training. If you want to use the CPU for training, you need to set `use_gpu` to `False`.
Of course, you can also directly modify the configuration file to update the configuration. For specific configuration parameters, please refer to [Configuration Document](config_en.md). Of course, you can also directly modify the configuration file to update the configuration. For specific configuration parameters, please refer to [Configuration Document](config_description_en.md).
* The output log examples are as follows: * The output log examples are as follows:
* If mixup or cutmix is used in training, top-1 and top-k (default by 5) will not be printed in the log: * If mixup or cutmix is used in training, top-1 and top-k (default by 5) will not be printed in the log:
......
...@@ -7,15 +7,17 @@ VisualDL是飞桨可视化分析工具,以丰富的图表呈现训练参数变 ...@@ -7,15 +7,17 @@ VisualDL是飞桨可视化分析工具,以丰富的图表呈现训练参数变
现在PaddleClas支持在训练阶段使用VisualDL查看训练过程中学习率(learning rate)、损失值(loss)以及准确率(accuracy)的变化情况。 现在PaddleClas支持在训练阶段使用VisualDL查看训练过程中学习率(learning rate)、损失值(loss)以及准确率(accuracy)的变化情况。
### 设置config文件并启动训练 ### 设置config文件并启动训练
在PaddleClas中使用VisualDL,只需在训练配置文件(config文件)添加如下字段 在PaddleClas中使用VisualDL,只需在训练配置文件(config文件)中设置字段 `Global.use_visualdl``True`
```yaml ```yaml
# config.yaml # config.yaml
vdl_dir: "./vdl.log" Global:
...
use_visualdl: True
...
``` ```
`vdl_dir` 用于指定VisualDL用于保存log信息的目录。
然后正常启动训练即可: PaddleClas 会将 VisualDL 的日志保存在 `Global.output_dir` 字段指定目录下的 `vdl/` 子目录下,然后正常启动训练即可:
```shell ```shell
python3 tools/train.py -c config.yaml python3 tools/train.py -c config.yaml
...@@ -25,10 +27,10 @@ python3 tools/train.py -c config.yaml ...@@ -25,10 +27,10 @@ python3 tools/train.py -c config.yaml
在启动训练程序后,可以在新的终端session中启动VisualDL服务: 在启动训练程序后,可以在新的终端session中启动VisualDL服务:
```shell ```shell
visualdl --logdir ./vdl.log visualdl --logdir ./output/vdl/
``` ```
上述命令中,参数`--logdir`用于指定日志目录,VisualDL将遍历并且迭代寻找指定目录的子目录,将所有实验结果进行可视化。也同样可以使用下述参数设定VisualDL服务的ip及端口号: 上述命令中,参数`--logdir`用于指定保存 VisualDL 日志的目录,VisualDL将遍历并且迭代寻找指定目录的子目录,将所有实验结果进行可视化。也同样可以使用下述参数设定VisualDL服务的ip及端口号:
* `--host`:设定IP,默认为127.0.0.1 * `--host`:设定IP,默认为127.0.0.1
* `--port`:设定端口,默认为8040 * `--port`:设定端口,默认为8040
......
...@@ -30,7 +30,7 @@ python3 tools/train.py \ ...@@ -30,7 +30,7 @@ python3 tools/train.py \
其中,`-c`用于指定配置文件的路径,`-o`用于指定需要修改或者添加的参数,其中`-o Arch.pretrained=False`表示不使用预训练模型,`-o Global.device=gpu`表示使用GPU进行训练。如果希望使用CPU进行训练,则需要将`Global.device`设置为`cpu` 其中,`-c`用于指定配置文件的路径,`-o`用于指定需要修改或者添加的参数,其中`-o Arch.pretrained=False`表示不使用预训练模型,`-o Global.device=gpu`表示使用GPU进行训练。如果希望使用CPU进行训练,则需要将`Global.device`设置为`cpu`
更详细的训练配置,也可以直接修改模型对应的配置文件。具体配置参数参考[配置文档](config.md) 更详细的训练配置,也可以直接修改模型对应的配置文件。具体配置参数参考[配置文档](config_description.md)
运行上述命令,可以看到输出日志,示例如下: 运行上述命令,可以看到输出日志,示例如下:
......
...@@ -41,10 +41,15 @@ class _SysPathG(object): ...@@ -41,10 +41,15 @@ class _SysPathG(object):
self.path) self.path)
with _SysPathG( with _SysPathG(os.path.dirname(os.path.abspath(__file__)), ):
os.path.join( import ppcls
os.path.dirname(os.path.abspath(__file__)), 'ppcls', 'arch')): import ppcls.arch.backbone as backbone
import backbone
def ppclas_init():
if ppcls.utils.logger._logger is None:
ppcls.utils.logger.init_logger()
ppclas_init()
def _load_pretrained_parameters(model, name): def _load_pretrained_parameters(model, name):
url = 'https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/{}_pretrained.pdparams'.format( url = 'https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/{}_pretrained.pdparams'.format(
...@@ -63,9 +68,8 @@ with _SysPathG( ...@@ -63,9 +68,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `AlexNet` model depends on args. model: nn.Layer. Specific `AlexNet` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.AlexNet(**kwargs) model = backbone.AlexNet(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'AlexNet')
return model return model
...@@ -80,9 +84,8 @@ with _SysPathG( ...@@ -80,9 +84,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `VGG11` model depends on args. model: nn.Layer. Specific `VGG11` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.VGG11(**kwargs) model = backbone.VGG11(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'VGG11')
return model return model
...@@ -97,9 +100,8 @@ with _SysPathG( ...@@ -97,9 +100,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `VGG13` model depends on args. model: nn.Layer. Specific `VGG13` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.VGG13(**kwargs) model = backbone.VGG13(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'VGG13')
return model return model
...@@ -114,9 +116,8 @@ with _SysPathG( ...@@ -114,9 +116,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `VGG16` model depends on args. model: nn.Layer. Specific `VGG16` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.VGG16(**kwargs) model = backbone.VGG16(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'VGG16')
return model return model
...@@ -131,9 +132,8 @@ with _SysPathG( ...@@ -131,9 +132,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `VGG19` model depends on args. model: nn.Layer. Specific `VGG19` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.VGG19(**kwargs) model = backbone.VGG19(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'VGG19')
return model return model
...@@ -149,9 +149,8 @@ with _SysPathG( ...@@ -149,9 +149,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNet18` model depends on args. model: nn.Layer. Specific `ResNet18` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ResNet18(**kwargs) model = backbone.ResNet18(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ResNet18')
return model return model
...@@ -167,9 +166,8 @@ with _SysPathG( ...@@ -167,9 +166,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNet34` model depends on args. model: nn.Layer. Specific `ResNet34` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ResNet34(**kwargs) model = backbone.ResNet34(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ResNet34')
return model return model
...@@ -185,9 +183,8 @@ with _SysPathG( ...@@ -185,9 +183,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNet50` model depends on args. model: nn.Layer. Specific `ResNet50` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ResNet50(**kwargs) model = backbone.ResNet50(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ResNet50')
return model return model
...@@ -203,9 +200,8 @@ with _SysPathG( ...@@ -203,9 +200,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNet101` model depends on args. model: nn.Layer. Specific `ResNet101` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ResNet101(**kwargs) model = backbone.ResNet101(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ResNet101')
return model return model
...@@ -221,9 +217,8 @@ with _SysPathG( ...@@ -221,9 +217,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNet152` model depends on args. model: nn.Layer. Specific `ResNet152` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ResNet152(**kwargs) model = backbone.ResNet152(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ResNet152')
return model return model
...@@ -237,9 +232,8 @@ with _SysPathG( ...@@ -237,9 +232,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `SqueezeNet1_0` model depends on args. model: nn.Layer. Specific `SqueezeNet1_0` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.SqueezeNet1_0(**kwargs) model = backbone.SqueezeNet1_0(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'SqueezeNet1_0')
return model return model
...@@ -253,9 +247,8 @@ with _SysPathG( ...@@ -253,9 +247,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `SqueezeNet1_1` model depends on args. model: nn.Layer. Specific `SqueezeNet1_1` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.SqueezeNet1_1(**kwargs) model = backbone.SqueezeNet1_1(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'SqueezeNet1_1')
return model return model
...@@ -271,9 +264,8 @@ with _SysPathG( ...@@ -271,9 +264,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `DenseNet121` model depends on args. model: nn.Layer. Specific `DenseNet121` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.DenseNet121(**kwargs) model = backbone.DenseNet121(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'DenseNet121')
return model return model
...@@ -289,9 +281,8 @@ with _SysPathG( ...@@ -289,9 +281,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `DenseNet161` model depends on args. model: nn.Layer. Specific `DenseNet161` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.DenseNet161(**kwargs) model = backbone.DenseNet161(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'DenseNet161')
return model return model
...@@ -307,9 +298,8 @@ with _SysPathG( ...@@ -307,9 +298,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `DenseNet169` model depends on args. model: nn.Layer. Specific `DenseNet169` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.DenseNet169(**kwargs) model = backbone.DenseNet169(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'DenseNet169')
return model return model
...@@ -325,9 +315,8 @@ with _SysPathG( ...@@ -325,9 +315,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `DenseNet201` model depends on args. model: nn.Layer. Specific `DenseNet201` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.DenseNet201(**kwargs) model = backbone.DenseNet201(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'DenseNet201')
return model return model
...@@ -343,9 +332,8 @@ with _SysPathG( ...@@ -343,9 +332,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `DenseNet264` model depends on args. model: nn.Layer. Specific `DenseNet264` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.DenseNet264(**kwargs) model = backbone.DenseNet264(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'DenseNet264')
return model return model
...@@ -359,9 +347,8 @@ with _SysPathG( ...@@ -359,9 +347,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `InceptionV3` model depends on args. model: nn.Layer. Specific `InceptionV3` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.InceptionV3(**kwargs) model = backbone.InceptionV3(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'InceptionV3')
return model return model
...@@ -375,9 +362,8 @@ with _SysPathG( ...@@ -375,9 +362,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `InceptionV4` model depends on args. model: nn.Layer. Specific `InceptionV4` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.InceptionV4(**kwargs) model = backbone.InceptionV4(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'InceptionV4')
return model return model
...@@ -391,9 +377,8 @@ with _SysPathG( ...@@ -391,9 +377,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `GoogLeNet` model depends on args. model: nn.Layer. Specific `GoogLeNet` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.GoogLeNet(**kwargs) model = backbone.GoogLeNet(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'GoogLeNet')
return model return model
...@@ -407,9 +392,8 @@ with _SysPathG( ...@@ -407,9 +392,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ShuffleNetV2_x0_25` model depends on args. model: nn.Layer. Specific `ShuffleNetV2_x0_25` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ShuffleNetV2_x0_25(**kwargs) model = backbone.ShuffleNetV2_x0_25(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ShuffleNetV2_x0_25')
return model return model
...@@ -423,9 +407,8 @@ with _SysPathG( ...@@ -423,9 +407,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV1` model depends on args. model: nn.Layer. Specific `MobileNetV1` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV1(**kwargs) model = backbone.MobileNetV1(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'MobileNetV1')
return model return model
...@@ -439,9 +422,8 @@ with _SysPathG( ...@@ -439,9 +422,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV1_x0_25` model depends on args. model: nn.Layer. Specific `MobileNetV1_x0_25` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV1_x0_25(**kwargs) model = backbone.MobileNetV1_x0_25(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'MobileNetV1_x0_25')
return model return model
...@@ -455,9 +437,8 @@ with _SysPathG( ...@@ -455,9 +437,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV1_x0_5` model depends on args. model: nn.Layer. Specific `MobileNetV1_x0_5` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV1_x0_5(**kwargs) model = backbone.MobileNetV1_x0_5(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'MobileNetV1_x0_5')
return model return model
...@@ -471,9 +452,8 @@ with _SysPathG( ...@@ -471,9 +452,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV1_x0_75` model depends on args. model: nn.Layer. Specific `MobileNetV1_x0_75` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV1_x0_75(**kwargs) model = backbone.MobileNetV1_x0_75(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'MobileNetV1_x0_75')
return model return model
...@@ -487,9 +467,8 @@ with _SysPathG( ...@@ -487,9 +467,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV2_x0_25` model depends on args. model: nn.Layer. Specific `MobileNetV2_x0_25` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV2_x0_25(**kwargs) model = backbone.MobileNetV2_x0_25(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'MobileNetV2_x0_25')
return model return model
...@@ -503,9 +482,8 @@ with _SysPathG( ...@@ -503,9 +482,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV2_x0_5` model depends on args. model: nn.Layer. Specific `MobileNetV2_x0_5` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV2_x0_5(**kwargs) model = backbone.MobileNetV2_x0_5(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'MobileNetV2_x0_5')
return model return model
...@@ -519,9 +497,8 @@ with _SysPathG( ...@@ -519,9 +497,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV2_x0_75` model depends on args. model: nn.Layer. Specific `MobileNetV2_x0_75` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV2_x0_75(**kwargs) model = backbone.MobileNetV2_x0_75(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'MobileNetV2_x0_75')
return model return model
...@@ -535,9 +512,8 @@ with _SysPathG( ...@@ -535,9 +512,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV2_x1_5` model depends on args. model: nn.Layer. Specific `MobileNetV2_x1_5` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV2_x1_5(**kwargs) model = backbone.MobileNetV2_x1_5(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'MobileNetV2_x1_5')
return model return model
...@@ -551,9 +527,8 @@ with _SysPathG( ...@@ -551,9 +527,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV2_x2_0` model depends on args. model: nn.Layer. Specific `MobileNetV2_x2_0` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV2_x2_0(**kwargs) model = backbone.MobileNetV2_x2_0(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'MobileNetV2_x2_0')
return model return model
...@@ -567,10 +542,8 @@ with _SysPathG( ...@@ -567,10 +542,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV3_large_x0_35` model depends on args. model: nn.Layer. Specific `MobileNetV3_large_x0_35` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV3_large_x0_35(**kwargs) model = backbone.MobileNetV3_large_x0_35(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model,
'MobileNetV3_large_x0_35')
return model return model
...@@ -584,10 +557,8 @@ with _SysPathG( ...@@ -584,10 +557,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV3_large_x0_5` model depends on args. model: nn.Layer. Specific `MobileNetV3_large_x0_5` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV3_large_x0_5(**kwargs) model = backbone.MobileNetV3_large_x0_5(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model,
'MobileNetV3_large_x0_5')
return model return model
...@@ -601,10 +572,8 @@ with _SysPathG( ...@@ -601,10 +572,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV3_large_x0_75` model depends on args. model: nn.Layer. Specific `MobileNetV3_large_x0_75` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV3_large_x0_75(**kwargs) model = backbone.MobileNetV3_large_x0_75(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model,
'MobileNetV3_large_x0_75')
return model return model
...@@ -618,10 +587,8 @@ with _SysPathG( ...@@ -618,10 +587,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV3_large_x1_0` model depends on args. model: nn.Layer. Specific `MobileNetV3_large_x1_0` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV3_large_x1_0(**kwargs) model = backbone.MobileNetV3_large_x1_0(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model,
'MobileNetV3_large_x1_0')
return model return model
...@@ -635,10 +602,8 @@ with _SysPathG( ...@@ -635,10 +602,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV3_large_x1_25` model depends on args. model: nn.Layer. Specific `MobileNetV3_large_x1_25` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV3_large_x1_25(**kwargs) model = backbone.MobileNetV3_large_x1_25(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model,
'MobileNetV3_large_x1_25')
return model return model
...@@ -652,10 +617,8 @@ with _SysPathG( ...@@ -652,10 +617,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV3_small_x0_35` model depends on args. model: nn.Layer. Specific `MobileNetV3_small_x0_35` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV3_small_x0_35(**kwargs) model = backbone.MobileNetV3_small_x0_35(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model,
'MobileNetV3_small_x0_35')
return model return model
...@@ -669,10 +632,8 @@ with _SysPathG( ...@@ -669,10 +632,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV3_small_x0_5` model depends on args. model: nn.Layer. Specific `MobileNetV3_small_x0_5` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV3_small_x0_5(**kwargs) model = backbone.MobileNetV3_small_x0_5(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model,
'MobileNetV3_small_x0_5')
return model return model
...@@ -686,10 +647,8 @@ with _SysPathG( ...@@ -686,10 +647,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV3_small_x0_75` model depends on args. model: nn.Layer. Specific `MobileNetV3_small_x0_75` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV3_small_x0_75(**kwargs) model = backbone.MobileNetV3_small_x0_75(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model,
'MobileNetV3_small_x0_75')
return model return model
...@@ -703,10 +662,8 @@ with _SysPathG( ...@@ -703,10 +662,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV3_small_x1_0` model depends on args. model: nn.Layer. Specific `MobileNetV3_small_x1_0` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV3_small_x1_0(**kwargs) model = backbone.MobileNetV3_small_x1_0(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model,
'MobileNetV3_small_x1_0')
return model return model
...@@ -720,10 +677,8 @@ with _SysPathG( ...@@ -720,10 +677,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `MobileNetV3_small_x1_25` model depends on args. model: nn.Layer. Specific `MobileNetV3_small_x1_25` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.MobileNetV3_small_x1_25(**kwargs) model = backbone.MobileNetV3_small_x1_25(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model,
'MobileNetV3_small_x1_25')
return model return model
...@@ -737,9 +692,8 @@ with _SysPathG( ...@@ -737,9 +692,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNeXt101_32x4d` model depends on args. model: nn.Layer. Specific `ResNeXt101_32x4d` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ResNeXt101_32x4d(**kwargs) model = backbone.ResNeXt101_32x4d(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ResNeXt101_32x4d')
return model return model
...@@ -753,9 +707,8 @@ with _SysPathG( ...@@ -753,9 +707,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNeXt101_64x4d` model depends on args. model: nn.Layer. Specific `ResNeXt101_64x4d` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ResNeXt101_64x4d(**kwargs) model = backbone.ResNeXt101_64x4d(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ResNeXt101_64x4d')
return model return model
...@@ -769,9 +722,8 @@ with _SysPathG( ...@@ -769,9 +722,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNeXt152_32x4d` model depends on args. model: nn.Layer. Specific `ResNeXt152_32x4d` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ResNeXt152_32x4d(**kwargs) model = backbone.ResNeXt152_32x4d(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ResNeXt152_32x4d')
return model return model
...@@ -785,9 +737,8 @@ with _SysPathG( ...@@ -785,9 +737,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNeXt152_64x4d` model depends on args. model: nn.Layer. Specific `ResNeXt152_64x4d` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ResNeXt152_64x4d(**kwargs) model = backbone.ResNeXt152_64x4d(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ResNeXt152_64x4d')
return model return model
...@@ -801,9 +752,8 @@ with _SysPathG( ...@@ -801,9 +752,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNeXt50_32x4d` model depends on args. model: nn.Layer. Specific `ResNeXt50_32x4d` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ResNeXt50_32x4d(**kwargs) model = backbone.ResNeXt50_32x4d(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ResNeXt50_32x4d')
return model return model
...@@ -817,9 +767,8 @@ with _SysPathG( ...@@ -817,9 +767,8 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNeXt50_64x4d` model depends on args. model: nn.Layer. Specific `ResNeXt50_64x4d` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.ResNeXt50_64x4d(**kwargs) model = backbone.ResNeXt50_64x4d(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'ResNeXt50_64x4d')
return model return model
...@@ -833,8 +782,7 @@ with _SysPathG( ...@@ -833,8 +782,7 @@ with _SysPathG(
Returns: Returns:
model: nn.Layer. Specific `ResNeXt50_64x4d` model depends on args. model: nn.Layer. Specific `ResNeXt50_64x4d` model depends on args.
""" """
kwargs.update({'pretrained': pretrained})
model = backbone.DarkNet53(**kwargs) model = backbone.DarkNet53(**kwargs)
if pretrained:
model = _load_pretrained_parameters(model, 'DarkNet53')
return model return model
...@@ -58,6 +58,7 @@ from ppcls.arch.backbone.model_zoo.rednet import RedNet26, RedNet38, RedNet50, R ...@@ -58,6 +58,7 @@ from ppcls.arch.backbone.model_zoo.rednet import RedNet26, RedNet38, RedNet50, R
from ppcls.arch.backbone.model_zoo.tnt import TNT_small from ppcls.arch.backbone.model_zoo.tnt import TNT_small
from ppcls.arch.backbone.model_zoo.hardnet import HarDNet68, HarDNet85, HarDNet39_ds, HarDNet68_ds from ppcls.arch.backbone.model_zoo.hardnet import HarDNet68, HarDNet85, HarDNet39_ds, HarDNet68_ds
from ppcls.arch.backbone.variant_models.resnet_variant import ResNet50_last_stage_stride1 from ppcls.arch.backbone.variant_models.resnet_variant import ResNet50_last_stage_stride1
from ppcls.arch.backbone.variant_models.vgg_variant import VGG19Sigmoid
def get_apis(): def get_apis():
......
...@@ -33,9 +33,9 @@ MODEL_URLS = { ...@@ -33,9 +33,9 @@ MODEL_URLS = {
"SwinTransformer_base_patch4_window12_384": "SwinTransformer_base_patch4_window12_384":
"https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/SwinTransformer_base_patch4_window12_384_pretrained.pdparams", "https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/SwinTransformer_base_patch4_window12_384_pretrained.pdparams",
"SwinTransformer_large_patch4_window7_224": "SwinTransformer_large_patch4_window7_224":
"https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/SwinTransformer_large_patch4_window7_224_pretrained.pdparams", "https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/SwinTransformer_large_patch4_window7_224_22kto1k_pretrained.pdparams",
"SwinTransformer_large_patch4_window12_384": "SwinTransformer_large_patch4_window12_384":
"https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/SwinTransformer_large_patch4_window12_384_pretrained.pdparams", "https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/SwinTransformer_large_patch4_window12_384_22kto1k_pretrained.pdparams",
} }
__all__ = list(MODEL_URLS.keys()) __all__ = list(MODEL_URLS.keys())
......
from .resnet_variant import ResNet50_last_stage_stride1 from .resnet_variant import ResNet50_last_stage_stride1
from .vgg_variant import VGG19Sigmoid
import paddle
from paddle.nn import Sigmoid
from ppcls.arch.backbone.legendary_models.vgg import VGG19
__all__ = ["VGG19Sigmoid"]
class SigmoidSuffix(paddle.nn.Layer):
def __init__(self, origin_layer):
super(SigmoidSuffix, self).__init__()
self.origin_layer = origin_layer
self.sigmoid = Sigmoid()
def forward(self, input, res_dict=None, **kwargs):
x = self.origin_layer(input)
x = self.sigmoid(x)
return x
def VGG19Sigmoid(pretrained=False, use_ssld=False, **kwargs):
def replace_function(origin_layer):
new_layer = SigmoidSuffix(origin_layer)
return new_layer
match_re = "linear_2"
model = VGG19(pretrained=pretrained, use_ssld=use_ssld, **kwargs)
model.replace_sub(match_re, replace_function, True)
return model
...@@ -28,7 +28,7 @@ class CircleMargin(nn.Layer): ...@@ -28,7 +28,7 @@ class CircleMargin(nn.Layer):
weight_attr = paddle.ParamAttr( weight_attr = paddle.ParamAttr(
initializer=paddle.nn.initializer.XavierNormal()) initializer=paddle.nn.initializer.XavierNormal())
self.fc0 = paddle.nn.Linear( self.fc = paddle.nn.Linear(
self.embedding_size, self.class_num, weight_attr=weight_attr) self.embedding_size, self.class_num, weight_attr=weight_attr)
def forward(self, input, label): def forward(self, input, label):
...@@ -36,19 +36,22 @@ class CircleMargin(nn.Layer): ...@@ -36,19 +36,22 @@ class CircleMargin(nn.Layer):
paddle.sum(paddle.square(input), axis=1, keepdim=True)) paddle.sum(paddle.square(input), axis=1, keepdim=True))
input = paddle.divide(input, feat_norm) input = paddle.divide(input, feat_norm)
weight = self.fc0.weight weight = self.fc.weight
weight_norm = paddle.sqrt( weight_norm = paddle.sqrt(
paddle.sum(paddle.square(weight), axis=0, keepdim=True)) paddle.sum(paddle.square(weight), axis=0, keepdim=True))
weight = paddle.divide(weight, weight_norm) weight = paddle.divide(weight, weight_norm)
logits = paddle.matmul(input, weight) logits = paddle.matmul(input, weight)
if not self.training or label is None:
return logits
alpha_p = paddle.clip(-logits.detach() + 1 + self.margin, min=0.) alpha_p = paddle.clip(-logits.detach() + 1 + self.margin, min=0.)
alpha_n = paddle.clip(logits.detach() + self.margin, min=0.) alpha_n = paddle.clip(logits.detach() + self.margin, min=0.)
delta_p = 1 - self.margin delta_p = 1 - self.margin
delta_n = self.margin delta_n = self.margin
index = paddle.fluid.layers.where(label != -1).reshape([-1])
m_hot = F.one_hot(label.reshape([-1]), num_classes=logits.shape[1]) m_hot = F.one_hot(label.reshape([-1]), num_classes=logits.shape[1])
logits_p = alpha_p * (logits - delta_p) logits_p = alpha_p * (logits - delta_p)
logits_n = alpha_n * (logits - delta_n) logits_n = alpha_n * (logits - delta_n)
pre_logits = logits_p * m_hot + logits_n * (1 - m_hot) pre_logits = logits_p * m_hot + logits_n * (1 - m_hot)
......
...@@ -46,6 +46,9 @@ class CosMargin(paddle.nn.Layer): ...@@ -46,6 +46,9 @@ class CosMargin(paddle.nn.Layer):
weight = paddle.divide(weight, weight_norm) weight = paddle.divide(weight, weight_norm)
cos = paddle.matmul(input, weight) cos = paddle.matmul(input, weight)
if not self.training or label is None:
return cos
cos_m = cos - self.margin cos_m = cos - self.margin
one_hot = paddle.nn.functional.one_hot(label, self.class_num) one_hot = paddle.nn.functional.one_hot(label, self.class_num)
......
# global configs
Global:
checkpoints: null
pretrained_model: null
output_dir: ./output_dlbhc/
device: gpu
save_interval: 1
eval_during_train: True
eval_interval: 1
epochs: 100
#eval_mode: "retrieval"
print_batch_step: 10
use_visualdl: False
# used for static mode and model export
image_shape: [3, 224, 224]
save_inference_dir: ./inference
#feature postprocess
feature_normalize: False
feature_binarize: "round"
# model architecture
Arch:
name: "RecModel"
Backbone:
name: "MobileNetV3_large_x1_0"
pretrained: True
class_num: 512
Head:
name: "FC"
class_num: 50030
embedding_size: 512
infer_output_key: "features"
infer_add_softmax: "false"
# loss function config for train/eval process
Loss:
Train:
- CELoss:
weight: 1.0
epsilon: 0.1
Eval:
- CELoss:
weight: 1.0
Optimizer:
name: Momentum
momentum: 0.9
lr:
name: Piecewise
learning_rate: 0.1
decay_epochs: [50, 150]
values: [0.1, 0.01, 0.001]
# data loader for train and eval
DataLoader:
Train:
dataset:
name: ImageNetDataset
image_root: ./dataset/Aliproduct/
cls_label_path: ./dataset/Aliproduct/train_list.txt
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- ResizeImage:
size: 256
- RandCropImage:
size: 227
- RandFlipImage:
flip_code: 1
- NormalizeImage:
scale: 1.0/255.0
mean: [0.4914, 0.4822, 0.4465]
std: [0.2023, 0.1994, 0.2010]
order: ''
sampler:
name: DistributedBatchSampler
batch_size: 128
drop_last: False
shuffle: True
loader:
num_workers: 4
use_shared_memory: True
Eval:
dataset:
name: ImageNetDataset
image_root: ./dataset/Aliproduct/
cls_label_path: ./dataset/Aliproduct/val_list.txt
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- ResizeImage:
size: 227
- NormalizeImage:
scale: 1.0/255.0
mean: [0.4914, 0.4822, 0.4465]
std: [0.2023, 0.1994, 0.2010]
order: ''
sampler:
name: DistributedBatchSampler
batch_size: 256
drop_last: False
shuffle: False
loader:
num_workers: 4
use_shared_memory: True
Infer:
infer_imgs: docs/images/whl/demo.jpg
batch_size: 10
transforms:
- DecodeImage:
to_rgb: True
channel_first: False
- ResizeImage:
resize_short: 256
- CropImage:
size: 227
- NormalizeImage:
scale: 1.0/255.0
mean: [0.4914, 0.4822, 0.4465]
std: [0.2023, 0.1994, 0.2010]
order: ''
- ToCHWImage:
PostProcess:
name: Topk
topk: 5
class_id_map_file: ppcls/utils/imagenet1k_label_list.txt
Metric:
Train:
- TopkAcc:
topk: [1, 5]
Eval:
- TopkAcc:
topk: [1, 5]
# switch to metric below when eval by retrieval
# - Recallk:
# topk: [1]
# - mAP:
# - Precisionk:
# topk: [1]
# global configs
Global:
checkpoints: null
pretrained_model: null
output_dir: ./output
device: gpu
save_interval: 1
eval_during_train: True
eval_interval: 1
eval_mode: "retrieval"
epochs: 128
print_batch_step: 10
use_visualdl: False
# used for static mode and model export
image_shape: [3, 224, 224]
save_inference_dir: ./inference
#feature postprocess
feature_normalize: False
feature_binarize: "round"
# model architecture
Arch:
name: "RecModel"
Backbone:
name: "VGG19Sigmoid"
pretrained: True
class_num: 48
Head:
name: "FC"
class_num: 10
embedding_size: 48
infer_output_key: "features"
infer_add_softmax: "false"
# loss function config for train/eval process
Loss:
Train:
- CELoss:
weight: 1.0
epsilon: 0.1
Eval:
- CELoss:
weight: 1.0
Optimizer:
name: Momentum
momentum: 0.9
lr:
name: Piecewise
learning_rate: 0.01
decay_epochs: [200]
values: [0.01, 0.001]
# data loader for train and eval
DataLoader:
Train:
dataset:
name: ImageNetDataset
image_root: ./dataset/cifar10/
cls_label_path: ./dataset/cifar10/cifar10-2/train.txt
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- ResizeImage:
size: 256
- RandCropImage:
size: 224
- RandFlipImage:
flip_code: 1
- NormalizeImage:
scale: 1.0/255.0
mean: [0.4914, 0.4822, 0.4465]
std: [0.2023, 0.1994, 0.2010]
order: ''
sampler:
name: DistributedBatchSampler
batch_size: 128
drop_last: False
shuffle: True
loader:
num_workers: 4
use_shared_memory: True
Eval:
Query:
dataset:
name: ImageNetDataset
image_root: ./dataset/cifar10/
cls_label_path: ./dataset/cifar10/cifar10-2/test.txt
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- ResizeImage:
size: 224
- NormalizeImage:
scale: 1.0/255.0
mean: [0.4914, 0.4822, 0.4465]
std: [0.2023, 0.1994, 0.2010]
order: ''
sampler:
name: DistributedBatchSampler
batch_size: 512
drop_last: False
shuffle: False
loader:
num_workers: 4
use_shared_memory: True
Gallery:
dataset:
name: ImageNetDataset
image_root: ./dataset/cifar10/
cls_label_path: ./dataset/cifar10/cifar10-2/database.txt
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- ResizeImage:
size: 224
- NormalizeImage:
scale: 1.0/255.0
mean: [0.4914, 0.4822, 0.4465]
std: [0.2023, 0.1994, 0.2010]
order: ''
sampler:
name: DistributedBatchSampler
batch_size: 512
drop_last: False
shuffle: False
loader:
num_workers: 4
use_shared_memory: True
Metric:
Train:
- TopkAcc:
topk: [1, 5]
Eval:
- mAP:
- Precisionk:
topk: [1, 5]
...@@ -42,9 +42,9 @@ class RandomErasing(object): ...@@ -42,9 +42,9 @@ class RandomErasing(object):
h = int(round(math.sqrt(target_area * aspect_ratio))) h = int(round(math.sqrt(target_area * aspect_ratio)))
w = int(round(math.sqrt(target_area / aspect_ratio))) w = int(round(math.sqrt(target_area / aspect_ratio)))
if w < img.shape[2] and h < img.shape[1]: if w < img.shape[1] and h < img.shape[0]:
x1 = random.randint(0, img.shape[1] - h) x1 = random.randint(0, img.shape[0] - h)
y1 = random.randint(0, img.shape[2] - w) y1 = random.randint(0, img.shape[1] - w)
if img.shape[0] == 3: if img.shape[0] == 3:
img[x1:x1 + h, y1:y1 + w, 0] = self.mean[0] img[x1:x1 + h, y1:y1 + w, 0] = self.mean[0]
img[x1:x1 + h, y1:y1 + w, 1] = self.mean[1] img[x1:x1 + h, y1:y1 + w, 1] = self.mean[1]
......
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# 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.
from ppcls.engine.evaluation.classification import classification_eval
from ppcls.engine.evaluation.retrieval import retrieval_eval
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# 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.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import time
import platform
import paddle
from ppcls.utils.misc import AverageMeter
from ppcls.utils import logger
def classification_eval(evaler, epoch_id=0):
output_info = dict()
time_info = {
"batch_cost": AverageMeter(
"batch_cost", '.5f', postfix=" s,"),
"reader_cost": AverageMeter(
"reader_cost", ".5f", postfix=" s,"),
}
print_batch_step = evaler.config["Global"]["print_batch_step"]
metric_key = None
tic = time.time()
eval_dataloader = evaler.eval_dataloader if evaler.use_dali else evaler.eval_dataloader(
)
max_iter = len(evaler.eval_dataloader) - 1 if platform.system(
) == "Windows" else len(evaler.eval_dataloader)
for iter_id, batch in enumerate(eval_dataloader):
if iter_id >= max_iter:
break
if iter_id == 5:
for key in time_info:
time_info[key].reset()
if evaler.use_dali:
batch = [
paddle.to_tensor(batch[0]['data']),
paddle.to_tensor(batch[0]['label'])
]
time_info["reader_cost"].update(time.time() - tic)
batch_size = batch[0].shape[0]
batch[0] = paddle.to_tensor(batch[0]).astype("float32")
batch[1] = batch[1].reshape([-1, 1]).astype("int64")
# image input
out = evaler.model(batch[0])
# calc loss
if evaler.eval_loss_func is not None:
loss_dict = evaler.eval_loss_func(out, batch[1])
for key in loss_dict:
if key not in output_info:
output_info[key] = AverageMeter(key, '7.5f')
output_info[key].update(loss_dict[key].numpy()[0], batch_size)
# calc metric
if evaler.eval_metric_func is not None:
metric_dict = evaler.eval_metric_func(out, batch[1])
if paddle.distributed.get_world_size() > 1:
for key in metric_dict:
paddle.distributed.all_reduce(
metric_dict[key], op=paddle.distributed.ReduceOp.SUM)
metric_dict[key] = metric_dict[
key] / paddle.distributed.get_world_size()
for key in metric_dict:
if metric_key is None:
metric_key = key
if key not in output_info:
output_info[key] = AverageMeter(key, '7.5f')
output_info[key].update(metric_dict[key].numpy()[0],
batch_size)
time_info["batch_cost"].update(time.time() - tic)
if iter_id % print_batch_step == 0:
time_msg = "s, ".join([
"{}: {:.5f}".format(key, time_info[key].avg)
for key in time_info
])
ips_msg = "ips: {:.5f} images/sec".format(
batch_size / time_info["batch_cost"].avg)
metric_msg = ", ".join([
"{}: {:.5f}".format(key, output_info[key].val)
for key in output_info
])
logger.info("[Eval][Epoch {}][Iter: {}/{}]{}, {}, {}".format(
epoch_id, iter_id,
len(evaler.eval_dataloader), metric_msg, time_msg, ips_msg))
tic = time.time()
if evaler.use_dali:
evaler.eval_dataloader.reset()
metric_msg = ", ".join([
"{}: {:.5f}".format(key, output_info[key].avg) for key in output_info
])
logger.info("[Eval][Epoch {}][Avg]{}".format(epoch_id, metric_msg))
# do not try to save best eval.model
if evaler.eval_metric_func is None:
return -1
# return 1st metric in the dict
return output_info[metric_key].avg
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# 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.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import platform
import paddle
from ppcls.utils import logger
def retrieval_eval(evaler, epoch_id=0):
evaler.model.eval()
# step1. build gallery
gallery_feas, gallery_img_id, gallery_unique_id = cal_feature(
evaler, name='gallery')
query_feas, query_img_id, query_query_id = cal_feature(
evaler, name='query')
# step2. do evaluation
sim_block_size = evaler.config["Global"].get("sim_block_size", 64)
sections = [sim_block_size] * (len(query_feas) // sim_block_size)
if len(query_feas) % sim_block_size:
sections.append(len(query_feas) % sim_block_size)
fea_blocks = paddle.split(query_feas, num_or_sections=sections)
if query_query_id is not None:
query_id_blocks = paddle.split(
query_query_id, num_or_sections=sections)
image_id_blocks = paddle.split(query_img_id, num_or_sections=sections)
metric_key = None
if evaler.eval_loss_func is None:
metric_dict = {metric_key: 0.}
else:
metric_dict = dict()
for block_idx, block_fea in enumerate(fea_blocks):
similarity_matrix = paddle.matmul(
block_fea, gallery_feas, transpose_y=True)
if query_query_id is not None:
query_id_block = query_id_blocks[block_idx]
query_id_mask = (query_id_block != gallery_unique_id.t())
image_id_block = image_id_blocks[block_idx]
image_id_mask = (image_id_block != gallery_img_id.t())
keep_mask = paddle.logical_or(query_id_mask, image_id_mask)
similarity_matrix = similarity_matrix * keep_mask.astype(
"float32")
else:
keep_mask = None
metric_tmp = evaler.eval_metric_func(similarity_matrix,
image_id_blocks[block_idx],
gallery_img_id, keep_mask)
for key in metric_tmp:
if key not in metric_dict:
metric_dict[key] = metric_tmp[key] * block_fea.shape[
0] / len(query_feas)
else:
metric_dict[key] += metric_tmp[key] * block_fea.shape[
0] / len(query_feas)
metric_info_list = []
for key in metric_dict:
if metric_key is None:
metric_key = key
metric_info_list.append("{}: {:.5f}".format(key, metric_dict[key]))
metric_msg = ", ".join(metric_info_list)
logger.info("[Eval][Epoch {}][Avg]{}".format(epoch_id, metric_msg))
return metric_dict[metric_key]
def cal_feature(evaler, name='gallery'):
all_feas = None
all_image_id = None
all_unique_id = None
has_unique_id = False
if name == 'gallery':
dataloader = evaler.gallery_dataloader
elif name == 'query':
dataloader = evaler.query_dataloader
else:
raise RuntimeError("Only support gallery or query dataset")
max_iter = len(dataloader) - 1 if platform.system() == "Windows" else len(
dataloader)
dataloader_tmp = dataloader if evaler.use_dali else dataloader()
for idx, batch in enumerate(dataloader_tmp): # load is very time-consuming
if idx >= max_iter:
break
if idx % evaler.config["Global"]["print_batch_step"] == 0:
logger.info(
f"{name} feature calculation process: [{idx}/{len(dataloader)}]"
)
if evaler.use_dali:
batch = [
paddle.to_tensor(batch[0]['data']),
paddle.to_tensor(batch[0]['label'])
]
batch = [paddle.to_tensor(x) for x in batch]
batch[1] = batch[1].reshape([-1, 1]).astype("int64")
if len(batch) == 3:
has_unique_id = True
batch[2] = batch[2].reshape([-1, 1]).astype("int64")
out = evaler.model(batch[0], batch[1])
batch_feas = out["features"]
# do norm
if evaler.config["Global"].get("feature_normalize", True):
feas_norm = paddle.sqrt(
paddle.sum(paddle.square(batch_feas), axis=1, keepdim=True))
batch_feas = paddle.divide(batch_feas, feas_norm)
# do binarize
if evaler.config["Global"].get("feature_binarize") == "round":
batch_feas = paddle.round(batch_feas).astype("float32") * 2.0 - 1.0
if evaler.config["Global"].get("feature_binarize") == "sign":
batch_feas = paddle.sign(batch_feas).astype("float32")
if all_feas is None:
all_feas = batch_feas
if has_unique_id:
all_unique_id = batch[2]
all_image_id = batch[1]
else:
all_feas = paddle.concat([all_feas, batch_feas])
all_image_id = paddle.concat([all_image_id, batch[1]])
if has_unique_id:
all_unique_id = paddle.concat([all_unique_id, batch[2]])
if evaler.use_dali:
dataloader_tmp.reset()
if paddle.distributed.get_world_size() > 1:
feat_list = []
img_id_list = []
unique_id_list = []
paddle.distributed.all_gather(feat_list, all_feas)
paddle.distributed.all_gather(img_id_list, all_image_id)
all_feas = paddle.concat(feat_list, axis=0)
all_image_id = paddle.concat(img_id_list, axis=0)
if has_unique_id:
paddle.distributed.all_gather(unique_id_list, all_unique_id)
all_unique_id = paddle.concat(unique_id_list, axis=0)
logger.info("Build {} done, all feat shape: {}, begin to eval..".format(
name, all_feas.shape))
return all_feas, all_image_id, all_unique_id
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# 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.
from ppcls.engine.train.train import train_epoch
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# 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.
from __future__ import absolute_import, division, print_function
import time
import paddle
from ppcls.engine.train.utils import update_loss, update_metric, log_info
def train_epoch(trainer, epoch_id, print_batch_step):
tic = time.time()
train_dataloader = trainer.train_dataloader if trainer.use_dali else trainer.train_dataloader(
)
for iter_id, batch in enumerate(train_dataloader):
if iter_id >= trainer.max_iter:
break
if iter_id == 5:
for key in trainer.time_info:
trainer.time_info[key].reset()
trainer.time_info["reader_cost"].update(time.time() - tic)
if trainer.use_dali:
batch = [
paddle.to_tensor(batch[0]['data']),
paddle.to_tensor(batch[0]['label'])
]
batch_size = batch[0].shape[0]
batch[1] = batch[1].reshape([-1, 1]).astype("int64")
trainer.global_step += 1
# image input
if trainer.amp:
with paddle.amp.auto_cast(custom_black_list={
"flatten_contiguous_range", "greater_than"
}):
out = forward(trainer, batch)
loss_dict = trainer.train_loss_func(out, batch[1])
else:
out = forward(trainer, batch)
# calc loss
if trainer.config["DataLoader"]["Train"]["dataset"].get(
"batch_transform_ops", None):
loss_dict = trainer.train_loss_func(out, batch[1:])
else:
loss_dict = trainer.train_loss_func(out, batch[1])
# step opt and lr
if trainer.amp:
scaled = trainer.scaler.scale(loss_dict["loss"])
scaled.backward()
trainer.scaler.minimize(trainer.optimizer, scaled)
else:
loss_dict["loss"].backward()
trainer.optimizer.step()
trainer.optimizer.clear_grad()
trainer.lr_sch.step()
# below code just for logging
# update metric_for_logger
update_metric(trainer, out, batch, batch_size)
# update_loss_for_logger
update_loss(trainer, loss_dict, batch_size)
trainer.time_info["batch_cost"].update(time.time() - tic)
if iter_id % print_batch_step == 0:
log_info(trainer, batch_size, epoch_id, iter_id)
tic = time.time()
def forward(trainer, batch):
if trainer.eval_mode == "classification":
return trainer.model(batch[0])
else:
return trainer.model(batch[0], batch[1])
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# 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.
from __future__ import absolute_import, division, print_function
import datetime
from ppcls.utils import logger
from ppcls.utils.misc import AverageMeter
def update_metric(trainer, out, batch, batch_size):
# calc metric
if trainer.train_metric_func is not None:
metric_dict = trainer.train_metric_func(out, batch[-1])
for key in metric_dict:
if key not in trainer.output_info:
trainer.output_info[key] = AverageMeter(key, '7.5f')
trainer.output_info[key].update(metric_dict[key].numpy()[0],
batch_size)
def update_loss(trainer, loss_dict, batch_size):
# update_output_info
for key in loss_dict:
if key not in trainer.output_info:
trainer.output_info[key] = AverageMeter(key, '7.5f')
trainer.output_info[key].update(loss_dict[key].numpy()[0], batch_size)
def log_info(trainer, batch_size, epoch_id, iter_id):
lr_msg = "lr: {:.5f}".format(trainer.lr_sch.get_lr())
metric_msg = ", ".join([
"{}: {:.5f}".format(key, trainer.output_info[key].avg)
for key in trainer.output_info
])
time_msg = "s, ".join([
"{}: {:.5f}".format(key, trainer.time_info[key].avg)
for key in trainer.time_info
])
ips_msg = "ips: {:.5f} images/sec".format(
batch_size / trainer.time_info["batch_cost"].avg)
eta_sec = ((trainer.config["Global"]["epochs"] - epoch_id + 1
) * len(trainer.train_dataloader) - iter_id
) * trainer.time_info["batch_cost"].avg
eta_msg = "eta: {:s}".format(str(datetime.timedelta(seconds=int(eta_sec))))
logger.info("[Train][Epoch {}/{}][Iter: {}/{}]{}, {}, {}, {}, {}".format(
epoch_id, trainer.config["Global"]["epochs"], iter_id,
len(trainer.train_dataloader), lr_msg, metric_msg, time_msg, ips_msg,
eta_msg))
logger.scaler(
name="lr",
value=trainer.lr_sch.get_lr(),
step=trainer.global_step,
writer=trainer.vdl_writer)
for key in trainer.output_info:
logger.scaler(
name="train_{}".format(key),
value=trainer.output_info[key].avg,
step=trainer.global_step,
writer=trainer.vdl_writer)
#copyright (c) 2021 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 paddle
import paddle.nn as nn
class DSHSDLoss(nn.Layer):
"""
# DSHSD(IEEE ACCESS 2019)
# paper [Deep Supervised Hashing Based on Stable Distribution](https://ieeexplore.ieee.org/document/8648432/)
# [DSHSD] epoch:70, bit:48, dataset:cifar10-1, MAP:0.809, Best MAP: 0.809
# [DSHSD] epoch:250, bit:48, dataset:nuswide_21, MAP:0.809, Best MAP: 0.815
# [DSHSD] epoch:135, bit:48, dataset:imagenet, MAP:0.647, Best MAP: 0.647
"""
def __init__(self, n_class, bit, alpha, multi_label=False):
super(DSHSDLoss, self).__init__()
self.m = 2 * bit
self.alpha = alpha
self.multi_label = multi_label
self.n_class = n_class
self.fc = paddle.nn.Linear(bit, n_class, bias_attr=False)
def forward(self, input, label):
feature = input["features"]
feature = feature.tanh().astype("float32")
dist = paddle.sum(
paddle.square((paddle.unsqueeze(feature, 1) - paddle.unsqueeze(feature, 0))),
axis=2)
# label to ont-hot
label = paddle.flatten(label)
label = paddle.nn.functional.one_hot(label, self.n_class).astype("float32")
s = (paddle.matmul(label, label, transpose_y=True) == 0).astype("float32")
Ld = (1 - s) / 2 * dist + s / 2 * (self.m - dist).clip(min=0)
Ld = Ld.mean()
logits = self.fc(feature)
if self.multi_label:
# multiple labels classification loss
Lc = (logits - label * logits + ((1 + (-logits).exp()).log())).sum(axis=1).mean()
else:
# single labels classification loss
Lc = (-paddle.nn.functional.softmax(logits).log() * label).sum(axis=1).mean()
return {"dshsdloss": Lc + Ld * self.alpha}
class LCDSHLoss(nn.Layer):
"""
# paper [Locality-Constrained Deep Supervised Hashing for Image Retrieval](https://www.ijcai.org/Proceedings/2017/0499.pdf)
# [LCDSH] epoch:145, bit:48, dataset:cifar10-1, MAP:0.798, Best MAP: 0.798
# [LCDSH] epoch:183, bit:48, dataset:nuswide_21, MAP:0.833, Best MAP: 0.834
"""
def __init__(self, n_class, _lambda):
super(LCDSHLoss, self).__init__()
self._lambda = _lambda
self.n_class = n_class
def forward(self, input, label):
feature = input["features"]
# label to ont-hot
label = paddle.flatten(label)
label = paddle.nn.functional.one_hot(label, self.n_class).astype("float32")
s = 2 * (paddle.matmul(label, label, transpose_y=True) > 0).astype("float32") - 1
inner_product = paddle.matmul(feature, feature, transpose_y=True) * 0.5
inner_product = inner_product.clip(min=-50, max=50)
L1 = paddle.log(1 + paddle.exp(-s * inner_product)).mean()
b = feature.sign()
inner_product_ = paddle.matmul(b, b, transpose_y=True) * 0.5
sigmoid = paddle.nn.Sigmoid()
L2 = (sigmoid(inner_product) - sigmoid(inner_product_)).pow(2).mean()
return {"lcdshloss": L1 + self._lambda * L2}
...@@ -16,7 +16,7 @@ from paddle import nn ...@@ -16,7 +16,7 @@ from paddle import nn
import copy import copy
from collections import OrderedDict from collections import OrderedDict
from .metrics import TopkAcc, mAP, mINP, Recallk from .metrics import TopkAcc, mAP, mINP, Recallk, Precisionk
from .metrics import DistillationTopkAcc from .metrics import DistillationTopkAcc
from .metrics import GoogLeNetTopkAcc from .metrics import GoogLeNetTopkAcc
......
...@@ -168,6 +168,47 @@ class Recallk(nn.Layer): ...@@ -168,6 +168,47 @@ class Recallk(nn.Layer):
return metric_dict return metric_dict
class Precisionk(nn.Layer):
def __init__(self, topk=(1, 5)):
super().__init__()
assert isinstance(topk, (int, list, tuple))
if isinstance(topk, int):
topk = [topk]
self.topk = topk
def forward(self, similarities_matrix, query_img_id, gallery_img_id,
keep_mask):
metric_dict = dict()
#get cmc
choosen_indices = paddle.argsort(
similarities_matrix, axis=1, descending=True)
gallery_labels_transpose = paddle.transpose(gallery_img_id, [1, 0])
gallery_labels_transpose = paddle.broadcast_to(
gallery_labels_transpose,
shape=[
choosen_indices.shape[0], gallery_labels_transpose.shape[1]
])
choosen_label = paddle.index_sample(gallery_labels_transpose,
choosen_indices)
equal_flag = paddle.equal(choosen_label, query_img_id)
if keep_mask is not None:
keep_mask = paddle.index_sample(
keep_mask.astype('float32'), choosen_indices)
equal_flag = paddle.logical_and(equal_flag,
keep_mask.astype('bool'))
equal_flag = paddle.cast(equal_flag, 'float32')
Ns = paddle.arange(gallery_img_id.shape[0]) + 1
equal_flag_cumsum = paddle.cumsum(equal_flag, axis=1)
Precision_at_k = (paddle.mean(equal_flag_cumsum, axis=0) / Ns).numpy()
for k in self.topk:
metric_dict["precision@{}".format(k)] = Precision_at_k[k - 1]
return metric_dict
class DistillationTopkAcc(TopkAcc): class DistillationTopkAcc(TopkAcc):
def __init__(self, model_key, feature_key=None, topk=(1, 5)): def __init__(self, model_key, feature_key=None, topk=(1, 5)):
super().__init__(topk=topk) super().__init__(topk=topk)
......
...@@ -21,11 +21,11 @@ __dir__ = os.path.dirname(os.path.abspath(__file__)) ...@@ -21,11 +21,11 @@ __dir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.abspath(os.path.join(__dir__, '../'))) sys.path.append(os.path.abspath(os.path.join(__dir__, '../')))
from ppcls.utils import config from ppcls.utils import config
from ppcls.engine.trainer import Trainer from ppcls.engine.engine import Engine
if __name__ == "__main__": if __name__ == "__main__":
args = config.parse_args() args = config.parse_args()
config = config.get_config( config = config.get_config(
args.config, overrides=args.override, show=False) args.config, overrides=args.override, show=False)
trainer = Trainer(config, mode="eval") engine = Engine(config, mode="eval")
trainer.eval() engine.eval()
...@@ -24,82 +24,11 @@ import paddle ...@@ -24,82 +24,11 @@ import paddle
import paddle.nn as nn import paddle.nn as nn
from ppcls.utils import config from ppcls.utils import config
from ppcls.utils.logger import init_logger from ppcls.engine.engine import Engine
from ppcls.utils.config import print_config
from ppcls.arch import build_model, RecModel, DistillationModel
from ppcls.utils.save_load import load_dygraph_pretrain
from ppcls.arch.gears.identity_head import IdentityHead
class ExportModel(nn.Layer):
"""
ExportModel: add softmax onto the model
"""
def __init__(self, config):
super().__init__()
self.base_model = build_model(config)
# we should choose a final model to export
if isinstance(self.base_model, DistillationModel):
self.infer_model_name = config["infer_model_name"]
else:
self.infer_model_name = None
self.infer_output_key = config.get("infer_output_key", None)
if self.infer_output_key == "features" and isinstance(self.base_model,
RecModel):
self.base_model.head = IdentityHead()
if config.get("infer_add_softmax", True):
self.softmax = nn.Softmax(axis=-1)
else:
self.softmax = None
def eval(self):
self.training = False
for layer in self.sublayers():
layer.training = False
layer.eval()
def forward(self, x):
x = self.base_model(x)
if isinstance(x, list):
x = x[0]
if self.infer_model_name is not None:
x = x[self.infer_model_name]
if self.infer_output_key is not None:
x = x[self.infer_output_key]
if self.softmax is not None:
x = self.softmax(x)
return x
if __name__ == "__main__": if __name__ == "__main__":
args = config.parse_args() args = config.parse_args()
config = config.get_config( config = config.get_config(
args.config, overrides=args.override, show=False) args.config, overrides=args.override, show=False)
log_file = os.path.join(config['Global']['output_dir'], engine = Engine(config, mode="export")
config["Arch"]["name"], "export.log") engine.export()
init_logger(name='root', log_file=log_file)
print_config(config)
# set device
assert config["Global"]["device"] in ["cpu", "gpu", "xpu"]
device = paddle.set_device(config["Global"]["device"])
model = ExportModel(config["Arch"])
if config["Global"]["pretrained_model"] is not None:
load_dygraph_pretrain(model.base_model,
config["Global"]["pretrained_model"])
model.eval()
model = paddle.jit.to_static(
model,
input_spec=[
paddle.static.InputSpec(
shape=[None] + config["Global"]["image_shape"],
dtype='float32')
])
paddle.jit.save(model,
os.path.join(config["Global"]["save_inference_dir"],
"inference"))
...@@ -21,12 +21,11 @@ __dir__ = os.path.dirname(os.path.abspath(__file__)) ...@@ -21,12 +21,11 @@ __dir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.abspath(os.path.join(__dir__, '../'))) sys.path.append(os.path.abspath(os.path.join(__dir__, '../')))
from ppcls.utils import config from ppcls.utils import config
from ppcls.engine.trainer import Trainer from ppcls.engine.engine import Engine
if __name__ == "__main__": if __name__ == "__main__":
args = config.parse_args() args = config.parse_args()
config = config.get_config( config = config.get_config(
args.config, overrides=args.override, show=False) args.config, overrides=args.override, show=False)
trainer = Trainer(config, mode="infer") engine = Engine(config, mode="infer")
engine.infer()
trainer.infer()
...@@ -21,11 +21,11 @@ __dir__ = os.path.dirname(os.path.abspath(__file__)) ...@@ -21,11 +21,11 @@ __dir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.abspath(os.path.join(__dir__, '../'))) sys.path.append(os.path.abspath(os.path.join(__dir__, '../')))
from ppcls.utils import config from ppcls.utils import config
from ppcls.engine.trainer import Trainer from ppcls.engine.engine import Engine
if __name__ == "__main__": if __name__ == "__main__":
args = config.parse_args() args = config.parse_args()
config = config.get_config( config = config.get_config(
args.config, overrides=args.override, show=False) args.config, overrides=args.override, show=False)
trainer = Trainer(config, mode="train") engine = Engine(config, mode="train")
trainer.train() engine.train()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册