From 7153ee1129590fe5aa873e67168519784da7abbb Mon Sep 17 00:00:00 2001 From: littletomatodonkey Date: Wed, 21 Oct 2020 09:21:22 +0000 Subject: [PATCH] fix quick start code and doc --- docs/en/tutorials/quick_start_en.md | 29 ++++++------- docs/zh_CN/tutorials/install.md | 2 +- docs/zh_CN/tutorials/quick_start.md | 28 ++++++------- ppcls/modeling/architectures/resnet_vd.py | 51 ++++++++++++++++------- ppcls/modeling/loss.py | 7 ++-- 5 files changed, 67 insertions(+), 50 deletions(-) diff --git a/docs/en/tutorials/quick_start_en.md b/docs/en/tutorials/quick_start_en.md index 746d2c51..7d7b6a11 100644 --- a/docs/en/tutorials/quick_start_en.md +++ b/docs/en/tutorials/quick_start_en.md @@ -40,33 +40,28 @@ cd ../../ ## Environment -### Set PYTHONPATH - -```bash -export PYTHONPATH=./:$PYTHONPATH -``` - ### Download pretrained model +You can use the following commands to downdload the pretrained models. ```bash -python tools/download.py -a ResNet50_vd -p ./pretrained -d True -python tools/download.py -a ResNet50_vd_ssld -p ./pretrained -d True -python tools/download.py -a MobileNetV3_large_x1_0 -p ./pretrained -d True +mkdir pretrained +cd pretrained +wget https://paddle-imagenet-models-name.bj.bcebos.com/ResNet50_vd_pretrained.tar +wget https://paddle-imagenet-models-name.bj.bcebos.com/ResNet50_vd_ssld_pretrained.tar +wget https://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV3_large_x1_0_pretrained.tar +tar -xf ResNet50_vd_pretrained.tar +tar -xf ResNet50_vd_ssld_pretrained.tar +tar -xf MobileNetV3_large_x1_0_pretrained.tar +cd ../ ``` -Paramters: -+ `architecture`(shortname: a): model name. -+ `path`(shortname: p) download path. -+ `decompress`(shortname: d) whether to decompress. - +**Note**: If you want to download the pretrained models on Windows environment, you can copy the links to the web page and download, you can use the the thirdparty tools such as `7Zip` to uncompress the tar files. +## Training * All experiments are running on the NVIDIA® Tesla® V100 sigle card. - -## Training - ### Train from scratch * Train ResNet50_vd diff --git a/docs/zh_CN/tutorials/install.md b/docs/zh_CN/tutorials/install.md index 449b8238..87505ecb 100644 --- a/docs/zh_CN/tutorials/install.md +++ b/docs/zh_CN/tutorials/install.md @@ -9,7 +9,7 @@ ## 二、安装PaddlePaddle -运行PaddleClas需要PaddlePaddle Fluid v1.7或更高版本。请参照[安装文档](http://www.paddlepaddle.org.cn/install/quick)中的说明进行操作。 +运行PaddleClas需要`PaddlePaddle 2.0-beta`或更高版本。请参照[安装文档](http://www.paddlepaddle.org.cn/install/quick)中的说明进行操作。 如果已经安装好了cuda、cudnn、nccl或者安装好了docker、nvidia-docker运行环境,可以pip安装最新GPU版本PaddlePaddle diff --git a/docs/zh_CN/tutorials/quick_start.md b/docs/zh_CN/tutorials/quick_start.md index 63c391c8..37358469 100644 --- a/docs/zh_CN/tutorials/quick_start.md +++ b/docs/zh_CN/tutorials/quick_start.md @@ -40,25 +40,23 @@ cd ../../ ## 二、环境准备 -### 2.1 设置PYTHONPATH环境变量 +### 2.1 下载预训练模型 -```bash -export PYTHONPATH=./:$PYTHONPATH -``` - -### 下载预训练模型 -通过tools/download.py下载所需要的预训练模型。 +通过下面的命令下载所需要的预训练模型。 ```bash -python tools/download.py -a ResNet50_vd -p ./pretrained -d True -python tools/download.py -a ResNet50_vd_ssld -p ./pretrained -d True -python tools/download.py -a MobileNetV3_large_x1_0 -p ./pretrained -d True +mkdir pretrained +cd pretrained +wget https://paddle-imagenet-models-name.bj.bcebos.com/ResNet50_vd_pretrained.tar +wget https://paddle-imagenet-models-name.bj.bcebos.com/ResNet50_vd_ssld_pretrained.tar +wget https://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV3_large_x1_0_pretrained.tar +tar -xf ResNet50_vd_pretrained.tar +tar -xf ResNet50_vd_ssld_pretrained.tar +tar -xf MobileNetV3_large_x1_0_pretrained.tar +cd ../ ``` -参数说明: -+ `architecture`(简写 a):模型结构 -+ `path`(简写 p):下载路径 -+ `decompress` (简写 d):是否解压 +**注意**:如果是在windows中下载预训练模型的话,需要把地址拷贝到网页中并下载,同时使用`7Zip`等工具进行解压。 ### 2.2 环境说明 @@ -161,7 +159,7 @@ python -m paddle.distributed.launch \ * 如果希望体验`3.6节`的知识蒸馏部分,可以首先保存训练得到的ResNet50_vd预训练模型到合适的位置,作为蒸馏时教师模型的预训练模型。脚本如下所示。 ```shell -cp -r output/ResNet50_vd/19/ ./pretrained/flowers102_R50_vd_final/ +cp -r output/ResNet50_vd/best_model/ ./pretrained/flowers102_R50_vd_final/ ``` ### 3.6 知识蒸馏小试牛刀 diff --git a/ppcls/modeling/architectures/resnet_vd.py b/ppcls/modeling/architectures/resnet_vd.py index e40ec7d0..00a6c013 100644 --- a/ppcls/modeling/architectures/resnet_vd.py +++ b/ppcls/modeling/architectures/resnet_vd.py @@ -32,18 +32,17 @@ __all__ = [ class ConvBNLayer(nn.Layer): - def __init__( - self, - num_channels, - num_filters, - filter_size, - stride=1, - groups=1, - is_vd_mode=False, - act=None, - name=None, ): + def __init__(self, + num_channels, + num_filters, + filter_size, + stride=1, + groups=1, + is_vd_mode=False, + act=None, + lr_mult=1.0, + name=None): super(ConvBNLayer, self).__init__() - self.is_vd_mode = is_vd_mode self._pool2d_avg = AvgPool2d( kernel_size=2, stride=2, padding=0, ceil_mode=True) @@ -54,7 +53,8 @@ class ConvBNLayer(nn.Layer): stride=stride, padding=(filter_size - 1) // 2, groups=groups, - weight_attr=ParamAttr(name=name + "_weights"), + weight_attr=ParamAttr( + name=name + "_weights", learning_rate=lr_mult), bias_attr=False) if name == "conv1": bn_name = "bn_" + name @@ -83,6 +83,7 @@ class BottleneckBlock(nn.Layer): stride, shortcut=True, if_first=False, + lr_mult=1.0, name=None): super(BottleneckBlock, self).__init__() @@ -91,6 +92,7 @@ class BottleneckBlock(nn.Layer): num_filters=num_filters, filter_size=1, act='relu', + lr_mult=lr_mult, name=name + "_branch2a") self.conv1 = ConvBNLayer( num_channels=num_filters, @@ -98,12 +100,14 @@ class BottleneckBlock(nn.Layer): filter_size=3, stride=stride, act='relu', + lr_mult=lr_mult, name=name + "_branch2b") self.conv2 = ConvBNLayer( num_channels=num_filters, num_filters=num_filters * 4, filter_size=1, act=None, + lr_mult=lr_mult, name=name + "_branch2c") if not shortcut: @@ -137,6 +141,7 @@ class BasicBlock(nn.Layer): stride, shortcut=True, if_first=False, + lr_mult=1.0, name=None): super(BasicBlock, self).__init__() self.stride = stride @@ -178,7 +183,10 @@ class BasicBlock(nn.Layer): class ResNet_vd(nn.Layer): - def __init__(self, layers=50, class_dim=1000): + def __init__(self, + layers=50, + class_dim=1000, + lr_mult_list=[1.0, 1.0, 1.0, 1.0, 1.0]): super(ResNet_vd, self).__init__() self.layers = layers @@ -187,6 +195,16 @@ class ResNet_vd(nn.Layer): "supported layers are {} but input layer is {}".format( supported_layers, layers) + self.lr_mult_list = lr_mult_list + assert isinstance(self.lr_mult_list, ( + list, tuple + )), "lr_mult_list should be in (list, tuple) but got {}".format( + type(self.lr_mult_list)) + assert len( + self.lr_mult_list + ) == 5, "lr_mult_list length should should be 5 but got {}".format( + len(self.lr_mult_list)) + if layers == 18: depth = [2, 2, 2, 2] elif layers == 34 or layers == 50: @@ -207,6 +225,7 @@ class ResNet_vd(nn.Layer): filter_size=3, stride=2, act='relu', + lr_mult=self.lr_mult_list[0], name="conv1_1") self.conv1_2 = ConvBNLayer( num_channels=32, @@ -214,6 +233,7 @@ class ResNet_vd(nn.Layer): filter_size=3, stride=1, act='relu', + lr_mult=self.lr_mult_list[0], name="conv1_2") self.conv1_3 = ConvBNLayer( num_channels=32, @@ -221,6 +241,7 @@ class ResNet_vd(nn.Layer): filter_size=3, stride=1, act='relu', + lr_mult=self.lr_mult_list[0], name="conv1_3") self.pool2d_max = MaxPool2d(kernel_size=3, stride=2, padding=1) @@ -245,6 +266,7 @@ class ResNet_vd(nn.Layer): stride=2 if i == 0 and block != 0 else 1, shortcut=shortcut, if_first=block == i == 0, + lr_mult=self.lr_mult_list[block + 1], name=conv_name)) self.block_list.append(bottleneck_block) shortcut = True @@ -262,7 +284,8 @@ class ResNet_vd(nn.Layer): stride=2 if i == 0 and block != 0 else 1, shortcut=shortcut, if_first=block == i == 0, - name=conv_name)) + name=conv_name, + lr_mult=lr_mult)) self.block_list.append(basic_block) shortcut = True diff --git a/ppcls/modeling/loss.py b/ppcls/modeling/loss.py index 0b705df4..c9c2c685 100644 --- a/ppcls/modeling/loss.py +++ b/ppcls/modeling/loss.py @@ -53,9 +53,10 @@ class Loss(object): avg_cost = paddle.mean(cost) return avg_cost - def _kldiv(self, input, target): - cost = target * F.log(target / input) * self._class_dim - cost = paddle.sum(cost) + def _kldiv(self, input, target, name=None): + eps = 1.0e-10 + cost = target * paddle.log( + (target + eps) / (input + eps)) * self._class_dim return cost def _jsdiv(self, input, target): -- GitLab