fix quick start code and doc
parent
7592654c6b
commit
7153ee1129
|
@ -40,33 +40,28 @@ cd ../../
|
||||||
|
|
||||||
## Environment
|
## Environment
|
||||||
|
|
||||||
### Set PYTHONPATH
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export PYTHONPATH=./:$PYTHONPATH
|
|
||||||
```
|
|
||||||
|
|
||||||
### Download pretrained model
|
### Download pretrained model
|
||||||
|
|
||||||
|
You can use the following commands to downdload the pretrained models.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python tools/download.py -a ResNet50_vd -p ./pretrained -d True
|
mkdir pretrained
|
||||||
python tools/download.py -a ResNet50_vd_ssld -p ./pretrained -d True
|
cd pretrained
|
||||||
python tools/download.py -a MobileNetV3_large_x1_0 -p ./pretrained -d True
|
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:
|
**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.
|
||||||
+ `architecture`(shortname: a): model name.
|
|
||||||
+ `path`(shortname: p) download path.
|
|
||||||
+ `decompress`(shortname: d) whether to decompress.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* All experiments are running on the NVIDIA® Tesla® V100 sigle card.
|
|
||||||
|
|
||||||
|
|
||||||
## Training
|
## Training
|
||||||
|
|
||||||
|
* All experiments are running on the NVIDIA® Tesla® V100 sigle card.
|
||||||
|
|
||||||
### Train from scratch
|
### Train from scratch
|
||||||
|
|
||||||
* Train ResNet50_vd
|
* Train ResNet50_vd
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## 二、安装PaddlePaddle
|
## 二、安装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
|
如果已经安装好了cuda、cudnn、nccl或者安装好了docker、nvidia-docker运行环境,可以pip安装最新GPU版本PaddlePaddle
|
||||||
|
|
||||||
|
|
|
@ -40,25 +40,23 @@ cd ../../
|
||||||
|
|
||||||
## 二、环境准备
|
## 二、环境准备
|
||||||
|
|
||||||
### 2.1 设置PYTHONPATH环境变量
|
### 2.1 下载预训练模型
|
||||||
|
|
||||||
|
通过下面的命令下载所需要的预训练模型。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export PYTHONPATH=./:$PYTHONPATH
|
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 ../
|
||||||
```
|
```
|
||||||
|
|
||||||
### 下载预训练模型
|
**注意**:如果是在windows中下载预训练模型的话,需要把地址拷贝到网页中并下载,同时使用`7Zip`等工具进行解压。
|
||||||
通过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
|
|
||||||
```
|
|
||||||
|
|
||||||
参数说明:
|
|
||||||
+ `architecture`(简写 a):模型结构
|
|
||||||
+ `path`(简写 p):下载路径
|
|
||||||
+ `decompress` (简写 d):是否解压
|
|
||||||
|
|
||||||
### 2.2 环境说明
|
### 2.2 环境说明
|
||||||
|
|
||||||
|
@ -161,7 +159,7 @@ python -m paddle.distributed.launch \
|
||||||
* 如果希望体验`3.6节`的知识蒸馏部分,可以首先保存训练得到的ResNet50_vd预训练模型到合适的位置,作为蒸馏时教师模型的预训练模型。脚本如下所示。
|
* 如果希望体验`3.6节`的知识蒸馏部分,可以首先保存训练得到的ResNet50_vd预训练模型到合适的位置,作为蒸馏时教师模型的预训练模型。脚本如下所示。
|
||||||
|
|
||||||
```shell
|
```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 知识蒸馏小试牛刀
|
### 3.6 知识蒸馏小试牛刀
|
||||||
|
|
|
@ -32,18 +32,17 @@ __all__ = [
|
||||||
|
|
||||||
|
|
||||||
class ConvBNLayer(nn.Layer):
|
class ConvBNLayer(nn.Layer):
|
||||||
def __init__(
|
def __init__(self,
|
||||||
self,
|
num_channels,
|
||||||
num_channels,
|
num_filters,
|
||||||
num_filters,
|
filter_size,
|
||||||
filter_size,
|
stride=1,
|
||||||
stride=1,
|
groups=1,
|
||||||
groups=1,
|
is_vd_mode=False,
|
||||||
is_vd_mode=False,
|
act=None,
|
||||||
act=None,
|
lr_mult=1.0,
|
||||||
name=None, ):
|
name=None):
|
||||||
super(ConvBNLayer, self).__init__()
|
super(ConvBNLayer, self).__init__()
|
||||||
|
|
||||||
self.is_vd_mode = is_vd_mode
|
self.is_vd_mode = is_vd_mode
|
||||||
self._pool2d_avg = AvgPool2d(
|
self._pool2d_avg = AvgPool2d(
|
||||||
kernel_size=2, stride=2, padding=0, ceil_mode=True)
|
kernel_size=2, stride=2, padding=0, ceil_mode=True)
|
||||||
|
@ -54,7 +53,8 @@ class ConvBNLayer(nn.Layer):
|
||||||
stride=stride,
|
stride=stride,
|
||||||
padding=(filter_size - 1) // 2,
|
padding=(filter_size - 1) // 2,
|
||||||
groups=groups,
|
groups=groups,
|
||||||
weight_attr=ParamAttr(name=name + "_weights"),
|
weight_attr=ParamAttr(
|
||||||
|
name=name + "_weights", learning_rate=lr_mult),
|
||||||
bias_attr=False)
|
bias_attr=False)
|
||||||
if name == "conv1":
|
if name == "conv1":
|
||||||
bn_name = "bn_" + name
|
bn_name = "bn_" + name
|
||||||
|
@ -83,6 +83,7 @@ class BottleneckBlock(nn.Layer):
|
||||||
stride,
|
stride,
|
||||||
shortcut=True,
|
shortcut=True,
|
||||||
if_first=False,
|
if_first=False,
|
||||||
|
lr_mult=1.0,
|
||||||
name=None):
|
name=None):
|
||||||
super(BottleneckBlock, self).__init__()
|
super(BottleneckBlock, self).__init__()
|
||||||
|
|
||||||
|
@ -91,6 +92,7 @@ class BottleneckBlock(nn.Layer):
|
||||||
num_filters=num_filters,
|
num_filters=num_filters,
|
||||||
filter_size=1,
|
filter_size=1,
|
||||||
act='relu',
|
act='relu',
|
||||||
|
lr_mult=lr_mult,
|
||||||
name=name + "_branch2a")
|
name=name + "_branch2a")
|
||||||
self.conv1 = ConvBNLayer(
|
self.conv1 = ConvBNLayer(
|
||||||
num_channels=num_filters,
|
num_channels=num_filters,
|
||||||
|
@ -98,12 +100,14 @@ class BottleneckBlock(nn.Layer):
|
||||||
filter_size=3,
|
filter_size=3,
|
||||||
stride=stride,
|
stride=stride,
|
||||||
act='relu',
|
act='relu',
|
||||||
|
lr_mult=lr_mult,
|
||||||
name=name + "_branch2b")
|
name=name + "_branch2b")
|
||||||
self.conv2 = ConvBNLayer(
|
self.conv2 = ConvBNLayer(
|
||||||
num_channels=num_filters,
|
num_channels=num_filters,
|
||||||
num_filters=num_filters * 4,
|
num_filters=num_filters * 4,
|
||||||
filter_size=1,
|
filter_size=1,
|
||||||
act=None,
|
act=None,
|
||||||
|
lr_mult=lr_mult,
|
||||||
name=name + "_branch2c")
|
name=name + "_branch2c")
|
||||||
|
|
||||||
if not shortcut:
|
if not shortcut:
|
||||||
|
@ -137,6 +141,7 @@ class BasicBlock(nn.Layer):
|
||||||
stride,
|
stride,
|
||||||
shortcut=True,
|
shortcut=True,
|
||||||
if_first=False,
|
if_first=False,
|
||||||
|
lr_mult=1.0,
|
||||||
name=None):
|
name=None):
|
||||||
super(BasicBlock, self).__init__()
|
super(BasicBlock, self).__init__()
|
||||||
self.stride = stride
|
self.stride = stride
|
||||||
|
@ -178,7 +183,10 @@ class BasicBlock(nn.Layer):
|
||||||
|
|
||||||
|
|
||||||
class ResNet_vd(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__()
|
super(ResNet_vd, self).__init__()
|
||||||
|
|
||||||
self.layers = layers
|
self.layers = layers
|
||||||
|
@ -187,6 +195,16 @@ class ResNet_vd(nn.Layer):
|
||||||
"supported layers are {} but input layer is {}".format(
|
"supported layers are {} but input layer is {}".format(
|
||||||
supported_layers, layers)
|
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:
|
if layers == 18:
|
||||||
depth = [2, 2, 2, 2]
|
depth = [2, 2, 2, 2]
|
||||||
elif layers == 34 or layers == 50:
|
elif layers == 34 or layers == 50:
|
||||||
|
@ -207,6 +225,7 @@ class ResNet_vd(nn.Layer):
|
||||||
filter_size=3,
|
filter_size=3,
|
||||||
stride=2,
|
stride=2,
|
||||||
act='relu',
|
act='relu',
|
||||||
|
lr_mult=self.lr_mult_list[0],
|
||||||
name="conv1_1")
|
name="conv1_1")
|
||||||
self.conv1_2 = ConvBNLayer(
|
self.conv1_2 = ConvBNLayer(
|
||||||
num_channels=32,
|
num_channels=32,
|
||||||
|
@ -214,6 +233,7 @@ class ResNet_vd(nn.Layer):
|
||||||
filter_size=3,
|
filter_size=3,
|
||||||
stride=1,
|
stride=1,
|
||||||
act='relu',
|
act='relu',
|
||||||
|
lr_mult=self.lr_mult_list[0],
|
||||||
name="conv1_2")
|
name="conv1_2")
|
||||||
self.conv1_3 = ConvBNLayer(
|
self.conv1_3 = ConvBNLayer(
|
||||||
num_channels=32,
|
num_channels=32,
|
||||||
|
@ -221,6 +241,7 @@ class ResNet_vd(nn.Layer):
|
||||||
filter_size=3,
|
filter_size=3,
|
||||||
stride=1,
|
stride=1,
|
||||||
act='relu',
|
act='relu',
|
||||||
|
lr_mult=self.lr_mult_list[0],
|
||||||
name="conv1_3")
|
name="conv1_3")
|
||||||
self.pool2d_max = MaxPool2d(kernel_size=3, stride=2, padding=1)
|
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,
|
stride=2 if i == 0 and block != 0 else 1,
|
||||||
shortcut=shortcut,
|
shortcut=shortcut,
|
||||||
if_first=block == i == 0,
|
if_first=block == i == 0,
|
||||||
|
lr_mult=self.lr_mult_list[block + 1],
|
||||||
name=conv_name))
|
name=conv_name))
|
||||||
self.block_list.append(bottleneck_block)
|
self.block_list.append(bottleneck_block)
|
||||||
shortcut = True
|
shortcut = True
|
||||||
|
@ -262,7 +284,8 @@ class ResNet_vd(nn.Layer):
|
||||||
stride=2 if i == 0 and block != 0 else 1,
|
stride=2 if i == 0 and block != 0 else 1,
|
||||||
shortcut=shortcut,
|
shortcut=shortcut,
|
||||||
if_first=block == i == 0,
|
if_first=block == i == 0,
|
||||||
name=conv_name))
|
name=conv_name,
|
||||||
|
lr_mult=lr_mult))
|
||||||
self.block_list.append(basic_block)
|
self.block_list.append(basic_block)
|
||||||
shortcut = True
|
shortcut = True
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,10 @@ class Loss(object):
|
||||||
avg_cost = paddle.mean(cost)
|
avg_cost = paddle.mean(cost)
|
||||||
return avg_cost
|
return avg_cost
|
||||||
|
|
||||||
def _kldiv(self, input, target):
|
def _kldiv(self, input, target, name=None):
|
||||||
cost = target * F.log(target / input) * self._class_dim
|
eps = 1.0e-10
|
||||||
cost = paddle.sum(cost)
|
cost = target * paddle.log(
|
||||||
|
(target + eps) / (input + eps)) * self._class_dim
|
||||||
return cost
|
return cost
|
||||||
|
|
||||||
def _jsdiv(self, input, target):
|
def _jsdiv(self, input, target):
|
||||||
|
|
Loading…
Reference in New Issue