提交 dc1b032d 编写于 作者: R ruri 提交者: qingqing01

Refine Image Classification Codes&Docs (#1943)

* Move models to legacy, rename models_name to models, refine README
* Refine eval/infer/train code
* Release ResNet 18/34, GoogleNet and ShuffleNet v2.
* Add RMSProp optimizer.
上级 b610d165
...@@ -37,8 +37,6 @@ In the shell script ```download_imagenet2012.sh```, there are three steps to pr ...@@ -37,8 +37,6 @@ In the shell script ```download_imagenet2012.sh```, there are three steps to pr
train/n02483708/n02483708_2436.jpeg 369 train/n02483708/n02483708_2436.jpeg 369
train/n03998194/n03998194_7015.jpeg 741 train/n03998194/n03998194_7015.jpeg 741
train/n04523525/n04523525_38118.jpeg 884 train/n04523525/n04523525_38118.jpeg 884
train/n04596742/n04596742_3032.jpeg 909
train/n03208938/n03208938_7065.jpeg 535
... ...
``` ```
* *val_list.txt*: label file of imagenet-2012 validation set, with each line seperated by ```SPACE```, like. * *val_list.txt*: label file of imagenet-2012 validation set, with each line seperated by ```SPACE```, like.
...@@ -46,8 +44,6 @@ train/n03208938/n03208938_7065.jpeg 535 ...@@ -46,8 +44,6 @@ train/n03208938/n03208938_7065.jpeg 535
val/ILSVRC2012_val_00000001.jpeg 65 val/ILSVRC2012_val_00000001.jpeg 65
val/ILSVRC2012_val_00000002.jpeg 970 val/ILSVRC2012_val_00000002.jpeg 970
val/ILSVRC2012_val_00000003.jpeg 230 val/ILSVRC2012_val_00000003.jpeg 230
val/ILSVRC2012_val_00000004.jpeg 809
val/ILSVRC2012_val_00000005.jpeg 516
... ...
``` ```
...@@ -84,15 +80,14 @@ python train.py \ ...@@ -84,15 +80,14 @@ python train.py \
* **pretrained_model**: model path for pretraining. Default: None. * **pretrained_model**: model path for pretraining. Default: None.
* **checkpoint**: the checkpoint path to resume. Default: None. * **checkpoint**: the checkpoint path to resume. Default: None.
* **data_dir**: the data path. Default: "./data/ILSVRC2012". * **data_dir**: the data path. Default: "./data/ILSVRC2012".
* **model_category**: the category of models, ("models"|"models_name"). Default: "models_name". * **fp16**: whether to enable half precision training with fp16. Default: False.
* **fp16**: whether to enable half precisioin training with fp16. Default: False.
* **scale_loss**: scale loss for fp16. Default: 1.0. * **scale_loss**: scale loss for fp16. Default: 1.0.
* **l2_decay**: L2_decay parameter. Default: 1e-4. * **l2_decay**: L2_decay parameter. Default: 1e-4.
* **momentum_rate**: momentum_rate. Default: 0.9. * **momentum_rate**: momentum_rate. Default: 0.9.
Or can start the training step by running the ```run.sh```. Or can start the training step by running the ```run.sh```.
**data reader introduction:** Data reader is defined in ```reader.py``` and ```reader_cv2.py```, Using CV2 reader can improve the speed of reading. In [training stage](#training-a-model), random crop and flipping are used, while center crop is used in [evaluation](#inference) and [inference](#inference) stages. Supported data augmentation includes: **data reader introduction:** Data reader is defined in ```reader.py```and```reader_cv2.py```, Using CV2 reader can improve the speed of reading. In [training stage](#training-a-model-with-flexible-parameters), random crop and flipping are used, while center crop is used in [Evaluation](#evaluation) and [Inference](#inference) stages. Supported data augmentation includes:
* rotation * rotation
* color jitter * color jitter
* random crop * random crop
...@@ -100,32 +95,11 @@ Or can start the training step by running the ```run.sh```. ...@@ -100,32 +95,11 @@ Or can start the training step by running the ```run.sh```.
* resize * resize
* flipping * flipping
**training curve:** The training curve can be drawn based on training log. For example, the log from training AlexNet is like:
```
End pass 1, train_loss 6.23153877258, train_acc1 0.0150696625933, train_acc5 0.0552518665791, test_loss 5.41981744766, test_acc1 0.0519132651389, test_acc5 0.156150355935
End pass 2, train_loss 5.15442800522, train_acc1 0.0784279331565, train_acc5 0.211050540209, test_loss 4.45795249939, test_acc1 0.140469551086, test_acc5 0.333163291216
End pass 3, train_loss 4.51505613327, train_acc1 0.145300447941, train_acc5 0.331567406654, test_loss 3.86548018456, test_acc1 0.219443559647, test_acc5 0.446448504925
End pass 4, train_loss 4.12735557556, train_acc1 0.19437250495, train_acc5 0.405713528395, test_loss 3.56990146637, test_acc1 0.264536827803, test_acc5 0.507190704346
End pass 5, train_loss 3.87505435944, train_acc1 0.229518383741, train_acc5 0.453582793474, test_loss 3.35345435143, test_acc1 0.297349333763, test_acc5 0.54753267765
End pass 6, train_loss 3.6929500103, train_acc1 0.255628824234, train_acc5 0.487188398838, test_loss 3.17112898827, test_acc1 0.326953113079, test_acc5 0.581780135632
End pass 7, train_loss 3.55882954597, train_acc1 0.275381118059, train_acc5 0.511990904808, test_loss 3.03736782074, test_acc1 0.349035382271, test_acc5 0.606293857098
End pass 8, train_loss 3.45595097542, train_acc1 0.291462600231, train_acc5 0.530815005302, test_loss 2.96034455299, test_acc1 0.362228929996, test_acc5 0.617390751839
End pass 9, train_loss 3.3745200634, train_acc1 0.303871691227, train_acc5 0.545210540295, test_loss 2.93932366371, test_acc1 0.37129303813, test_acc5 0.623573005199
...
```
The error rate curves of AlexNet, ResNet50 and SE-ResNeXt-50 are shown in the figure below.
<p align="center">
<img src="images/curve.jpg" height=480 width=640 hspace='10'/> <br />
Training and validation Curves
</p>
## Using Mixed-Precision Training ## Using Mixed-Precision Training
You may add `--fp16 1` to start train using mixed precisioin training, which the training process will use float16 and the output model ("master" parameters) is saved as float32. You also may need to pass `--scale_loss` to overcome accuracy issues, usually `--scale_loss 8.0` will do. You may add `--fp16=1` to start train using mixed precisioin training, which the training process will use float16 and the output model ("master" parameters) is saved as float32. You also may need to pass `--scale_loss` to overcome accuracy issues, usually `--scale_loss=8.0` will do.
Note that currently `--fp16` can not use together with `--with_mem_opt`, so pass `--with_mem_opt 0` to disable memory optimization pass. Note that currently `--fp16` can not use together with `--with_mem_opt`, so pass `--with_mem_opt=0` to disable memory optimization pass.
## Finetuning ## Finetuning
...@@ -156,20 +130,6 @@ python eval.py \ ...@@ -156,20 +130,6 @@ python eval.py \
--pretrained_model=${path_to_pretrain_model} --pretrained_model=${path_to_pretrain_model}
``` ```
According to the congfiguration of evaluation, the output log is like:
```
Testbatch 0,loss 2.1786134243, acc1 0.625,acc5 0.8125,time 0.48 sec
Testbatch 10,loss 0.898496925831, acc1 0.75,acc5 0.9375,time 0.51 sec
Testbatch 20,loss 1.32524681091, acc1 0.6875,acc5 0.9375,time 0.37 sec
Testbatch 30,loss 1.46830511093, acc1 0.5,acc5 0.9375,time 0.51 sec
Testbatch 40,loss 1.12802267075, acc1 0.625,acc5 0.9375,time 0.35 sec
Testbatch 50,loss 0.881597697735, acc1 0.8125,acc5 1.0,time 0.32 sec
Testbatch 60,loss 0.300163716078, acc1 0.875,acc5 1.0,time 0.48 sec
Testbatch 70,loss 0.692037761211, acc1 0.875,acc5 1.0,time 0.35 sec
Testbatch 80,loss 0.0969972759485, acc1 1.0,acc5 1.0,time 0.41 sec
...
```
## Inference ## Inference
Inference is used to get prediction score or image features based on trained models. Inference is used to get prediction score or image features based on trained models.
``` ```
...@@ -180,30 +140,10 @@ python infer.py \ ...@@ -180,30 +140,10 @@ python infer.py \
--with_mem_opt=True \ --with_mem_opt=True \
--pretrained_model=${path_to_pretrain_model} --pretrained_model=${path_to_pretrain_model}
``` ```
The output contains predication results, including maximum score (before softmax) and corresponding predicted label.
```
Test-0-score: [13.168352], class [491]
Test-1-score: [7.913302], class [975]
Test-2-score: [16.959702], class [21]
Test-3-score: [14.197695], class [383]
Test-4-score: [12.607652], class [878]
Test-5-score: [17.725458], class [15]
Test-6-score: [12.678599], class [118]
Test-7-score: [12.353498], class [505]
Test-8-score: [20.828007], class [747]
Test-9-score: [15.135801], class [315]
Test-10-score: [14.585114], class [920]
Test-11-score: [13.739927], class [679]
Test-12-score: [15.040644], class [386]
...
```
## Supported models and performances ## Supported models and performances
Models consists of two categories: Models with specified parameters names in model definition and Models without specified parameters, Generate named model by indicating ```model_category = models_name```. Available top-1/top-5 validation accuracy on ImageNet 2012 are listed in table. Pretrained models can be downloaded by clicking related model names.
Models are trained by starting with learning rate ```0.1``` and decaying it by ```0.1``` after each pre-defined epoches, if not special introduced. Available top-1/top-5 validation accuracy on ImageNet 2012 are listed in table. Pretrained models can be downloaded by clicking related model names.
- Released models: specify parameter names - Released models: specify parameter names
...@@ -216,20 +156,12 @@ Models are trained by starting with learning rate ```0.1``` and decaying it by ` ...@@ -216,20 +156,12 @@ Models are trained by starting with learning rate ```0.1``` and decaying it by `
|[VGG19](https://paddle-imagenet-models-name.bj.bcebos.com/VGG19_pretrained.zip) | 72.56%/90.83% | 72.32%/90.98% | |[VGG19](https://paddle-imagenet-models-name.bj.bcebos.com/VGG19_pretrained.zip) | 72.56%/90.83% | 72.32%/90.98% |
|[MobileNetV1](http://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV1_pretrained.zip) | 70.91%/89.54% | 70.51%/89.35% | |[MobileNetV1](http://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV1_pretrained.zip) | 70.91%/89.54% | 70.51%/89.35% |
|[MobileNetV2](https://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV2_pretrained.zip) | 71.90%/90.55% | 71.53%/90.41% | |[MobileNetV2](https://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV2_pretrained.zip) | 71.90%/90.55% | 71.53%/90.41% |
|[ResNet18](https://paddle-imagenet-models-name.bj.bcebos.com/ResNet18_pretrained.tar) | 70.85%/89.89% | 70.65%/89.89% |
|[ResNet34](https://paddle-imagenet-models-name.bj.bcebos.com/ResNet34_pretrained.tar) | 74.41%/92.03% | 74.13%/91.97% |
|[ResNet50](http://paddle-imagenet-models-name.bj.bcebos.com/ResNet50_pretrained.zip) | 76.35%/92.80% | 76.22%/92.92% | |[ResNet50](http://paddle-imagenet-models-name.bj.bcebos.com/ResNet50_pretrained.zip) | 76.35%/92.80% | 76.22%/92.92% |
|[ResNet101](http://paddle-imagenet-models-name.bj.bcebos.com/ResNet101_pretrained.zip) | 77.49%/93.57% | 77.56%/93.64% | |[ResNet101](http://paddle-imagenet-models-name.bj.bcebos.com/ResNet101_pretrained.zip) | 77.49%/93.57% | 77.56%/93.64% |
|[ResNet152](https://paddle-imagenet-models-name.bj.bcebos.com/ResNet152_pretrained.zip) | 78.12%/93.93% | 77.92%/93.87% | |[ResNet152](https://paddle-imagenet-models-name.bj.bcebos.com/ResNet152_pretrained.zip) | 78.12%/93.93% | 77.92%/93.87% |
|[SE_ResNeXt50_32x4d](https://paddle-imagenet-models-name.bj.bcebos.com/SE_ResNext50_32x4d_pretrained.zip) | 78.50%/94.01% | 78.44%/93.96% | |[SE_ResNeXt50_32x4d](https://paddle-imagenet-models-name.bj.bcebos.com/SE_ResNext50_32x4d_pretrained.zip) | 78.50%/94.01% | 78.44%/93.96% |
|[SE_ResNeXt101_32x4d](https://paddle-imagenet-models-name.bj.bcebos.com/SE_ResNeXt101_32x4d_pretrained.zip) | 79.26%/94.22% | 79.12%/94.20% | |[SE_ResNeXt101_32x4d](https://paddle-imagenet-models-name.bj.bcebos.com/SE_ResNeXt101_32x4d_pretrained.zip) | 79.26%/94.22% | 79.12%/94.20% |
|[GoogleNet](https://paddle-imagenet-models-name.bj.bcebos.com/GoogleNet_pretrained.tar) | 70.50%/89.59% | 70.27%/89.58% |
|[ShuffleNetV2](https://paddle-imagenet-models-name.bj.bcebos.com/ShuffleNet_pretrained.tar) | | 69.48%/88.99% |
- Released models: not specify parameter names
**NOTE: These are trained by using model_category=models**
|model | top-1/top-5 accuracy(PIL)| top-1/top-5 accuracy(CV2) |
|- |:-: |:-:|
|[ResNet152](http://paddle-imagenet-models.bj.bcebos.com/ResNet152_pretrained.zip) | 78.18%/93.93% | 78.11%/94.04% |
|[SE_ResNeXt50_32x4d](http://paddle-imagenet-models.bj.bcebos.com/se_resnext_50_model.tar) | 78.32%/93.96% | 77.58%/93.73% |
# 图像分类以及模型库 # 图像分类以及模型库
图像分类是计算机视觉的重要领域,它的目标是将图像分类到预定义的标签。近期,需要研究者提出很多不同种类的神经网络,并且极大的提升了分类算法的性能。本页将介绍如何使用PaddlePaddle进行图像分类,包括[数据准备](#data-preparation)[训练](#training-a-model)[参数微调](#finetuning)[模型评估](#evaluation)以及[模型推断](#inference) 图像分类是计算机视觉的重要领域,它的目标是将图像分类到预定义的标签。近期,许多研究者提出很多不同种类的神经网络,并且极大的提升了分类算法的性能。本页将介绍如何使用PaddlePaddle进行图像分类
--- ---
## 内容 ## 内容
- [安装](#installation) - [安装](#安装)
- [数据准备](#data-preparation) - [数据准备](#数据准备)
- [模型训练](#training-a-model) - [模型训练](#模型训练)
- [参数微调](#finetuning) - [混合精度训练](#混合精度训练)
- [模型评估](#evaluation) - [参数微调](#参数微调)
- [模型推断](#inference) - [模型评估](#模型评估)
- [已有模型及其性能](#supported-models) - [模型预测](#模型预测)
- [已有模型及其性能](#已有模型及其性能)
## 安装 ## 安装
在当前目录下运行样例代码需要PadddlePaddle Fluid的v0.13.0或以上的版本。如果你的运行环境中的PaddlePaddle低于此版本,请根据安装文档中的说明来更新PaddlePaddle。 在当前目录下运行样例代码需要PadddlePaddle Fluid的v0.13.0或以上的版本。如果你的运行环境中的PaddlePaddle低于此版本,请根据 [installation document](http://paddlepaddle.org/documentation/docs/zh/1.3/beginners_guide/install/index_cn.html) 中的说明来更新PaddlePaddle。
## 数据准备 ## 数据准备
...@@ -36,8 +37,6 @@ sh download_imagenet2012.sh ...@@ -36,8 +37,6 @@ sh download_imagenet2012.sh
train/n02483708/n02483708_2436.jpeg 369 train/n02483708/n02483708_2436.jpeg 369
train/n03998194/n03998194_7015.jpeg 741 train/n03998194/n03998194_7015.jpeg 741
train/n04523525/n04523525_38118.jpeg 884 train/n04523525/n04523525_38118.jpeg 884
train/n04596742/n04596742_3032.jpeg 909
train/n03208938/n03208938_7065.jpeg 535
... ...
``` ```
* *val_list.txt*: ImageNet-2012验证集合的标签文件,每一行采用"空格"分隔图像路径与标注,例如: * *val_list.txt*: ImageNet-2012验证集合的标签文件,每一行采用"空格"分隔图像路径与标注,例如:
...@@ -45,10 +44,9 @@ train/n03208938/n03208938_7065.jpeg 535 ...@@ -45,10 +44,9 @@ train/n03208938/n03208938_7065.jpeg 535
val/ILSVRC2012_val_00000001.jpeg 65 val/ILSVRC2012_val_00000001.jpeg 65
val/ILSVRC2012_val_00000002.jpeg 970 val/ILSVRC2012_val_00000002.jpeg 970
val/ILSVRC2012_val_00000003.jpeg 230 val/ILSVRC2012_val_00000003.jpeg 230
val/ILSVRC2012_val_00000004.jpeg 809
val/ILSVRC2012_val_00000005.jpeg 516
... ...
``` ```
注意:需要根据本地环境调整reader.py相关路径来正确读取数据。
## 模型训练 ## 模型训练
...@@ -66,22 +64,27 @@ python train.py \ ...@@ -66,22 +64,27 @@ python train.py \
--lr=0.1 --lr=0.1
``` ```
**参数说明:** **参数说明:**
* **model**: name model to use. Default: "SE_ResNeXt50_32x4d". * **model**: 模型名称, 默认值: "SE_ResNeXt50_32x4d"
* **num_epochs**: the number of epochs. Default: 120. * **num_epochs**: 训练回合数,默认值: 120
* **batch_size**: the size of each mini-batch. Default: 256. * **batch_size**: 批大小,默认值: 256
* **use_gpu**: whether to use GPU or not. Default: True. * **use_gpu**: 是否在GPU上运行,默认值: True
* **total_images**: total number of images in the training set. Default: 1281167. * **total_images**: 图片数,ImageNet2012默认值: 1281167.
* **class_dim**: the class number of the classification task. Default: 1000. * **class_dim**: 类别数,默认值: 1000
* **image_shape**: input size of the network. Default: "3,224,224". * **image_shape**: 图片大小,默认值: "3,224,224"
* **model_save_dir**: the directory to save trained model. Default: "output". * **model_save_dir**: 模型存储路径,默认值: "output/"
* **with_mem_opt**: whether to use memory optimization or not. Default: False. * **with_mem_opt**: 是否开启显存优化,默认值: False
* **lr_strategy**: learning rate changing strategy. Default: "piecewise_decay". * **lr_strategy**: 学习率变化策略,默认值: "piecewise_decay"
* **lr**: initialized learning rate. Default: 0.1. * **lr**: 初始学习率,默认值: 0.1
* **pretrained_model**: model path for pretraining. Default: None. * **pretrained_model**: 预训练模型路径,默认值: None
* **checkpoint**: the checkpoint path to resume. Default: None. * **checkpoint**: 用于继续训练的检查点(指定具体模型存储路径,如"output/SE_ResNeXt50_32x4d/100/"),默认值: None
* **model_category**: the category of models, ("models"|"models_name"). Default:"models_name". * **fp16**: 是否开启混合精度训练,默认值: False
* **scale_loss**: 调整混合训练的loss scale值,默认值: 1.0
**数据读取器说明:** 数据读取器定义在```reader.py``````reader_cv2.py```中, 一般, CV2 reader可以提高数据读取速度, reader(PIL)可以得到相对更高的精度, 在[训练阶段](#training-a-model), 默认采用的增广方式是随机裁剪与水平翻转, 而在[评估](#inference)[推断](#inference)阶段用的默认方式是中心裁剪。当前支持的数据增广方式有: * **l2_decay**: l2_decay值,默认值: 1e-4
* **momentum_rate**: momentum_rate值,默认值: 0.9
```run.sh```中有用于训练的脚本.
**数据读取器说明:** 数据读取器定义在```reader.py``````reader_cv2.py```中。一般, CV2可以提高数据读取速度, PIL reader可以得到相对更高的精度, 我们现在默认基于PIL的数据读取器, 在[训练阶段](#模型训练), 默认采用的增广方式是随机裁剪与水平翻转, 而在[模型评估](#模型评估)[模型预测](#模型预测)阶段用的默认方式是中心裁剪。当前支持的数据增广方式有:
* 旋转 * 旋转
* 颜色抖动 * 颜色抖动
* 随机裁剪 * 随机裁剪
...@@ -89,31 +92,11 @@ python train.py \ ...@@ -89,31 +92,11 @@ python train.py \
* 长宽调整 * 长宽调整
* 水平翻转 * 水平翻转
**训练曲线:** 通过训练过程中的日志可以画出训练曲线。举个例子,训练AlexNet出来的日志如下所示:
```
End pass 1, train_loss 6.23153877258, train_acc1 0.0150696625933, train_acc5 0.0552518665791, test_loss 5.41981744766, test_acc1 0.0519132651389, test_acc5 0.156150355935
End pass 2, train_loss 5.15442800522, train_acc1 0.0784279331565, train_acc5 0.211050540209, test_loss 4.45795249939, test_acc1 0.140469551086, test_acc5 0.333163291216
End pass 3, train_loss 4.51505613327, train_acc1 0.145300447941, train_acc5 0.331567406654, test_loss 3.86548018456, test_acc1 0.219443559647, test_acc5 0.446448504925
End pass 4, train_loss 4.12735557556, train_acc1 0.19437250495, train_acc5 0.405713528395, test_loss 3.56990146637, test_acc1 0.264536827803, test_acc5 0.507190704346
End pass 5, train_loss 3.87505435944, train_acc1 0.229518383741, train_acc5 0.453582793474, test_loss 3.35345435143, test_acc1 0.297349333763, test_acc5 0.54753267765
End pass 6, train_loss 3.6929500103, train_acc1 0.255628824234, train_acc5 0.487188398838, test_loss 3.17112898827, test_acc1 0.326953113079, test_acc5 0.581780135632
End pass 7, train_loss 3.55882954597, train_acc1 0.275381118059, train_acc5 0.511990904808, test_loss 3.03736782074, test_acc1 0.349035382271, test_acc5 0.606293857098
End pass 8, train_loss 3.45595097542, train_acc1 0.291462600231, train_acc5 0.530815005302, test_loss 2.96034455299, test_acc1 0.362228929996, test_acc5 0.617390751839
End pass 9, train_loss 3.3745200634, train_acc1 0.303871691227, train_acc5 0.545210540295, test_loss 2.93932366371, test_acc1 0.37129303813, test_acc5 0.623573005199
...
```
下图给出了AlexNet、ResNet50以及SE-ResNeXt-50网络的错误率曲线:
<p align="center">
<img src="images/curve.jpg" height=480 width=640 hspace='10'/> <br />
训练集合与验证集合上的错误率曲线
</p>
## 混合精度训练 ## 混合精度训练
可以通过开启`--fp16 1`启动混合精度训练,这样训练过程会使用float16数据,并输出float32的模型参数("master"参数)。您可能需要同时传入`--scale_loss`来解决fp16训练的精度问题,通常传入`--scale_loss 8.0`即可。 可以通过开启`--fp16=True`启动混合精度训练,这样训练过程会使用float16数据,并输出float32的模型参数("master"参数)。您可能需要同时传入`--scale_loss`来解决fp16训练的精度问题,通常传入`--scale_loss=8.0`即可。
注意,目前混合精度训练不能和内存优化功能同时使用,所以需要传`--with_mem_opt 0`这个参数来禁用内存优化功能。 注意,目前混合精度训练不能和内存优化功能同时使用,所以需要传`--with_mem_opt=False`这个参数来禁用内存优化功能。
## 参数微调 ## 参数微调
...@@ -133,7 +116,7 @@ python train.py ...@@ -133,7 +116,7 @@ python train.py
``` ```
## 模型评估 ## 模型评估
模型评估是指对训练完毕的模型评估各类性能指标。用户可以下载[预训练模型](#supported-models)并且设置```path_to_pretrain_model```为模型所在路径。运行如下的命令,可以获得一个模型top-1/top-5精度: 模型评估是指对训练完毕的模型评估各类性能指标。用户可以下载[已有模型及其性能](#已有模型及其性能)并且设置```path_to_pretrain_model```为模型所在路径。运行如下的命令,可以获得一个模型top-1/top-5精度:
``` ```
python eval.py \ python eval.py \
--model=SE_ResNeXt50_32x4d \ --model=SE_ResNeXt50_32x4d \
...@@ -144,23 +127,8 @@ python eval.py \ ...@@ -144,23 +127,8 @@ python eval.py \
--pretrained_model=${path_to_pretrain_model} --pretrained_model=${path_to_pretrain_model}
``` ```
根据这个评估程序的配置,输出日志形式如下: ## 模型预测
``` 模型预测可以获取一个模型的预测分数或者图像的特征:
Testbatch 0,loss 2.1786134243, acc1 0.625,acc5 0.8125,time 0.48 sec
Testbatch 10,loss 0.898496925831, acc1 0.75,acc5 0.9375,time 0.51 sec
Testbatch 20,loss 1.32524681091, acc1 0.6875,acc5 0.9375,time 0.37 sec
Testbatch 30,loss 1.46830511093, acc1 0.5,acc5 0.9375,time 0.51 sec
Testbatch 40,loss 1.12802267075, acc1 0.625,acc5 0.9375,time 0.35 sec
Testbatch 50,loss 0.881597697735, acc1 0.8125,acc5 1.0,time 0.32 sec
Testbatch 60,loss 0.300163716078, acc1 0.875,acc5 1.0,time 0.48 sec
Testbatch 70,loss 0.692037761211, acc1 0.875,acc5 1.0,time 0.35 sec
Testbatch 80,loss 0.0969972759485, acc1 1.0,acc5 1.0,time 0.41 sec
...
```
## 模型推断
模型推断可以获取一个模型的预测分数或者图像的特征:
``` ```
python infer.py \ python infer.py \
--model=SE_ResNeXt50_32x4d \ --model=SE_ResNeXt50_32x4d \
...@@ -169,31 +137,12 @@ python infer.py \ ...@@ -169,31 +137,12 @@ python infer.py \
--with_mem_opt=True \ --with_mem_opt=True \
--pretrained_model=${path_to_pretrain_model} --pretrained_model=${path_to_pretrain_model}
``` ```
输出的预测结果包括最高分数(未经过softmax处理)以及相应的预测标签。
```
Test-0-score: [13.168352], class [491]
Test-1-score: [7.913302], class [975]
Test-2-score: [16.959702], class [21]
Test-3-score: [14.197695], class [383]
Test-4-score: [12.607652], class [878]
Test-5-score: [17.725458], class [15]
Test-6-score: [12.678599], class [118]
Test-7-score: [12.353498], class [505]
Test-8-score: [20.828007], class [747]
Test-9-score: [15.135801], class [315]
Test-10-score: [14.585114], class [920]
Test-11-score: [13.739927], class [679]
Test-12-score: [15.040644], class [386]
...
```
## 已有模型及其性能 ## 已有模型及其性能
Models包括两种模型:带有参数名字的模型,和不带有参数名字的模型。通过设置 ```model_category = models_name```来训练带有参数名字的模型。 表格中列出了在```models```目录下支持的图像分类模型,并且给出了已完成训练的模型在ImageNet-2012验证集合上的top-1/top-5精度,
可以通过点击相应模型的名称下载相应预训练模型。
表格中列出了在"models"目录下支持的神经网络种类,并且给出了已完成训练的模型在ImageNet-2012验证集合上的top-1/top-5精度;如无特征说明,训练模型的初始学习率为```0.1```,每隔预定的epochs会下降```0.1```。预训练模型可以通过点击相应模型的名称进行下载。
- Released models: specify parameter names - Released models:
|model | top-1/top-5 accuracy(PIL)| top-1/top-5 accuracy(CV2) | |model | top-1/top-5 accuracy(PIL)| top-1/top-5 accuracy(CV2) |
|- |:-: |:-:| |- |:-: |:-:|
...@@ -204,17 +153,12 @@ Models包括两种模型:带有参数名字的模型,和不带有参数名 ...@@ -204,17 +153,12 @@ Models包括两种模型:带有参数名字的模型,和不带有参数名
|[VGG19](https://paddle-imagenet-models-name.bj.bcebos.com/VGG19_pretrained.zip) | 72.56%/90.83% | 72.32%/90.98% | |[VGG19](https://paddle-imagenet-models-name.bj.bcebos.com/VGG19_pretrained.zip) | 72.56%/90.83% | 72.32%/90.98% |
|[MobileNetV1](http://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV1_pretrained.zip) | 70.91%/89.54% | 70.51%/89.35% | |[MobileNetV1](http://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV1_pretrained.zip) | 70.91%/89.54% | 70.51%/89.35% |
|[MobileNetV2](https://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV2_pretrained.zip) | 71.90%/90.55% | 71.53%/90.41% | |[MobileNetV2](https://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV2_pretrained.zip) | 71.90%/90.55% | 71.53%/90.41% |
|[ResNet18](https://paddle-imagenet-models-name.bj.bcebos.com/ResNet18_pretrained.tar) | 70.85%/89.89% | 70.65%/89.89% |
|[ResNet34](https://paddle-imagenet-models-name.bj.bcebos.com/ResNet34_pretrained.tar) | 74.41%/92.03% | 74.13%/91.97% |
|[ResNet50](http://paddle-imagenet-models-name.bj.bcebos.com/ResNet50_pretrained.zip) | 76.35%/92.80% | 76.22%/92.92% | |[ResNet50](http://paddle-imagenet-models-name.bj.bcebos.com/ResNet50_pretrained.zip) | 76.35%/92.80% | 76.22%/92.92% |
|[ResNet101](http://paddle-imagenet-models-name.bj.bcebos.com/ResNet101_pretrained.zip) | 77.49%/93.57% | 77.56%/93.64% | |[ResNet101](http://paddle-imagenet-models-name.bj.bcebos.com/ResNet101_pretrained.zip) | 77.49%/93.57% | 77.56%/93.64% |
|[ResNet152](https://paddle-imagenet-models-name.bj.bcebos.com/ResNet152_pretrained.zip) | 78.12%/93.93% | 77.92%/93.87% | |[ResNet152](https://paddle-imagenet-models-name.bj.bcebos.com/ResNet152_pretrained.zip) | 78.12%/93.93% | 77.92%/93.87% |
|[SE_ResNeXt50_32x4d](https://paddle-imagenet-models-name.bj.bcebos.com/SE_ResNext50_32x4d_pretrained.zip) | 78.50%/94.01% | 78.44%/93.96% | |[SE_ResNeXt50_32x4d](https://paddle-imagenet-models-name.bj.bcebos.com/SE_ResNext50_32x4d_pretrained.zip) | 78.50%/94.01% | 78.44%/93.96% |
|[SE_ResNeXt101_32x4d](https://paddle-imagenet-models-name.bj.bcebos.com/SE_ResNeXt101_32x4d_pretrained.zip) | 79.26%/94.22% | 79.12%/94.20% | |[SE_ResNeXt101_32x4d](https://paddle-imagenet-models-name.bj.bcebos.com/SE_ResNeXt101_32x4d_pretrained.zip) | 79.26%/94.22% | 79.12%/94.20% |
|[GoogleNet](https://paddle-imagenet-models-name.bj.bcebos.com/GoogleNet_pretrained.tar) | 70.50%/89.59% | 70.27%/89.58% |
- Released models: not specify parameter names |[ShuffleNetV2](https://paddle-imagenet-models-name.bj.bcebos.com/ShuffleNet_pretrained.tar) | | 69.48%/88.99% |
**注意:这是model_category = models 的预训练模型**
|model | top-1/top-5 accuracy(PIL)| top-1/top-5 accuracy(CV2) |
|- |:-: |:-:|
|[ResNet152](http://paddle-imagenet-models.bj.bcebos.com/ResNet152_pretrained.zip) | 78.18%/93.93% | 78.11%/94.04% |
|[SE_ResNeXt50_32x4d](http://paddle-imagenet-models.bj.bcebos.com/se_resnext_50_model.tar) | 78.32%/93.96% | 77.58%/93.73% |
...@@ -7,12 +7,12 @@ import time ...@@ -7,12 +7,12 @@ import time
import sys import sys
import paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
#import reader_cv2 as reader
import reader as reader import reader as reader
import argparse import argparse
import functools import functools
import models
from utils.learning_rate import cosine_decay from utils.learning_rate import cosine_decay
from utility import add_arguments, print_arguments from utils.utility import add_arguments, print_arguments
import math import math
parser = argparse.ArgumentParser(description=__doc__) parser = argparse.ArgumentParser(description=__doc__)
...@@ -25,22 +25,9 @@ add_arg('image_shape', str, "3,224,224", "Input image size") ...@@ -25,22 +25,9 @@ add_arg('image_shape', str, "3,224,224", "Input image size")
add_arg('with_mem_opt', bool, True, "Whether to use memory optimization or not.") add_arg('with_mem_opt', bool, True, "Whether to use memory optimization or not.")
add_arg('pretrained_model', str, None, "Whether to use pretrained model.") add_arg('pretrained_model', str, None, "Whether to use pretrained model.")
add_arg('model', str, "SE_ResNeXt50_32x4d", "Set the network to use.") add_arg('model', str, "SE_ResNeXt50_32x4d", "Set the network to use.")
add_arg('model_category', str, "models_name", "Whether to use models_name or not, valid value:'models','models_name'." )
# yapf: enable # yapf: enable
def set_models(model_category):
global models
assert model_category in ["models", "models_name"
], "{} is not in lists: {}".format(
model_category, ["models", "models_name"])
if model_category == "models_name":
import models_name as models
else:
import models as models
def eval(args): def eval(args):
# parameters from arguments # parameters from arguments
class_dim = args.class_dim class_dim = args.class_dim
...@@ -119,7 +106,7 @@ def eval(args): ...@@ -119,7 +106,7 @@ def eval(args):
if batch_id % 10 == 0: if batch_id % 10 == 0:
print("Testbatch {0},loss {1}, " print("Testbatch {0},loss {1}, "
"acc1 {2},acc5 {3},time {4}".format(batch_id, \ "acc1 {2},acc5 {3},time {4}".format(batch_id, \
loss, acc1, acc5, \ "%.5f"%loss,"%.5f"%acc1, "%.5f"%acc5, \
"%2.2f sec" % period)) "%2.2f sec" % period))
sys.stdout.flush() sys.stdout.flush()
...@@ -128,14 +115,13 @@ def eval(args): ...@@ -128,14 +115,13 @@ def eval(args):
test_acc5 = np.sum(test_info[2]) / cnt test_acc5 = np.sum(test_info[2]) / cnt
print("Test_loss {0}, test_acc1 {1}, test_acc5 {2}".format( print("Test_loss {0}, test_acc1 {1}, test_acc5 {2}".format(
test_loss, test_acc1, test_acc5)) "%.5f"%test_loss, "%.5f"%test_acc1, "%.5f"%test_acc5))
sys.stdout.flush() sys.stdout.flush()
def main(): def main():
args = parser.parse_args() args = parser.parse_args()
print_arguments(args) print_arguments(args)
set_models(args.model_category)
eval(args) eval(args)
......
...@@ -10,7 +10,9 @@ import paddle.fluid as fluid ...@@ -10,7 +10,9 @@ import paddle.fluid as fluid
import reader import reader
import argparse import argparse
import functools import functools
from utility import add_arguments, print_arguments import models
import utils
from utils.utility import add_arguments,print_arguments
import math import math
parser = argparse.ArgumentParser(description=__doc__) parser = argparse.ArgumentParser(description=__doc__)
...@@ -22,25 +24,14 @@ add_arg('image_shape', str, "3,224,224", "Input image size") ...@@ -22,25 +24,14 @@ add_arg('image_shape', str, "3,224,224", "Input image size")
add_arg('with_mem_opt', bool, True, "Whether to use memory optimization or not.") add_arg('with_mem_opt', bool, True, "Whether to use memory optimization or not.")
add_arg('pretrained_model', str, None, "Whether to use pretrained model.") add_arg('pretrained_model', str, None, "Whether to use pretrained model.")
add_arg('model', str, "SE_ResNeXt50_32x4d", "Set the network to use.") add_arg('model', str, "SE_ResNeXt50_32x4d", "Set the network to use.")
add_arg('model_category', str, "models_name", "Whether to use models_name or not, valid value:'models','models_name'." ) add_arg('save_inference', bool, False, "Whether to save inference model or not")
# yapf: enable # yapf: enable
def set_models(model_category):
global models
assert model_category in ["models", "models_name"
], "{} is not in lists: {}".format(
model_category, ["models", "models_name"])
if model_category == "models_name":
import models_name as models
else:
import models as models
def infer(args): def infer(args):
# parameters from arguments # parameters from arguments
class_dim = args.class_dim class_dim = args.class_dim
model_name = args.model model_name = args.model
save_inference = args.save_inference
pretrained_model = args.pretrained_model pretrained_model = args.pretrained_model
with_memory_optimization = args.with_mem_opt with_memory_optimization = args.with_mem_opt
image_shape = [int(m) for m in args.image_shape.split(",")] image_shape = [int(m) for m in args.image_shape.split(",")]
...@@ -52,7 +43,7 @@ def infer(args): ...@@ -52,7 +43,7 @@ def infer(args):
# model definition # model definition
model = models.__dict__[model_name]() model = models.__dict__[model_name]()
if model_name is "GoogleNet": if model_name == "GoogleNet":
out, _, _ = model.net(input=image, class_dim=class_dim) out, _, _ = model.net(input=image, class_dim=class_dim)
else: else:
out = model.net(input=image, class_dim=class_dim) out = model.net(input=image, class_dim=class_dim)
...@@ -60,7 +51,7 @@ def infer(args): ...@@ -60,7 +51,7 @@ def infer(args):
test_program = fluid.default_main_program().clone(for_test=True) test_program = fluid.default_main_program().clone(for_test=True)
fetch_list = [out.name] fetch_list = [out.name]
if with_memory_optimization: if with_memory_optimization and not save_inference:
fluid.memory_optimize( fluid.memory_optimize(
fluid.default_main_program(), skip_opt_set=set(fetch_list)) fluid.default_main_program(), skip_opt_set=set(fetch_list))
...@@ -74,7 +65,17 @@ def infer(args): ...@@ -74,7 +65,17 @@ def infer(args):
return os.path.exists(os.path.join(pretrained_model, var.name)) return os.path.exists(os.path.join(pretrained_model, var.name))
fluid.io.load_vars(exe, pretrained_model, predicate=if_exist) fluid.io.load_vars(exe, pretrained_model, predicate=if_exist)
if save_inference:
fluid.io.save_inference_model(
dirname=model_name,
feeded_var_names=['image'],
main_program=test_program,
target_vars=out,
executor=exe,
model_filename='model',
params_filename='params')
print("model: ",model_name," is already saved")
exit(0)
test_batch_size = 1 test_batch_size = 1
test_reader = paddle.batch(reader.test(), batch_size=test_batch_size) test_reader = paddle.batch(reader.test(), batch_size=test_batch_size)
feeder = fluid.DataFeeder(place=place, feed_list=[image]) feeder = fluid.DataFeeder(place=place, feed_list=[image])
...@@ -94,7 +95,6 @@ def infer(args): ...@@ -94,7 +95,6 @@ def infer(args):
def main(): def main():
args = parser.parse_args() args = parser.parse_args()
print_arguments(args) print_arguments(args)
set_models(args.model_category)
infer(args) infer(args)
......
For historical reasons, We keep "no name" models here, which are different from "specified name" models.
**NOTE: Training the models in legacy folder will generate models without specified parameters.**
- **Released models: not specify parameter names**
|model | top-1/top-5 accuracy(PIL)| top-1/top-5 accuracy(CV2) |
|- |:-: |:-:|
|[ResNet152](http://paddle-imagenet-models.bj.bcebos.com/ResNet152_pretrained.zip) | 78.18%/93.93% | 78.11%/94.04% |
|[SE_ResNeXt50_32x4d](http://paddle-imagenet-models.bj.bcebos.com/se_resnext_50_model.tar) | 78.32%/93.96% | 77.58%/93.73% |
...@@ -4,7 +4,9 @@ from .mobilenet_v2 import MobileNetV2 ...@@ -4,7 +4,9 @@ from .mobilenet_v2 import MobileNetV2
from .googlenet import GoogleNet from .googlenet import GoogleNet
from .vgg import VGG11, VGG13, VGG16, VGG19 from .vgg import VGG11, VGG13, VGG16, VGG19
from .resnet import ResNet50, ResNet101, ResNet152 from .resnet import ResNet50, ResNet101, ResNet152
from .resnet_dist import DistResNet
from .inception_v4 import InceptionV4 from .inception_v4 import InceptionV4
from .se_resnext import SE_ResNeXt50_32x4d, SE_ResNeXt101_32x4d, SE_ResNeXt152_32x4d from .se_resnext import SE_ResNeXt50_32x4d, SE_ResNeXt101_32x4d, SE_ResNeXt152_32x4d
from .dpn import DPN68, DPN92, DPN98, DPN107, DPN131 from .dpn import DPN68, DPN92, DPN98, DPN107, DPN131
from .shufflenet_v2 import ShuffleNetV2_x0_5, ShuffleNetV2_x1_0, ShuffleNetV2_x1_5, ShuffleNetV2_x2_0 from .shufflenet_v2 import ShuffleNetV2_x0_5, ShuffleNetV2_x1_0, ShuffleNetV2_x1_5, ShuffleNetV2_x2_0
from .fast_imagenet import FastImageNet
...@@ -26,9 +26,6 @@ class AlexNet(): ...@@ -26,9 +26,6 @@ class AlexNet():
def net(self, input, class_dim=1000): def net(self, input, class_dim=1000):
stdv = 1.0 / math.sqrt(input.shape[1] * 11 * 11) stdv = 1.0 / math.sqrt(input.shape[1] * 11 * 11)
layer_name = [
"conv1", "conv2", "conv3", "conv4", "conv5", "fc6", "fc7", "fc8"
]
conv1 = fluid.layers.conv2d( conv1 = fluid.layers.conv2d(
input=input, input=input,
num_filters=64, num_filters=64,
...@@ -38,11 +35,9 @@ class AlexNet(): ...@@ -38,11 +35,9 @@ class AlexNet():
groups=1, groups=1,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)),
name=layer_name[0] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)))
name=layer_name[0] + "_weights"))
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=conv1, input=conv1,
pool_size=3, pool_size=3,
...@@ -60,11 +55,9 @@ class AlexNet(): ...@@ -60,11 +55,9 @@ class AlexNet():
groups=1, groups=1,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)),
name=layer_name[1] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)))
name=layer_name[1] + "_weights"))
pool2 = fluid.layers.pool2d( pool2 = fluid.layers.pool2d(
input=conv2, input=conv2,
pool_size=3, pool_size=3,
...@@ -82,11 +75,9 @@ class AlexNet(): ...@@ -82,11 +75,9 @@ class AlexNet():
groups=1, groups=1,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)),
name=layer_name[2] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)))
name=layer_name[2] + "_weights"))
stdv = 1.0 / math.sqrt(conv3.shape[1] * 3 * 3) stdv = 1.0 / math.sqrt(conv3.shape[1] * 3 * 3)
conv4 = fluid.layers.conv2d( conv4 = fluid.layers.conv2d(
...@@ -98,11 +89,9 @@ class AlexNet(): ...@@ -98,11 +89,9 @@ class AlexNet():
groups=1, groups=1,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)),
name=layer_name[3] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)))
name=layer_name[3] + "_weights"))
stdv = 1.0 / math.sqrt(conv4.shape[1] * 3 * 3) stdv = 1.0 / math.sqrt(conv4.shape[1] * 3 * 3)
conv5 = fluid.layers.conv2d( conv5 = fluid.layers.conv2d(
...@@ -114,11 +103,9 @@ class AlexNet(): ...@@ -114,11 +103,9 @@ class AlexNet():
groups=1, groups=1,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)),
name=layer_name[4] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)))
name=layer_name[4] + "_weights"))
pool5 = fluid.layers.pool2d( pool5 = fluid.layers.pool2d(
input=conv5, input=conv5,
pool_size=3, pool_size=3,
...@@ -127,42 +114,36 @@ class AlexNet(): ...@@ -127,42 +114,36 @@ class AlexNet():
pool_type='max') pool_type='max')
drop6 = fluid.layers.dropout(x=pool5, dropout_prob=0.5) drop6 = fluid.layers.dropout(x=pool5, dropout_prob=0.5)
stdv = 1.0 / math.sqrt(drop6.shape[1] * drop6.shape[2] * stdv = 1.0 / math.sqrt(drop6.shape[1] * drop6.shape[2] *
drop6.shape[3] * 1.0) drop6.shape[3] * 1.0)
fc6 = fluid.layers.fc( fc6 = fluid.layers.fc(
input=drop6, input=drop6,
size=4096, size=4096,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)),
name=layer_name[5] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)))
name=layer_name[5] + "_weights"))
drop7 = fluid.layers.dropout(x=fc6, dropout_prob=0.5) drop7 = fluid.layers.dropout(x=fc6, dropout_prob=0.5)
stdv = 1.0 / math.sqrt(drop7.shape[1] * 1.0)
stdv = 1.0 / math.sqrt(drop7.shape[1] * 1.0)
fc7 = fluid.layers.fc( fc7 = fluid.layers.fc(
input=drop7, input=drop7,
size=4096, size=4096,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)),
name=layer_name[6] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)))
name=layer_name[6] + "_weights"))
stdv = 1.0 / math.sqrt(fc7.shape[1] * 1.0) stdv = 1.0 / math.sqrt(fc7.shape[1] * 1.0)
out = fluid.layers.fc( out = fluid.layers.fc(
input=fc7, input=fc7,
size=class_dim, size=class_dim,
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)),
name=layer_name[7] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)))
name=layer_name[7] + "_weights"))
return out return out
...@@ -7,7 +7,6 @@ import time ...@@ -7,7 +7,6 @@ import time
import sys import sys
import paddle.fluid as fluid import paddle.fluid as fluid
import math import math
from paddle.fluid.param_attr import ParamAttr
__all__ = ["DPN", "DPN68", "DPN92", "DPN98", "DPN107", "DPN131"] __all__ = ["DPN", "DPN68", "DPN92", "DPN98", "DPN107", "DPN131"]
...@@ -53,30 +52,16 @@ class DPN(object): ...@@ -53,30 +52,16 @@ class DPN(object):
padding=init_padding, padding=init_padding,
groups=1, groups=1,
act=None, act=None,
bias_attr=False, bias_attr=False)
name="conv1",
param_attr=ParamAttr(name="conv1_weights"), )
conv1_x_1 = fluid.layers.batch_norm( conv1_x_1 = fluid.layers.batch_norm(
input=conv1_x_1, input=conv1_x_1, act='relu', is_test=False)
act='relu',
is_test=False,
name="conv1_bn",
param_attr=ParamAttr(name='conv1_bn_scale'),
bias_attr=ParamAttr('conv1_bn_offset'),
moving_mean_name='conv1_bn_mean',
moving_variance_name='conv1_bn_variance', )
convX_x_x = fluid.layers.pool2d( convX_x_x = fluid.layers.pool2d(
input=conv1_x_1, input=conv1_x_1,
pool_size=3, pool_size=3,
pool_stride=2, pool_stride=2,
pool_padding=1, pool_padding=1,
pool_type='max', pool_type='max')
name="pool1")
#conv2 - conv5
match_list, num = [], 0
for gc in range(4): for gc in range(4):
bw = bws[gc] bw = bws[gc]
inc = inc_sec[gc] inc = inc_sec[gc]
...@@ -84,46 +69,32 @@ class DPN(object): ...@@ -84,46 +69,32 @@ class DPN(object):
if gc == 0: if gc == 0:
_type1 = 'proj' _type1 = 'proj'
_type2 = 'normal' _type2 = 'normal'
match = 1
else: else:
_type1 = 'down' _type1 = 'down'
_type2 = 'normal' _type2 = 'normal'
match = match + k_sec[gc - 1] convX_x_x = self.dual_path_factory(convX_x_x, R, R, bw, inc, G,
match_list.append(match) _type1)
convX_x_x = self.dual_path_factory(
convX_x_x, R, R, bw, inc, G, _type1, name="dpn" + str(match))
for i_ly in range(2, k_sec[gc] + 1): for i_ly in range(2, k_sec[gc] + 1):
num += 1 convX_x_x = self.dual_path_factory(convX_x_x, R, R, bw, inc, G,
if num in match_list: _type2)
num += 1
convX_x_x = self.dual_path_factory(
convX_x_x, R, R, bw, inc, G, _type2, name="dpn" + str(num))
conv5_x_x = fluid.layers.concat(convX_x_x, axis=1) conv5_x_x = fluid.layers.concat(convX_x_x, axis=1)
conv5_x_x = fluid.layers.batch_norm( conv5_x_x = fluid.layers.batch_norm(
input=conv5_x_x, input=conv5_x_x, act='relu', is_test=False)
act='relu',
is_test=False,
name="final_concat_bn",
param_attr=ParamAttr(name='final_concat_bn_scale'),
bias_attr=ParamAttr('final_concat_bn_offset'),
moving_mean_name='final_concat_bn_mean',
moving_variance_name='final_concat_bn_variance', )
pool5 = fluid.layers.pool2d( pool5 = fluid.layers.pool2d(
input=conv5_x_x, input=conv5_x_x,
pool_size=7, pool_size=7,
pool_stride=1, pool_stride=1,
pool_padding=0, pool_padding=0,
pool_type='avg', ) pool_type='avg')
#stdv = 1.0 / math.sqrt(pool5.shape[1] * 1.0)
stdv = 0.01 stdv = 0.01
param_attr = fluid.param_attr.ParamAttr( param_attr = fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)) initializer=fluid.initializer.Uniform(-stdv, stdv))
fc6 = fluid.layers.fc(input=pool5, fc6 = fluid.layers.fc(input=pool5,
size=class_dim, size=class_dim,
param_attr=param_attr, param_attr=param_attr)
name="fc6")
return fc6 return fc6
...@@ -201,8 +172,7 @@ class DPN(object): ...@@ -201,8 +172,7 @@ class DPN(object):
num_1x1_c, num_1x1_c,
inc, inc,
G, G,
_type='normal', _type='normal'):
name=None):
kw = 3 kw = 3
kh = 3 kh = 3
pw = (kw - 1) // 2 pw = (kw - 1) // 2
...@@ -231,50 +201,35 @@ class DPN(object): ...@@ -231,50 +201,35 @@ class DPN(object):
num_filter=(num_1x1_c + 2 * inc), num_filter=(num_1x1_c + 2 * inc),
kernel=(1, 1), kernel=(1, 1),
pad=(0, 0), pad=(0, 0),
stride=(key_stride, key_stride), stride=(key_stride, key_stride))
name=name + "_match")
data_o1, data_o2 = fluid.layers.split( data_o1, data_o2 = fluid.layers.split(
c1x1_w, c1x1_w, num_or_sections=[num_1x1_c, 2 * inc], dim=1)
num_or_sections=[num_1x1_c, 2 * inc],
dim=1,
name=name + "_match_conv_Slice")
else: else:
data_o1 = data[0] data_o1 = data[0]
data_o2 = data[1] data_o2 = data[1]
# MAIN # MAIN
c1x1_a = self.bn_ac_conv( c1x1_a = self.bn_ac_conv(
data=data_in, data=data_in, num_filter=num_1x1_a, kernel=(1, 1), pad=(0, 0))
num_filter=num_1x1_a,
kernel=(1, 1),
pad=(0, 0),
name=name + "_conv1")
c3x3_b = self.bn_ac_conv( c3x3_b = self.bn_ac_conv(
data=c1x1_a, data=c1x1_a,
num_filter=num_3x3_b, num_filter=num_3x3_b,
kernel=(kw, kh), kernel=(kw, kh),
pad=(pw, ph), pad=(pw, ph),
stride=(key_stride, key_stride), stride=(key_stride, key_stride),
num_group=G, num_group=G)
name=name + "_conv2")
c1x1_c = self.bn_ac_conv( c1x1_c = self.bn_ac_conv(
data=c3x3_b, data=c3x3_b,
num_filter=(num_1x1_c + inc), num_filter=(num_1x1_c + inc),
kernel=(1, 1), kernel=(1, 1),
pad=(0, 0), pad=(0, 0))
name=name + "_conv3")
c1x1_c1, c1x1_c2 = fluid.layers.split( c1x1_c1, c1x1_c2 = fluid.layers.split(
c1x1_c, c1x1_c, num_or_sections=[num_1x1_c, inc], dim=1)
num_or_sections=[num_1x1_c, inc],
dim=1,
name=name + "_conv3_Slice")
# OUTPUTS # OUTPUTS
summ = fluid.layers.elementwise_add( summ = fluid.layers.elementwise_add(x=data_o1, y=c1x1_c1)
x=data_o1, y=c1x1_c1, name=name + "_elewise") dense = fluid.layers.concat([data_o2, c1x1_c2], axis=1)
dense = fluid.layers.concat(
[data_o2, c1x1_c2], axis=1, name=name + "_concat")
return [summ, dense] return [summ, dense]
...@@ -284,17 +239,8 @@ class DPN(object): ...@@ -284,17 +239,8 @@ class DPN(object):
kernel, kernel,
pad, pad,
stride=(1, 1), stride=(1, 1),
num_group=1, num_group=1):
name=None): bn_ac = fluid.layers.batch_norm(input=data, act='relu', is_test=False)
bn_ac = fluid.layers.batch_norm(
input=data,
act='relu',
is_test=False,
name=name + '.output.1',
param_attr=ParamAttr(name=name + '_bn_scale'),
bias_attr=ParamAttr(name + '_bn_offset'),
moving_mean_name=name + '_bn_mean',
moving_variance_name=name + '_bn_variance', )
bn_ac_conv = fluid.layers.conv2d( bn_ac_conv = fluid.layers.conv2d(
input=bn_ac, input=bn_ac,
num_filters=num_filter, num_filters=num_filter,
...@@ -303,8 +249,7 @@ class DPN(object): ...@@ -303,8 +249,7 @@ class DPN(object):
padding=pad, padding=pad,
groups=num_group, groups=num_group,
act=None, act=None,
bias_attr=False, bias_attr=False)
param_attr=ParamAttr(name=name + "_weights"))
return bn_ac_conv return bn_ac_conv
...@@ -314,7 +259,7 @@ def DPN68(): ...@@ -314,7 +259,7 @@ def DPN68():
def DPN92(): def DPN92():
onvodel = DPN(layers=92) model = DPN(layers=92)
return model return model
......
...@@ -3,7 +3,6 @@ from __future__ import division ...@@ -3,7 +3,6 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
from paddle.fluid.param_attr import ParamAttr
__all__ = ['GoogleNet'] __all__ = ['GoogleNet']
...@@ -30,13 +29,11 @@ class GoogleNet(): ...@@ -30,13 +29,11 @@ class GoogleNet():
filter_size, filter_size,
stride=1, stride=1,
groups=1, groups=1,
act=None, act=None):
name=None):
channels = input.shape[1] channels = input.shape[1]
stdv = (3.0 / (filter_size**2 * channels))**0.5 stdv = (3.0 / (filter_size**2 * channels))**0.5
param_attr = ParamAttr( param_attr = fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv))
name=name + "_weights")
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
...@@ -46,63 +43,43 @@ class GoogleNet(): ...@@ -46,63 +43,43 @@ class GoogleNet():
groups=groups, groups=groups,
act=act, act=act,
param_attr=param_attr, param_attr=param_attr,
bias_attr=False, bias_attr=False)
name=name)
return conv return conv
def xavier(self, channels, filter_size, name): def xavier(self, channels, filter_size):
stdv = (3.0 / (filter_size**2 * channels))**0.5 stdv = (3.0 / (filter_size**2 * channels))**0.5
param_attr = ParamAttr( param_attr = fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv))
name=name + "_weights")
return param_attr return param_attr
def inception(self, def inception(self, name, input, channels, filter1, filter3R, filter3,
input, filter5R, filter5, proj):
channels,
filter1,
filter3R,
filter3,
filter5R,
filter5,
proj,
name=None):
conv1 = self.conv_layer( conv1 = self.conv_layer(
input=input, input=input, num_filters=filter1, filter_size=1, stride=1, act=None)
num_filters=filter1,
filter_size=1,
stride=1,
act=None,
name="inception_" + name + "_1x1")
conv3r = self.conv_layer( conv3r = self.conv_layer(
input=input, input=input,
num_filters=filter3R, num_filters=filter3R,
filter_size=1, filter_size=1,
stride=1, stride=1,
act=None, act=None)
name="inception_" + name + "_3x3_reduce")
conv3 = self.conv_layer( conv3 = self.conv_layer(
input=conv3r, input=conv3r,
num_filters=filter3, num_filters=filter3,
filter_size=3, filter_size=3,
stride=1, stride=1,
act=None, act=None)
name="inception_" + name + "_3x3")
conv5r = self.conv_layer( conv5r = self.conv_layer(
input=input, input=input,
num_filters=filter5R, num_filters=filter5R,
filter_size=1, filter_size=1,
stride=1, stride=1,
act=None, act=None)
name="inception_" + name + "_5x5_reduce")
conv5 = self.conv_layer( conv5 = self.conv_layer(
input=conv5r, input=conv5r,
num_filters=filter5, num_filters=filter5,
filter_size=5, filter_size=5,
stride=1, stride=1,
act=None, act=None)
name="inception_" + name + "_5x5")
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=input, input=input,
pool_size=3, pool_size=3,
...@@ -110,124 +87,81 @@ class GoogleNet(): ...@@ -110,124 +87,81 @@ class GoogleNet():
pool_padding=1, pool_padding=1,
pool_type='max') pool_type='max')
convprj = fluid.layers.conv2d( convprj = fluid.layers.conv2d(
input=pool, input=pool, filter_size=1, num_filters=proj, stride=1, padding=0)
filter_size=1,
num_filters=proj,
stride=1,
padding=0,
name="inception_" + name + "_3x3_proj",
param_attr=ParamAttr(
name="inception_" + name + "_3x3_proj_weights"),
bias_attr=False)
cat = fluid.layers.concat(input=[conv1, conv3, conv5, convprj], axis=1) cat = fluid.layers.concat(input=[conv1, conv3, conv5, convprj], axis=1)
cat = fluid.layers.relu(cat) cat = fluid.layers.relu(cat)
return cat return cat
def net(self, input, class_dim=1000): def net(self, input, class_dim=1000):
conv = self.conv_layer( conv = self.conv_layer(
input=input, input=input, num_filters=64, filter_size=7, stride=2, act=None)
num_filters=64,
filter_size=7,
stride=2,
act=None,
name="conv1")
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=conv, pool_size=3, pool_type='max', pool_stride=2) input=conv, pool_size=3, pool_type='max', pool_stride=2)
conv = self.conv_layer( conv = self.conv_layer(
input=pool, input=pool, num_filters=64, filter_size=1, stride=1, act=None)
num_filters=64,
filter_size=1,
stride=1,
act=None,
name="conv2_1x1")
conv = self.conv_layer( conv = self.conv_layer(
input=conv, input=conv, num_filters=192, filter_size=3, stride=1, act=None)
num_filters=192,
filter_size=3,
stride=1,
act=None,
name="conv2_3x3")
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=conv, pool_size=3, pool_type='max', pool_stride=2) input=conv, pool_size=3, pool_type='max', pool_stride=2)
ince3a = self.inception(pool, 192, 64, 96, 128, 16, 32, 32, "ince3a") ince3a = self.inception("ince3a", pool, 192, 64, 96, 128, 16, 32, 32)
ince3b = self.inception(ince3a, 256, 128, 128, 192, 32, 96, 64, ince3b = self.inception("ince3b", ince3a, 256, 128, 128, 192, 32, 96,
"ince3b") 64)
pool3 = fluid.layers.pool2d( pool3 = fluid.layers.pool2d(
input=ince3b, pool_size=3, pool_type='max', pool_stride=2) input=ince3b, pool_size=3, pool_type='max', pool_stride=2)
ince4a = self.inception(pool3, 480, 192, 96, 208, 16, 48, 64, "ince4a") ince4a = self.inception("ince4a", pool3, 480, 192, 96, 208, 16, 48, 64)
ince4b = self.inception(ince4a, 512, 160, 112, 224, 24, 64, 64, ince4b = self.inception("ince4b", ince4a, 512, 160, 112, 224, 24, 64,
"ince4b") 64)
ince4c = self.inception(ince4b, 512, 128, 128, 256, 24, 64, 64, ince4c = self.inception("ince4c", ince4b, 512, 128, 128, 256, 24, 64,
"ince4c") 64)
ince4d = self.inception(ince4c, 512, 112, 144, 288, 32, 64, 64, ince4d = self.inception("ince4d", ince4c, 512, 112, 144, 288, 32, 64,
"ince4d") 64)
ince4e = self.inception(ince4d, 528, 256, 160, 320, 32, 128, 128, ince4e = self.inception("ince4e", ince4d, 528, 256, 160, 320, 32, 128,
"ince4e") 128)
pool4 = fluid.layers.pool2d( pool4 = fluid.layers.pool2d(
input=ince4e, pool_size=3, pool_type='max', pool_stride=2) input=ince4e, pool_size=3, pool_type='max', pool_stride=2)
ince5a = self.inception(pool4, 832, 256, 160, 320, 32, 128, 128, ince5a = self.inception("ince5a", pool4, 832, 256, 160, 320, 32, 128,
"ince5a") 128)
ince5b = self.inception(ince5a, 832, 384, 192, 384, 48, 128, 128, ince5b = self.inception("ince5b", ince5a, 832, 384, 192, 384, 48, 128,
"ince5b") 128)
pool5 = fluid.layers.pool2d( pool5 = fluid.layers.pool2d(
input=ince5b, pool_size=7, pool_type='avg', pool_stride=7) input=ince5b, pool_size=7, pool_type='avg', pool_stride=7)
dropout = fluid.layers.dropout(x=pool5, dropout_prob=0.4) dropout = fluid.layers.dropout(x=pool5, dropout_prob=0.4)
out = fluid.layers.fc(input=dropout, out = fluid.layers.fc(input=dropout,
size=class_dim, size=class_dim,
act='softmax', act='softmax',
param_attr=self.xavier(1024, 1, "out"), param_attr=self.xavier(1024, 1))
name="out",
bias_attr=ParamAttr(name="out_offset"))
pool_o1 = fluid.layers.pool2d( pool_o1 = fluid.layers.pool2d(
input=ince4a, pool_size=5, pool_type='avg', pool_stride=3) input=ince4a, pool_size=5, pool_type='avg', pool_stride=3)
conv_o1 = self.conv_layer( conv_o1 = self.conv_layer(
input=pool_o1, input=pool_o1, num_filters=128, filter_size=1, stride=1, act=None)
num_filters=128,
filter_size=1,
stride=1,
act=None,
name="conv_o1")
fc_o1 = fluid.layers.fc(input=conv_o1, fc_o1 = fluid.layers.fc(input=conv_o1,
size=1024, size=1024,
act='relu', act='relu',
param_attr=self.xavier(2048, 1, "fc_o1"), param_attr=self.xavier(2048, 1))
name="fc_o1",
bias_attr=ParamAttr(name="fc_o1_offset"))
dropout_o1 = fluid.layers.dropout(x=fc_o1, dropout_prob=0.7) dropout_o1 = fluid.layers.dropout(x=fc_o1, dropout_prob=0.7)
out1 = fluid.layers.fc(input=dropout_o1, out1 = fluid.layers.fc(input=dropout_o1,
size=class_dim, size=class_dim,
act='softmax', act='softmax',
param_attr=self.xavier(1024, 1, "out1"), param_attr=self.xavier(1024, 1))
name="out1",
bias_attr=ParamAttr(name="out1_offset"))
pool_o2 = fluid.layers.pool2d( pool_o2 = fluid.layers.pool2d(
input=ince4d, pool_size=5, pool_type='avg', pool_stride=3) input=ince4d, pool_size=5, pool_type='avg', pool_stride=3)
conv_o2 = self.conv_layer( conv_o2 = self.conv_layer(
input=pool_o2, input=pool_o2, num_filters=128, filter_size=1, stride=1, act=None)
num_filters=128,
filter_size=1,
stride=1,
act=None,
name="conv_o2")
fc_o2 = fluid.layers.fc(input=conv_o2, fc_o2 = fluid.layers.fc(input=conv_o2,
size=1024, size=1024,
act='relu', act='relu',
param_attr=self.xavier(2048, 1, "fc_o2"), param_attr=self.xavier(2048, 1))
name="fc_o2",
bias_attr=ParamAttr(name="fc_o2_offset"))
dropout_o2 = fluid.layers.dropout(x=fc_o2, dropout_prob=0.7) dropout_o2 = fluid.layers.dropout(x=fc_o2, dropout_prob=0.7)
out2 = fluid.layers.fc(input=dropout_o2, out2 = fluid.layers.fc(input=dropout_o2,
size=class_dim, size=class_dim,
act='softmax', act='softmax',
param_attr=self.xavier(1024, 1, "out2"), param_attr=self.xavier(1024, 1))
name="out2",
bias_attr=ParamAttr(name="out2_offset"))
# last fc layer is "out" # last fc layer is "out"
return out, out1, out2 return out, out1, out2
...@@ -4,7 +4,6 @@ from __future__ import print_function ...@@ -4,7 +4,6 @@ from __future__ import print_function
import paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import math import math
from paddle.fluid.param_attr import ParamAttr
__all__ = ['InceptionV4'] __all__ = ['InceptionV4']
...@@ -29,15 +28,15 @@ class InceptionV4(): ...@@ -29,15 +28,15 @@ class InceptionV4():
x = self.inception_stem(input) x = self.inception_stem(input)
for i in range(4): for i in range(4):
x = self.inceptionA(x, name=str(i + 1)) x = self.inceptionA(x)
x = self.reductionA(x) x = self.reductionA(x)
for i in range(7): for i in range(7):
x = self.inceptionB(x, name=str(i + 1)) x = self.inceptionB(x)
x = self.reductionB(x) x = self.reductionB(x)
for i in range(3): for i in range(3):
x = self.inceptionC(x, name=str(i + 1)) x = self.inceptionC(x)
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=x, pool_size=8, pool_type='avg', global_pooling=True) input=x, pool_size=8, pool_type='avg', global_pooling=True)
...@@ -48,12 +47,8 @@ class InceptionV4(): ...@@ -48,12 +47,8 @@ class InceptionV4():
out = fluid.layers.fc( out = fluid.layers.fc(
input=drop, input=drop,
size=class_dim, size=class_dim,
param_attr=ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv), initializer=fluid.initializer.Uniform(-stdv, stdv)))
name="final_fc_weights"),
bias_attr=ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv),
name="final_fc_offset"))
return out return out
def conv_bn_layer(self, def conv_bn_layer(self,
...@@ -63,8 +58,7 @@ class InceptionV4(): ...@@ -63,8 +58,7 @@ class InceptionV4():
stride=1, stride=1,
padding=0, padding=0,
groups=1, groups=1,
act='relu', act='relu'):
name=None):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=data, input=data,
num_filters=num_filters, num_filters=num_filters,
...@@ -73,58 +67,32 @@ class InceptionV4(): ...@@ -73,58 +67,32 @@ class InceptionV4():
padding=padding, padding=padding,
groups=groups, groups=groups,
act=None, act=None,
param_attr=ParamAttr(name=name + "_weights"), bias_attr=False)
bias_attr=False, return fluid.layers.batch_norm(input=conv, act=act)
name=name)
bn_name = name + "_bn" def inception_stem(self, data):
return fluid.layers.batch_norm( conv = self.conv_bn_layer(data, 32, 3, stride=2, act='relu')
input=conv, conv = self.conv_bn_layer(conv, 32, 3, act='relu')
act=act, conv = self.conv_bn_layer(conv, 64, 3, padding=1, act='relu')
name=bn_name,
param_attr=ParamAttr(name=bn_name + "_scale"),
bias_attr=ParamAttr(name=bn_name + "_offset"),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
def inception_stem(self, data, name=None):
conv = self.conv_bn_layer(
data, 32, 3, stride=2, act='relu', name="conv1_3x3_s2")
conv = self.conv_bn_layer(conv, 32, 3, act='relu', name="conv2_3x3_s1")
conv = self.conv_bn_layer(
conv, 64, 3, padding=1, act='relu', name="conv3_3x3_s1")
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=conv, pool_size=3, pool_stride=2, pool_type='max') input=conv, pool_size=3, pool_stride=2, pool_type='max')
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(conv, 96, 3, stride=2, act='relu')
conv, 96, 3, stride=2, act='relu', name="inception_stem1_3x3_s2")
concat = fluid.layers.concat([pool1, conv2], axis=1) concat = fluid.layers.concat([pool1, conv2], axis=1)
conv1 = self.conv_bn_layer( conv1 = self.conv_bn_layer(concat, 64, 1, act='relu')
concat, 64, 1, act='relu', name="inception_stem2_3x3_reduce") conv1 = self.conv_bn_layer(conv1, 96, 3, act='relu')
conv1 = self.conv_bn_layer(
conv1, 96, 3, act='relu', name="inception_stem2_3x3")
conv2 = self.conv_bn_layer(concat, 64, 1, act='relu')
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(
concat, 64, 1, act='relu', name="inception_stem2_1x7_reduce") conv2, 64, (7, 1), padding=(3, 0), act='relu')
conv2 = self.conv_bn_layer(
conv2,
64, (7, 1),
padding=(3, 0),
act='relu',
name="inception_stem2_1x7")
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(
conv2, conv2, 64, (1, 7), padding=(0, 3), act='relu')
64, (1, 7), conv2 = self.conv_bn_layer(conv2, 96, 3, act='relu')
padding=(0, 3),
act='relu',
name="inception_stem2_7x1")
conv2 = self.conv_bn_layer(
conv2, 96, 3, act='relu', name="inception_stem2_3x3_2")
concat = fluid.layers.concat([conv1, conv2], axis=1) concat = fluid.layers.concat([conv1, conv2], axis=1)
conv1 = self.conv_bn_layer( conv1 = self.conv_bn_layer(concat, 192, 3, stride=2, act='relu')
concat, 192, 3, stride=2, act='relu', name="inception_stem3_3x3_s2")
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=concat, pool_size=3, pool_stride=2, pool_type='max') input=concat, pool_size=3, pool_stride=2, pool_type='max')
...@@ -132,207 +100,105 @@ class InceptionV4(): ...@@ -132,207 +100,105 @@ class InceptionV4():
return concat return concat
def inceptionA(self, data, name=None): def inceptionA(self, data):
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=data, pool_size=3, pool_padding=1, pool_type='avg') input=data, pool_size=3, pool_padding=1, pool_type='avg')
conv1 = self.conv_bn_layer( conv1 = self.conv_bn_layer(pool1, 96, 1, act='relu')
pool1, 96, 1, act='relu', name="inception_a" + name + "_1x1")
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(data, 96, 1, act='relu')
data, 96, 1, act='relu', name="inception_a" + name + "_1x1_2")
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(data, 64, 1, act='relu')
data, 64, 1, act='relu', name="inception_a" + name + "_3x3_reduce") conv3 = self.conv_bn_layer(conv3, 96, 3, padding=1, act='relu')
conv3 = self.conv_bn_layer(
conv3,
96,
3,
padding=1,
act='relu',
name="inception_a" + name + "_3x3")
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(data, 64, 1, act='relu')
data, conv4 = self.conv_bn_layer(conv4, 96, 3, padding=1, act='relu')
64, conv4 = self.conv_bn_layer(conv4, 96, 3, padding=1, act='relu')
1,
act='relu',
name="inception_a" + name + "_3x3_2_reduce")
conv4 = self.conv_bn_layer(
conv4,
96,
3,
padding=1,
act='relu',
name="inception_a" + name + "_3x3_2")
conv4 = self.conv_bn_layer(
conv4,
96,
3,
padding=1,
act='relu',
name="inception_a" + name + "_3x3_3")
concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1) concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1)
return concat return concat
def reductionA(self, data, name=None): def reductionA(self, data):
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=data, pool_size=3, pool_stride=2, pool_type='max') input=data, pool_size=3, pool_stride=2, pool_type='max')
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(data, 384, 3, stride=2, act='relu')
data, 384, 3, stride=2, act='relu', name="reduction_a_3x3")
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(data, 192, 1, act='relu')
data, 192, 1, act='relu', name="reduction_a_3x3_2_reduce") conv3 = self.conv_bn_layer(conv3, 224, 3, padding=1, act='relu')
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(conv3, 256, 3, stride=2, act='relu')
conv3, 224, 3, padding=1, act='relu', name="reduction_a_3x3_2")
conv3 = self.conv_bn_layer(
conv3, 256, 3, stride=2, act='relu', name="reduction_a_3x3_3")
concat = fluid.layers.concat([pool1, conv2, conv3], axis=1) concat = fluid.layers.concat([pool1, conv2, conv3], axis=1)
return concat return concat
def inceptionB(self, data, name=None): def inceptionB(self, data):
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=data, pool_size=3, pool_padding=1, pool_type='avg') input=data, pool_size=3, pool_padding=1, pool_type='avg')
conv1 = self.conv_bn_layer( conv1 = self.conv_bn_layer(pool1, 128, 1, act='relu')
pool1, 128, 1, act='relu', name="inception_b" + name + "_1x1")
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(data, 384, 1, act='relu')
data, 384, 1, act='relu', name="inception_b" + name + "_1x1_2")
conv3 = self.conv_bn_layer(data, 192, 1, act='relu')
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(
data, 192, 1, act='relu', name="inception_b" + name + "_1x7_reduce") conv3, 224, (1, 7), padding=(0, 3), act='relu')
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(
conv3, conv3, 256, (7, 1), padding=(3, 0), act='relu')
224, (1, 7),
padding=(0, 3),
act='relu',
name="inception_b" + name + "_1x7")
conv3 = self.conv_bn_layer(
conv3,
256, (7, 1),
padding=(3, 0),
act='relu',
name="inception_b" + name + "_7x1")
conv4 = self.conv_bn_layer(data, 192, 1, act='relu')
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
data, conv4, 192, (1, 7), padding=(0, 3), act='relu')
192,
1,
act='relu',
name="inception_b" + name + "_7x1_2_reduce")
conv4 = self.conv_bn_layer(
conv4,
192, (1, 7),
padding=(0, 3),
act='relu',
name="inception_b" + name + "_1x7_2")
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
conv4, conv4, 224, (7, 1), padding=(3, 0), act='relu')
224, (7, 1),
padding=(3, 0),
act='relu',
name="inception_b" + name + "_7x1_2")
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
conv4, conv4, 224, (1, 7), padding=(0, 3), act='relu')
224, (1, 7),
padding=(0, 3),
act='relu',
name="inception_b" + name + "_1x7_3")
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
conv4, conv4, 256, (7, 1), padding=(3, 0), act='relu')
256, (7, 1),
padding=(3, 0),
act='relu',
name="inception_b" + name + "_7x1_3")
concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1) concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1)
return concat return concat
def reductionB(self, data, name=None): def reductionB(self, data):
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=data, pool_size=3, pool_stride=2, pool_type='max') input=data, pool_size=3, pool_stride=2, pool_type='max')
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(data, 192, 1, act='relu')
data, 192, 1, act='relu', name="reduction_b_3x3_reduce") conv2 = self.conv_bn_layer(conv2, 192, 3, stride=2, act='relu')
conv2 = self.conv_bn_layer(
conv2, 192, 3, stride=2, act='relu', name="reduction_b_3x3")
conv3 = self.conv_bn_layer(data, 256, 1, act='relu')
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(
data, 256, 1, act='relu', name="reduction_b_1x7_reduce") conv3, 256, (1, 7), padding=(0, 3), act='relu')
conv3 = self.conv_bn_layer(
conv3,
256, (1, 7),
padding=(0, 3),
act='relu',
name="reduction_b_1x7")
conv3 = self.conv_bn_layer(
conv3,
320, (7, 1),
padding=(3, 0),
act='relu',
name="reduction_b_7x1")
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(
conv3, 320, 3, stride=2, act='relu', name="reduction_b_3x3_2") conv3, 320, (7, 1), padding=(3, 0), act='relu')
conv3 = self.conv_bn_layer(conv3, 320, 3, stride=2, act='relu')
concat = fluid.layers.concat([pool1, conv2, conv3], axis=1) concat = fluid.layers.concat([pool1, conv2, conv3], axis=1)
return concat return concat
def inceptionC(self, data, name=None): def inceptionC(self, data):
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=data, pool_size=3, pool_padding=1, pool_type='avg') input=data, pool_size=3, pool_padding=1, pool_type='avg')
conv1 = self.conv_bn_layer( conv1 = self.conv_bn_layer(pool1, 256, 1, act='relu')
pool1, 256, 1, act='relu', name="inception_c" + name + "_1x1")
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(data, 256, 1, act='relu')
data, 256, 1, act='relu', name="inception_c" + name + "_1x1_2")
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(data, 384, 1, act='relu')
data, 384, 1, act='relu', name="inception_c" + name + "_1x1_3")
conv3_1 = self.conv_bn_layer( conv3_1 = self.conv_bn_layer(
conv3, conv3, 256, (1, 3), padding=(0, 1), act='relu')
256, (1, 3),
padding=(0, 1),
act='relu',
name="inception_c" + name + "_1x3")
conv3_2 = self.conv_bn_layer( conv3_2 = self.conv_bn_layer(
conv3, conv3, 256, (3, 1), padding=(1, 0), act='relu')
256, (3, 1),
padding=(1, 0),
act='relu',
name="inception_c" + name + "_3x1")
conv4 = self.conv_bn_layer(data, 384, 1, act='relu')
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
data, 384, 1, act='relu', name="inception_c" + name + "_1x1_4") conv4, 448, (1, 3), padding=(0, 1), act='relu')
conv4 = self.conv_bn_layer(
conv4,
448, (1, 3),
padding=(0, 1),
act='relu',
name="inception_c" + name + "_1x3_2")
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
conv4, conv4, 512, (3, 1), padding=(1, 0), act='relu')
512, (3, 1),
padding=(1, 0),
act='relu',
name="inception_c" + name + "_3x1_2")
conv4_1 = self.conv_bn_layer( conv4_1 = self.conv_bn_layer(
conv4, conv4, 256, (1, 3), padding=(0, 1), act='relu')
256, (1, 3),
padding=(0, 1),
act='relu',
name="inception_c" + name + "_1x3_3")
conv4_2 = self.conv_bn_layer( conv4_2 = self.conv_bn_layer(
conv4, conv4, 256, (3, 1), padding=(1, 0), act='relu')
256, (3, 1),
padding=(1, 0),
act='relu',
name="inception_c" + name + "_3x1_3")
concat = fluid.layers.concat( concat = fluid.layers.concat(
[conv1, conv2, conv3_1, conv3_2, conv4_1, conv4_2], axis=1) [conv1, conv2, conv3_1, conv3_2, conv4_1, conv4_2], axis=1)
......
...@@ -32,8 +32,7 @@ class MobileNet(): ...@@ -32,8 +32,7 @@ class MobileNet():
channels=3, channels=3,
num_filters=int(32 * scale), num_filters=int(32 * scale),
stride=2, stride=2,
padding=1, padding=1)
name="conv1")
# 56x56 # 56x56
input = self.depthwise_separable( input = self.depthwise_separable(
...@@ -42,8 +41,7 @@ class MobileNet(): ...@@ -42,8 +41,7 @@ class MobileNet():
num_filters2=64, num_filters2=64,
num_groups=32, num_groups=32,
stride=1, stride=1,
scale=scale, scale=scale)
name="conv2_1")
input = self.depthwise_separable( input = self.depthwise_separable(
input, input,
...@@ -51,8 +49,7 @@ class MobileNet(): ...@@ -51,8 +49,7 @@ class MobileNet():
num_filters2=128, num_filters2=128,
num_groups=64, num_groups=64,
stride=2, stride=2,
scale=scale, scale=scale)
name="conv2_2")
# 28x28 # 28x28
input = self.depthwise_separable( input = self.depthwise_separable(
...@@ -61,8 +58,7 @@ class MobileNet(): ...@@ -61,8 +58,7 @@ class MobileNet():
num_filters2=128, num_filters2=128,
num_groups=128, num_groups=128,
stride=1, stride=1,
scale=scale, scale=scale)
name="conv3_1")
input = self.depthwise_separable( input = self.depthwise_separable(
input, input,
...@@ -70,8 +66,7 @@ class MobileNet(): ...@@ -70,8 +66,7 @@ class MobileNet():
num_filters2=256, num_filters2=256,
num_groups=128, num_groups=128,
stride=2, stride=2,
scale=scale, scale=scale)
name="conv3_2")
# 14x14 # 14x14
input = self.depthwise_separable( input = self.depthwise_separable(
...@@ -80,8 +75,7 @@ class MobileNet(): ...@@ -80,8 +75,7 @@ class MobileNet():
num_filters2=256, num_filters2=256,
num_groups=256, num_groups=256,
stride=1, stride=1,
scale=scale, scale=scale)
name="conv4_1")
input = self.depthwise_separable( input = self.depthwise_separable(
input, input,
...@@ -89,8 +83,7 @@ class MobileNet(): ...@@ -89,8 +83,7 @@ class MobileNet():
num_filters2=512, num_filters2=512,
num_groups=256, num_groups=256,
stride=2, stride=2,
scale=scale, scale=scale)
name="conv4_2")
# 14x14 # 14x14
for i in range(5): for i in range(5):
...@@ -100,8 +93,7 @@ class MobileNet(): ...@@ -100,8 +93,7 @@ class MobileNet():
num_filters2=512, num_filters2=512,
num_groups=512, num_groups=512,
stride=1, stride=1,
scale=scale, scale=scale)
name="conv5" + "_" + str(i + 1))
# 7x7 # 7x7
input = self.depthwise_separable( input = self.depthwise_separable(
input, input,
...@@ -109,8 +101,7 @@ class MobileNet(): ...@@ -109,8 +101,7 @@ class MobileNet():
num_filters2=1024, num_filters2=1024,
num_groups=512, num_groups=512,
stride=2, stride=2,
scale=scale, scale=scale)
name="conv5_6")
input = self.depthwise_separable( input = self.depthwise_separable(
input, input,
...@@ -118,8 +109,7 @@ class MobileNet(): ...@@ -118,8 +109,7 @@ class MobileNet():
num_filters2=1024, num_filters2=1024,
num_groups=1024, num_groups=1024,
stride=1, stride=1,
scale=scale, scale=scale)
name="conv6")
input = fluid.layers.pool2d( input = fluid.layers.pool2d(
input=input, input=input,
...@@ -130,9 +120,7 @@ class MobileNet(): ...@@ -130,9 +120,7 @@ class MobileNet():
output = fluid.layers.fc(input=input, output = fluid.layers.fc(input=input,
size=class_dim, size=class_dim,
param_attr=ParamAttr( param_attr=ParamAttr(initializer=MSRA()))
initializer=MSRA(), name="fc7_weights"),
bias_attr=ParamAttr(name="fc7_offset"))
return output return output
def conv_bn_layer(self, def conv_bn_layer(self,
...@@ -144,8 +132,7 @@ class MobileNet(): ...@@ -144,8 +132,7 @@ class MobileNet():
channels=None, channels=None,
num_groups=1, num_groups=1,
act='relu', act='relu',
use_cudnn=True, use_cudnn=True):
name=None):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
...@@ -155,26 +142,12 @@ class MobileNet(): ...@@ -155,26 +142,12 @@ class MobileNet():
groups=num_groups, groups=num_groups,
act=None, act=None,
use_cudnn=use_cudnn, use_cudnn=use_cudnn,
param_attr=ParamAttr( param_attr=ParamAttr(initializer=MSRA()),
initializer=MSRA(), name=name + "_weights"),
bias_attr=False) bias_attr=False)
bn_name = name + "_bn" return fluid.layers.batch_norm(input=conv, act=act)
return fluid.layers.batch_norm(
input=conv, def depthwise_separable(self, input, num_filters1, num_filters2, num_groups,
act=act, stride, scale):
param_attr=ParamAttr(name=bn_name + "_scale"),
bias_attr=ParamAttr(name=bn_name + "_offset"),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
def depthwise_separable(self,
input,
num_filters1,
num_filters2,
num_groups,
stride,
scale,
name=None):
depthwise_conv = self.conv_bn_layer( depthwise_conv = self.conv_bn_layer(
input=input, input=input,
filter_size=3, filter_size=3,
...@@ -182,14 +155,12 @@ class MobileNet(): ...@@ -182,14 +155,12 @@ class MobileNet():
stride=stride, stride=stride,
padding=1, padding=1,
num_groups=int(num_groups * scale), num_groups=int(num_groups * scale),
use_cudnn=False, use_cudnn=False)
name=name + "_dw")
pointwise_conv = self.conv_bn_layer( pointwise_conv = self.conv_bn_layer(
input=depthwise_conv, input=depthwise_conv,
filter_size=1, filter_size=1,
num_filters=int(num_filters2 * scale), num_filters=int(num_filters2 * scale),
stride=1, stride=1,
padding=0, padding=0)
name=name + "_sep")
return pointwise_conv return pointwise_conv
...@@ -36,40 +36,33 @@ class MobileNetV2(): ...@@ -36,40 +36,33 @@ class MobileNetV2():
(6, 320, 1, 1), (6, 320, 1, 1),
] ]
#conv1
input = self.conv_bn_layer( input = self.conv_bn_layer(
input, input,
num_filters=int(32 * scale), num_filters=int(32 * scale),
filter_size=3, filter_size=3,
stride=2, stride=2,
padding=1, padding=1,
if_act=True, if_act=True)
name='conv1_1')
# bottleneck sequences
i = 1
in_c = int(32 * scale) in_c = int(32 * scale)
for layer_setting in bottleneck_params_list: for layer_setting in bottleneck_params_list:
t, c, n, s = layer_setting t, c, n, s = layer_setting
i += 1
input = self.invresi_blocks( input = self.invresi_blocks(
input=input, input=input,
in_c=in_c, in_c=in_c,
t=t, t=t,
c=int(c * scale), c=int(c * scale),
n=n, n=n,
s=s, s=s, )
name='conv' + str(i))
in_c = int(c * scale) in_c = int(c * scale)
#last_conv
input = self.conv_bn_layer( input = self.conv_bn_layer(
input=input, input=input,
num_filters=int(1280 * scale) if scale > 1.0 else 1280, num_filters=int(1280 * scale) if scale > 1.0 else 1280,
filter_size=1, filter_size=1,
stride=1, stride=1,
padding=0, padding=0,
if_act=True, if_act=True)
name='conv9')
input = fluid.layers.pool2d( input = fluid.layers.pool2d(
input=input, input=input,
...@@ -80,8 +73,7 @@ class MobileNetV2(): ...@@ -80,8 +73,7 @@ class MobileNetV2():
output = fluid.layers.fc(input=input, output = fluid.layers.fc(input=input,
size=class_dim, size=class_dim,
param_attr=ParamAttr(name='fc10_weights'), param_attr=ParamAttr(initializer=MSRA()))
bias_attr=ParamAttr(name='fc10_offset'))
return output return output
def conv_bn_layer(self, def conv_bn_layer(self,
...@@ -92,9 +84,8 @@ class MobileNetV2(): ...@@ -92,9 +84,8 @@ class MobileNetV2():
padding, padding,
channels=None, channels=None,
num_groups=1, num_groups=1,
if_act=True, use_cudnn=True,
name=None, if_act=True):
use_cudnn=True):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
...@@ -104,15 +95,9 @@ class MobileNetV2(): ...@@ -104,15 +95,9 @@ class MobileNetV2():
groups=num_groups, groups=num_groups,
act=None, act=None,
use_cudnn=use_cudnn, use_cudnn=use_cudnn,
param_attr=ParamAttr(name=name + '_weights'), param_attr=ParamAttr(initializer=MSRA()),
bias_attr=False) bias_attr=False)
bn_name = name + '_bn' bn = fluid.layers.batch_norm(input=conv)
bn = fluid.layers.batch_norm(
input=conv,
param_attr=ParamAttr(name=bn_name + "_scale"),
bias_attr=ParamAttr(name=bn_name + "_offset"),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
if if_act: if if_act:
return fluid.layers.relu6(bn) return fluid.layers.relu6(bn)
else: else:
...@@ -121,18 +106,10 @@ class MobileNetV2(): ...@@ -121,18 +106,10 @@ class MobileNetV2():
def shortcut(self, input, data_residual): def shortcut(self, input, data_residual):
return fluid.layers.elementwise_add(input, data_residual) return fluid.layers.elementwise_add(input, data_residual)
def inverted_residual_unit(self, def inverted_residual_unit(self, input, num_in_filter, num_filters,
input, ifshortcut, stride, filter_size, padding,
num_in_filter, expansion_factor):
num_filters,
ifshortcut,
stride,
filter_size,
padding,
expansion_factor,
name=None):
num_expfilter = int(round(num_in_filter * expansion_factor)) num_expfilter = int(round(num_in_filter * expansion_factor))
channel_expand = self.conv_bn_layer( channel_expand = self.conv_bn_layer(
input=input, input=input,
num_filters=num_expfilter, num_filters=num_expfilter,
...@@ -140,9 +117,7 @@ class MobileNetV2(): ...@@ -140,9 +117,7 @@ class MobileNetV2():
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True, if_act=True)
name=name + '_expand')
bottleneck_conv = self.conv_bn_layer( bottleneck_conv = self.conv_bn_layer(
input=channel_expand, input=channel_expand,
num_filters=num_expfilter, num_filters=num_expfilter,
...@@ -151,9 +126,7 @@ class MobileNetV2(): ...@@ -151,9 +126,7 @@ class MobileNetV2():
padding=padding, padding=padding,
num_groups=num_expfilter, num_groups=num_expfilter,
if_act=True, if_act=True,
name=name + '_dwise',
use_cudnn=False) use_cudnn=False)
linear_out = self.conv_bn_layer( linear_out = self.conv_bn_layer(
input=bottleneck_conv, input=bottleneck_conv,
num_filters=num_filters, num_filters=num_filters,
...@@ -161,15 +134,14 @@ class MobileNetV2(): ...@@ -161,15 +134,14 @@ class MobileNetV2():
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=False, if_act=False)
name=name + '_linear')
if ifshortcut: if ifshortcut:
out = self.shortcut(input=input, data_residual=linear_out) out = self.shortcut(input=input, data_residual=linear_out)
return out return out
else: else:
return linear_out return linear_out
def invresi_blocks(self, input, in_c, t, c, n, s, name=None): def invresi_blocks(self, input, in_c, t, c, n, s):
first_block = self.inverted_residual_unit( first_block = self.inverted_residual_unit(
input=input, input=input,
num_in_filter=in_c, num_in_filter=in_c,
...@@ -178,8 +150,7 @@ class MobileNetV2(): ...@@ -178,8 +150,7 @@ class MobileNetV2():
stride=s, stride=s,
filter_size=3, filter_size=3,
padding=1, padding=1,
expansion_factor=t, expansion_factor=t)
name=name + '_1')
last_residual_block = first_block last_residual_block = first_block
last_c = c last_c = c
...@@ -193,6 +164,5 @@ class MobileNetV2(): ...@@ -193,6 +164,5 @@ class MobileNetV2():
stride=1, stride=1,
filter_size=3, filter_size=3,
padding=1, padding=1,
expansion_factor=t, expansion_factor=t)
name=name + '_' + str(i + 1))
return last_residual_block return last_residual_block
...@@ -4,7 +4,6 @@ from __future__ import print_function ...@@ -4,7 +4,6 @@ from __future__ import print_function
import paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import math import math
from paddle.fluid.param_attr import ParamAttr
__all__ = ["ResNet", "ResNet50", "ResNet101", "ResNet152"] __all__ = ["ResNet", "ResNet50", "ResNet101", "ResNet152"]
...@@ -41,12 +40,7 @@ class ResNet(): ...@@ -41,12 +40,7 @@ class ResNet():
num_filters = [64, 128, 256, 512] num_filters = [64, 128, 256, 512]
conv = self.conv_bn_layer( conv = self.conv_bn_layer(
input=input, input=input, num_filters=64, filter_size=7, stride=2, act='relu')
num_filters=64,
filter_size=7,
stride=2,
act='relu',
name="conv1")
conv = fluid.layers.pool2d( conv = fluid.layers.pool2d(
input=conv, input=conv,
pool_size=3, pool_size=3,
...@@ -56,18 +50,10 @@ class ResNet(): ...@@ -56,18 +50,10 @@ class ResNet():
for block in range(len(depth)): for block in range(len(depth)):
for i in range(depth[block]): for i in range(depth[block]):
if layers in [101, 152] and block == 2:
if i == 0:
conv_name = "res" + str(block + 2) + "a"
else:
conv_name = "res" + str(block + 2) + "b" + str(i)
else:
conv_name = "res" + str(block + 2) + chr(97 + i)
conv = self.bottleneck_block( conv = self.bottleneck_block(
input=conv, input=conv,
num_filters=num_filters[block], num_filters=num_filters[block],
stride=2 if i == 0 and block != 0 else 1, stride=2 if i == 0 and block != 0 else 1)
name=conv_name)
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=conv, pool_size=7, pool_type='avg', global_pooling=True) input=conv, pool_size=7, pool_type='avg', global_pooling=True)
...@@ -85,8 +71,7 @@ class ResNet(): ...@@ -85,8 +71,7 @@ class ResNet():
filter_size, filter_size,
stride=1, stride=1,
groups=1, groups=1,
act=None, act=None):
name=None):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
...@@ -95,55 +80,31 @@ class ResNet(): ...@@ -95,55 +80,31 @@ class ResNet():
padding=(filter_size - 1) // 2, padding=(filter_size - 1) // 2,
groups=groups, groups=groups,
act=None, act=None,
param_attr=ParamAttr(name=name + "_weights"), bias_attr=False)
bias_attr=False, return fluid.layers.batch_norm(input=conv, act=act)
name=name + '.conv2d.output.1')
if name == "conv1": def shortcut(self, input, ch_out, stride):
bn_name = "bn_" + name
else:
bn_name = "bn" + name[3:]
return fluid.layers.batch_norm(
input=conv,
act=act,
name=bn_name + '.output.1',
param_attr=ParamAttr(name=bn_name + '_scale'),
bias_attr=ParamAttr(bn_name + '_offset'),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance', )
def shortcut(self, input, ch_out, stride, name):
ch_in = input.shape[1] ch_in = input.shape[1]
if ch_in != ch_out or stride != 1: if ch_in != ch_out or stride != 1:
return self.conv_bn_layer(input, ch_out, 1, stride, name=name) return self.conv_bn_layer(input, ch_out, 1, stride)
else: else:
return input return input
def bottleneck_block(self, input, num_filters, stride, name): def bottleneck_block(self, input, num_filters, stride):
conv0 = self.conv_bn_layer( conv0 = self.conv_bn_layer(
input=input, input=input, num_filters=num_filters, filter_size=1, act='relu')
num_filters=num_filters,
filter_size=1,
act='relu',
name=name + "_branch2a")
conv1 = self.conv_bn_layer( conv1 = self.conv_bn_layer(
input=conv0, input=conv0,
num_filters=num_filters, num_filters=num_filters,
filter_size=3, filter_size=3,
stride=stride, stride=stride,
act='relu', act='relu')
name=name + "_branch2b")
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(
input=conv1, input=conv1, num_filters=num_filters * 4, filter_size=1, act=None)
num_filters=num_filters * 4,
filter_size=1,
act=None,
name=name + "_branch2c")
short = self.shortcut( short = self.shortcut(input, num_filters * 4, stride)
input, num_filters * 4, stride, name=name + "_branch1")
return fluid.layers.elementwise_add( return fluid.layers.elementwise_add(x=short, y=conv2, act='relu')
x=short, y=conv2, act='relu', name=name + ".add.output.5")
def ResNet50(): def ResNet50():
......
...@@ -4,7 +4,6 @@ from __future__ import print_function ...@@ -4,7 +4,6 @@ from __future__ import print_function
import paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import math import math
from paddle.fluid.param_attr import ParamAttr
__all__ = [ __all__ = [
"SE_ResNeXt", "SE_ResNeXt50_32x4d", "SE_ResNeXt101_32x4d", "SE_ResNeXt", "SE_ResNeXt50_32x4d", "SE_ResNeXt101_32x4d",
...@@ -19,7 +18,7 @@ train_parameters = { ...@@ -19,7 +18,7 @@ train_parameters = {
"learning_strategy": { "learning_strategy": {
"name": "piecewise_decay", "name": "piecewise_decay",
"batch_size": 256, "batch_size": 256,
"epochs": [40, 80, 100], "epochs": [30, 60, 90],
"steps": [0.1, 0.01, 0.001, 0.0001] "steps": [0.1, 0.01, 0.001, 0.0001]
} }
} }
...@@ -46,8 +45,7 @@ class SE_ResNeXt(): ...@@ -46,8 +45,7 @@ class SE_ResNeXt():
num_filters=64, num_filters=64,
filter_size=7, filter_size=7,
stride=2, stride=2,
act='relu', act='relu')
name='conv1', )
conv = fluid.layers.pool2d( conv = fluid.layers.pool2d(
input=conv, input=conv,
pool_size=3, pool_size=3,
...@@ -65,8 +63,7 @@ class SE_ResNeXt(): ...@@ -65,8 +63,7 @@ class SE_ResNeXt():
num_filters=64, num_filters=64,
filter_size=7, filter_size=7,
stride=2, stride=2,
act='relu', act='relu')
name="conv1", )
conv = fluid.layers.pool2d( conv = fluid.layers.pool2d(
input=conv, input=conv,
pool_size=3, pool_size=3,
...@@ -84,94 +81,67 @@ class SE_ResNeXt(): ...@@ -84,94 +81,67 @@ class SE_ResNeXt():
num_filters=64, num_filters=64,
filter_size=3, filter_size=3,
stride=2, stride=2,
act='relu', act='relu')
name='conv1')
conv = self.conv_bn_layer( conv = self.conv_bn_layer(
input=conv, input=conv, num_filters=64, filter_size=3, stride=1, act='relu')
num_filters=64,
filter_size=3,
stride=1,
act='relu',
name='conv2')
conv = self.conv_bn_layer( conv = self.conv_bn_layer(
input=conv, input=conv,
num_filters=128, num_filters=128,
filter_size=3, filter_size=3,
stride=1, stride=1,
act='relu', act='relu')
name='conv3')
conv = fluid.layers.pool2d( conv = fluid.layers.pool2d(
input=conv, pool_size=3, pool_stride=2, pool_padding=1, \ input=conv, pool_size=3, pool_stride=2, pool_padding=1, \
pool_type='max') pool_type='max')
n = 1 if layers == 50 or layers == 101 else 3
for block in range(len(depth)): for block in range(len(depth)):
n += 1
for i in range(depth[block]): for i in range(depth[block]):
conv = self.bottleneck_block( conv = self.bottleneck_block(
input=conv, input=conv,
num_filters=num_filters[block], num_filters=num_filters[block],
stride=2 if i == 0 and block != 0 else 1, stride=2 if i == 0 and block != 0 else 1,
cardinality=cardinality, cardinality=cardinality,
reduction_ratio=reduction_ratio, reduction_ratio=reduction_ratio)
name=str(n) + '_' + str(i + 1))
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=conv, pool_size=7, pool_type='avg', global_pooling=True) input=conv, pool_size=7, pool_type='avg', global_pooling=True)
drop = fluid.layers.dropout( drop = fluid.layers.dropout(
x=pool, dropout_prob=0.5, seed=self.params['dropout_seed']) x=pool, dropout_prob=0.5, seed=self.params['dropout_seed'])
stdv = 1.0 / math.sqrt(drop.shape[1] * 1.0) stdv = 1.0 / math.sqrt(drop.shape[1] * 1.0)
out = fluid.layers.fc( out = fluid.layers.fc(input=drop,
input=drop, size=class_dim,
size=class_dim, param_attr=fluid.param_attr.ParamAttr(
param_attr=ParamAttr( initializer=fluid.initializer.Uniform(-stdv,
initializer=fluid.initializer.Uniform(-stdv, stdv), stdv)))
name='fc6_weights'),
bias_attr=ParamAttr(name='fc6_offset'))
return out return out
def shortcut(self, input, ch_out, stride, name): def shortcut(self, input, ch_out, stride):
ch_in = input.shape[1] ch_in = input.shape[1]
if ch_in != ch_out or stride != 1: if ch_in != ch_out or stride != 1:
filter_size = 1 filter_size = 1
return self.conv_bn_layer( return self.conv_bn_layer(input, ch_out, filter_size, stride)
input, ch_out, filter_size, stride, name='conv' + name + '_prj')
else: else:
return input return input
def bottleneck_block(self, def bottleneck_block(self, input, num_filters, stride, cardinality,
input, reduction_ratio):
num_filters,
stride,
cardinality,
reduction_ratio,
name=None):
conv0 = self.conv_bn_layer( conv0 = self.conv_bn_layer(
input=input, input=input, num_filters=num_filters, filter_size=1, act='relu')
num_filters=num_filters,
filter_size=1,
act='relu',
name='conv' + name + '_x1')
conv1 = self.conv_bn_layer( conv1 = self.conv_bn_layer(
input=conv0, input=conv0,
num_filters=num_filters, num_filters=num_filters,
filter_size=3, filter_size=3,
stride=stride, stride=stride,
groups=cardinality, groups=cardinality,
act='relu', act='relu')
name='conv' + name + '_x2')
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(
input=conv1, input=conv1, num_filters=num_filters * 2, filter_size=1, act=None)
num_filters=num_filters * 2,
filter_size=1,
act=None,
name='conv' + name + '_x3')
scale = self.squeeze_excitation( scale = self.squeeze_excitation(
input=conv2, input=conv2,
num_channels=num_filters * 2, num_channels=num_filters * 2,
reduction_ratio=reduction_ratio, reduction_ratio=reduction_ratio)
name='fc' + name)
short = self.shortcut(input, num_filters * 2, stride, name=name) short = self.shortcut(input, num_filters * 2, stride)
return fluid.layers.elementwise_add(x=short, y=scale, act='relu') return fluid.layers.elementwise_add(x=short, y=scale, act='relu')
...@@ -181,8 +151,7 @@ class SE_ResNeXt(): ...@@ -181,8 +151,7 @@ class SE_ResNeXt():
filter_size, filter_size,
stride=1, stride=1,
groups=1, groups=1,
act=None, act=None):
name=None):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
...@@ -191,42 +160,26 @@ class SE_ResNeXt(): ...@@ -191,42 +160,26 @@ class SE_ResNeXt():
padding=(filter_size - 1) // 2, padding=(filter_size - 1) // 2,
groups=groups, groups=groups,
act=None, act=None,
bias_attr=False, bias_attr=False)
param_attr=ParamAttr(name=name + '_weights'), ) return fluid.layers.batch_norm(input=conv, act=act)
bn_name = name + "_bn"
return fluid.layers.batch_norm( def squeeze_excitation(self, input, num_channels, reduction_ratio):
input=conv,
act=act,
param_attr=ParamAttr(name=bn_name + '_scale'),
bias_attr=ParamAttr(bn_name + '_offset'),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
def squeeze_excitation(self,
input,
num_channels,
reduction_ratio,
name=None):
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=input, pool_size=0, pool_type='avg', global_pooling=True) input=input, pool_size=0, pool_type='avg', global_pooling=True)
stdv = 1.0 / math.sqrt(pool.shape[1] * 1.0) stdv = 1.0 / math.sqrt(pool.shape[1] * 1.0)
squeeze = fluid.layers.fc( squeeze = fluid.layers.fc(input=pool,
input=pool, size=num_channels // reduction_ratio,
size=num_channels // reduction_ratio, act='relu',
act='relu', param_attr=fluid.param_attr.ParamAttr(
param_attr=fluid.param_attr.ParamAttr( initializer=fluid.initializer.Uniform(
initializer=fluid.initializer.Uniform(-stdv, stdv), -stdv, stdv)))
name=name + '_sqz_weights'),
bias_attr=ParamAttr(name=name + '_sqz_offset'))
stdv = 1.0 / math.sqrt(squeeze.shape[1] * 1.0) stdv = 1.0 / math.sqrt(squeeze.shape[1] * 1.0)
excitation = fluid.layers.fc( excitation = fluid.layers.fc(input=squeeze,
input=squeeze, size=num_channels,
size=num_channels, act='sigmoid',
act='sigmoid', param_attr=fluid.param_attr.ParamAttr(
param_attr=fluid.param_attr.ParamAttr( initializer=fluid.initializer.Uniform(
initializer=fluid.initializer.Uniform(-stdv, stdv), -stdv, stdv)))
name=name + '_exc_weights'),
bias_attr=ParamAttr(name=name + '_exc_offset'))
scale = fluid.layers.elementwise_mul(x=input, y=excitation, axis=0) scale = fluid.layers.elementwise_mul(x=input, y=excitation, axis=0)
return scale return scale
......
...@@ -52,8 +52,7 @@ class ShuffleNetV2(): ...@@ -52,8 +52,7 @@ class ShuffleNetV2():
filter_size=3, filter_size=3,
num_filters=input_channel, num_filters=input_channel,
padding=1, padding=1,
stride=2, stride=2)
name='stage1_conv')
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=conv1, input=conv1,
pool_size=3, pool_size=3,
...@@ -71,35 +70,30 @@ class ShuffleNetV2(): ...@@ -71,35 +70,30 @@ class ShuffleNetV2():
input=conv, input=conv,
num_filters=output_channel, num_filters=output_channel,
stride=2, stride=2,
benchmodel=2, benchmodel=2)
name=str(idxstage + 2) + '_' + str(i + 1))
else: else:
conv = self.inverted_residual_unit( conv = self.inverted_residual_unit(
input=conv, input=conv,
num_filters=output_channel, num_filters=output_channel,
stride=1, stride=1,
benchmodel=1, benchmodel=1)
name=str(idxstage + 2) + '_' + str(i + 1))
conv_last = self.conv_bn_layer( conv_last = self.conv_bn_layer(
input=conv, input=conv,
filter_size=1, filter_size=1,
num_filters=stage_out_channels[-1], num_filters=stage_out_channels[-1],
padding=0, padding=0,
stride=1, stride=1)
name='conv5')
pool_last = fluid.layers.pool2d( pool_last = fluid.layers.pool2d(
input=conv_last, input=conv_last,
pool_size=7, pool_size=7,
pool_stride=1, pool_stride=7,
pool_padding=0, pool_padding=0,
pool_type='avg') pool_type='avg')
output = fluid.layers.fc(input=pool_last, output = fluid.layers.fc(input=pool_last,
size=class_dim, size=class_dim,
param_attr=ParamAttr( param_attr=ParamAttr(initializer=MSRA()))
initializer=MSRA(), name='fc6_weights'),
bias_attr=ParamAttr(name='fc6_offset'))
return output return output
def conv_bn_layer(self, def conv_bn_layer(self,
...@@ -110,9 +104,7 @@ class ShuffleNetV2(): ...@@ -110,9 +104,7 @@ class ShuffleNetV2():
padding, padding,
num_groups=1, num_groups=1,
use_cudnn=True, use_cudnn=True,
if_act=True, if_act=True):
name=None):
# print(num_groups)
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
...@@ -122,25 +114,12 @@ class ShuffleNetV2(): ...@@ -122,25 +114,12 @@ class ShuffleNetV2():
groups=num_groups, groups=num_groups,
act=None, act=None,
use_cudnn=use_cudnn, use_cudnn=use_cudnn,
param_attr=ParamAttr( param_attr=ParamAttr(initializer=MSRA()),
initializer=MSRA(), name=name + '_weights'),
bias_attr=False) bias_attr=False)
bn_name = name + '_bn'
if if_act: if if_act:
return fluid.layers.batch_norm( return fluid.layers.batch_norm(input=conv, act='relu')
input=conv,
act='relu',
param_attr=ParamAttr(name=bn_name + "_scale"),
bias_attr=ParamAttr(name=bn_name + "_offset"),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
else: else:
return fluid.layers.batch_norm( return fluid.layers.batch_norm(input=conv)
input=conv,
param_attr=ParamAttr(name=bn_name + "_scale"),
bias_attr=ParamAttr(name=bn_name + "_offset"),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
def channel_shuffle(self, x, groups): def channel_shuffle(self, x, groups):
batchsize, num_channels, height, width = x.shape[0], x.shape[ batchsize, num_channels, height, width = x.shape[0], x.shape[
...@@ -159,12 +138,7 @@ class ShuffleNetV2(): ...@@ -159,12 +138,7 @@ class ShuffleNetV2():
return x return x
def inverted_residual_unit(self, def inverted_residual_unit(self, input, num_filters, stride, benchmodel):
input,
num_filters,
stride,
benchmodel,
name=None):
assert stride in [1, 2], \ assert stride in [1, 2], \
"supported stride are {} but your stride is {}".format([1,2], stride) "supported stride are {} but your stride is {}".format([1,2], stride)
...@@ -176,8 +150,6 @@ class ShuffleNetV2(): ...@@ -176,8 +150,6 @@ class ShuffleNetV2():
input, input,
num_or_sections=[input.shape[1] // 2, input.shape[1] // 2], num_or_sections=[input.shape[1] // 2, input.shape[1] // 2],
dim=1) dim=1)
# x1 = input[:, :(input.shape[1]//2), :, :]
# x2 = input[:, (input.shape[1]//2):, :, :]
conv_pw = self.conv_bn_layer( conv_pw = self.conv_bn_layer(
input=x2, input=x2,
...@@ -186,8 +158,7 @@ class ShuffleNetV2(): ...@@ -186,8 +158,7 @@ class ShuffleNetV2():
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True, if_act=True)
name='stage_' + name + '_conv1')
conv_dw = self.conv_bn_layer( conv_dw = self.conv_bn_layer(
input=conv_pw, input=conv_pw,
...@@ -196,8 +167,7 @@ class ShuffleNetV2(): ...@@ -196,8 +167,7 @@ class ShuffleNetV2():
stride=stride, stride=stride,
padding=1, padding=1,
num_groups=oup_inc, num_groups=oup_inc,
if_act=False, if_act=False)
name='stage_' + name + '_conv2')
conv_linear = self.conv_bn_layer( conv_linear = self.conv_bn_layer(
input=conv_dw, input=conv_dw,
...@@ -206,63 +176,57 @@ class ShuffleNetV2(): ...@@ -206,63 +176,57 @@ class ShuffleNetV2():
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True, if_act=True)
name='stage_' + name + '_conv3')
out = fluid.layers.concat([x1, conv_linear], axis=1) out = fluid.layers.concat([x1, conv_linear], axis=1)
else: else:
#branch1 #branch1
conv_dw_1 = self.conv_bn_layer( conv_dw = self.conv_bn_layer(
input=input, input=input,
num_filters=inp, num_filters=inp,
filter_size=3, filter_size=3,
stride=stride, stride=stride,
padding=1, padding=1,
num_groups=inp, num_groups=inp,
if_act=False, if_act=False)
name='stage_' + name + '_conv4')
conv_linear_1 = self.conv_bn_layer( conv_linear_1 = self.conv_bn_layer(
input=conv_dw_1, input=conv_dw,
num_filters=oup_inc, num_filters=oup_inc,
filter_size=1, filter_size=1,
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True, if_act=True)
name='stage_' + name + '_conv5')
#branch2 #branch2
conv_pw_2 = self.conv_bn_layer( conv_pw = self.conv_bn_layer(
input=input, input=input,
num_filters=oup_inc, num_filters=oup_inc,
filter_size=1, filter_size=1,
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True, if_act=True)
name='stage_' + name + '_conv1')
conv_dw_2 = self.conv_bn_layer( conv_dw = self.conv_bn_layer(
input=conv_pw_2, input=conv_pw,
num_filters=oup_inc, num_filters=oup_inc,
filter_size=3, filter_size=3,
stride=stride, stride=stride,
padding=1, padding=1,
num_groups=oup_inc, num_groups=oup_inc,
if_act=False, if_act=False)
name='stage_' + name + '_conv2')
conv_linear_2 = self.conv_bn_layer( conv_linear_2 = self.conv_bn_layer(
input=conv_dw_2, input=conv_dw,
num_filters=oup_inc, num_filters=oup_inc,
filter_size=1, filter_size=1,
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True, if_act=True)
name='stage_' + name + '_conv3')
out = fluid.layers.concat([conv_linear_1, conv_linear_2], axis=1) out = fluid.layers.concat([conv_linear_1, conv_linear_2], axis=1)
return self.channel_shuffle(out, 2) return self.channel_shuffle(out, 2)
......
...@@ -36,37 +36,42 @@ class VGGNet(): ...@@ -36,37 +36,42 @@ class VGGNet():
"supported layers are {} but input layer is {}".format(vgg_spec.keys(), layers) "supported layers are {} but input layer is {}".format(vgg_spec.keys(), layers)
nums = vgg_spec[layers] nums = vgg_spec[layers]
conv1 = self.conv_block(input, 64, nums[0], name="conv1_") conv1 = self.conv_block(input, 64, nums[0])
conv2 = self.conv_block(conv1, 128, nums[1], name="conv2_") conv2 = self.conv_block(conv1, 128, nums[1])
conv3 = self.conv_block(conv2, 256, nums[2], name="conv3_") conv3 = self.conv_block(conv2, 256, nums[2])
conv4 = self.conv_block(conv3, 512, nums[3], name="conv4_") conv4 = self.conv_block(conv3, 512, nums[3])
conv5 = self.conv_block(conv4, 512, nums[4], name="conv5_") conv5 = self.conv_block(conv4, 512, nums[4])
fc_dim = 4096 fc_dim = 4096
fc_name = ["fc6", "fc7", "fc8"]
fc1 = fluid.layers.fc( fc1 = fluid.layers.fc(
input=conv5, input=conv5,
size=fc_dim, size=fc_dim,
act='relu', act='relu',
param_attr=fluid.param_attr.ParamAttr(name=fc_name[0] + "_weights"), param_attr=fluid.param_attr.ParamAttr(
bias_attr=fluid.param_attr.ParamAttr(name=fc_name[0] + "_offset")) initializer=fluid.initializer.Normal(scale=0.005)),
bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Constant(value=0.1)))
fc1 = fluid.layers.dropout(x=fc1, dropout_prob=0.5) fc1 = fluid.layers.dropout(x=fc1, dropout_prob=0.5)
fc2 = fluid.layers.fc( fc2 = fluid.layers.fc(
input=fc1, input=fc1,
size=fc_dim, size=fc_dim,
act='relu', act='relu',
param_attr=fluid.param_attr.ParamAttr(name=fc_name[1] + "_weights"), param_attr=fluid.param_attr.ParamAttr(
bias_attr=fluid.param_attr.ParamAttr(name=fc_name[1] + "_offset")) initializer=fluid.initializer.Normal(scale=0.005)),
bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Constant(value=0.1)))
fc2 = fluid.layers.dropout(x=fc2, dropout_prob=0.5) fc2 = fluid.layers.dropout(x=fc2, dropout_prob=0.5)
out = fluid.layers.fc( out = fluid.layers.fc(
input=fc2, input=fc2,
size=class_dim, size=class_dim,
param_attr=fluid.param_attr.ParamAttr(name=fc_name[2] + "_weights"), param_attr=fluid.param_attr.ParamAttr(
bias_attr=fluid.param_attr.ParamAttr(name=fc_name[2] + "_offset")) initializer=fluid.initializer.Normal(scale=0.005)),
bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Constant(value=0.1)))
return out return out
def conv_block(self, input, num_filter, groups, name=None): def conv_block(self, input, num_filter, groups):
conv = input conv = input
for i in range(groups): for i in range(groups):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
...@@ -77,9 +82,9 @@ class VGGNet(): ...@@ -77,9 +82,9 @@ class VGGNet():
padding=1, padding=1,
act='relu', act='relu',
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
name=name + str(i + 1) + "_weights"), initializer=fluid.initializer.Normal(scale=0.01)),
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
name=name + str(i + 1) + "_offset")) initializer=fluid.initializer.Constant(value=0.0)))
return fluid.layers.pool2d( return fluid.layers.pool2d(
input=conv, pool_size=2, pool_type='max', pool_stride=2) input=conv, pool_size=2, pool_type='max', pool_stride=2)
......
...@@ -3,10 +3,10 @@ from .mobilenet import MobileNet ...@@ -3,10 +3,10 @@ from .mobilenet import MobileNet
from .mobilenet_v2 import MobileNetV2 from .mobilenet_v2 import MobileNetV2
from .googlenet import GoogleNet from .googlenet import GoogleNet
from .vgg import VGG11, VGG13, VGG16, VGG19 from .vgg import VGG11, VGG13, VGG16, VGG19
from .resnet import ResNet50, ResNet101, ResNet152 from .resnet import ResNet18, ResNet34, ResNet50, ResNet101, ResNet152
from .resnet_dist import DistResNet from .resnet_dist import DistResNet
from .inception_v4 import InceptionV4 from .inception_v4 import InceptionV4
from .se_resnext import SE_ResNeXt50_32x4d, SE_ResNeXt101_32x4d, SE_ResNeXt152_32x4d from .se_resnext import SE_ResNeXt50_32x4d, SE_ResNeXt101_32x4d, SE_ResNeXt152_32x4d
from .dpn import DPN68, DPN92, DPN98, DPN107, DPN131 from .dpn import DPN68, DPN92, DPN98, DPN107, DPN131
from .shufflenet_v2 import ShuffleNetV2_x0_5, ShuffleNetV2_x1_0, ShuffleNetV2_x1_5, ShuffleNetV2_x2_0 from .shufflenet_v2 import ShuffleNetV2, ShuffleNetV2_x0_5_swish, ShuffleNetV2_x1_0_swish, ShuffleNetV2_x1_5_swish, ShuffleNetV2_x2_0_swish, ShuffleNetV2_x8_0_swish
from .fast_imagenet import FastImageNet from .fast_imagenet import FastImageNet
...@@ -26,6 +26,9 @@ class AlexNet(): ...@@ -26,6 +26,9 @@ class AlexNet():
def net(self, input, class_dim=1000): def net(self, input, class_dim=1000):
stdv = 1.0 / math.sqrt(input.shape[1] * 11 * 11) stdv = 1.0 / math.sqrt(input.shape[1] * 11 * 11)
layer_name = [
"conv1", "conv2", "conv3", "conv4", "conv5", "fc6", "fc7", "fc8"
]
conv1 = fluid.layers.conv2d( conv1 = fluid.layers.conv2d(
input=input, input=input,
num_filters=64, num_filters=64,
...@@ -35,9 +38,11 @@ class AlexNet(): ...@@ -35,9 +38,11 @@ class AlexNet():
groups=1, groups=1,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)), initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[0] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[0] + "_weights"))
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=conv1, input=conv1,
pool_size=3, pool_size=3,
...@@ -55,9 +60,11 @@ class AlexNet(): ...@@ -55,9 +60,11 @@ class AlexNet():
groups=1, groups=1,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)), initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[1] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[1] + "_weights"))
pool2 = fluid.layers.pool2d( pool2 = fluid.layers.pool2d(
input=conv2, input=conv2,
pool_size=3, pool_size=3,
...@@ -75,9 +82,11 @@ class AlexNet(): ...@@ -75,9 +82,11 @@ class AlexNet():
groups=1, groups=1,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)), initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[2] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[2] + "_weights"))
stdv = 1.0 / math.sqrt(conv3.shape[1] * 3 * 3) stdv = 1.0 / math.sqrt(conv3.shape[1] * 3 * 3)
conv4 = fluid.layers.conv2d( conv4 = fluid.layers.conv2d(
...@@ -89,9 +98,11 @@ class AlexNet(): ...@@ -89,9 +98,11 @@ class AlexNet():
groups=1, groups=1,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)), initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[3] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[3] + "_weights"))
stdv = 1.0 / math.sqrt(conv4.shape[1] * 3 * 3) stdv = 1.0 / math.sqrt(conv4.shape[1] * 3 * 3)
conv5 = fluid.layers.conv2d( conv5 = fluid.layers.conv2d(
...@@ -103,9 +114,11 @@ class AlexNet(): ...@@ -103,9 +114,11 @@ class AlexNet():
groups=1, groups=1,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)), initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[4] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[4] + "_weights"))
pool5 = fluid.layers.pool2d( pool5 = fluid.layers.pool2d(
input=conv5, input=conv5,
pool_size=3, pool_size=3,
...@@ -114,36 +127,42 @@ class AlexNet(): ...@@ -114,36 +127,42 @@ class AlexNet():
pool_type='max') pool_type='max')
drop6 = fluid.layers.dropout(x=pool5, dropout_prob=0.5) drop6 = fluid.layers.dropout(x=pool5, dropout_prob=0.5)
stdv = 1.0 / math.sqrt(drop6.shape[1] * drop6.shape[2] * stdv = 1.0 / math.sqrt(drop6.shape[1] * drop6.shape[2] *
drop6.shape[3] * 1.0) drop6.shape[3] * 1.0)
fc6 = fluid.layers.fc( fc6 = fluid.layers.fc(
input=drop6, input=drop6,
size=4096, size=4096,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)), initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[5] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[5] + "_weights"))
drop7 = fluid.layers.dropout(x=fc6, dropout_prob=0.5) drop7 = fluid.layers.dropout(x=fc6, dropout_prob=0.5)
stdv = 1.0 / math.sqrt(drop7.shape[1] * 1.0) stdv = 1.0 / math.sqrt(drop7.shape[1] * 1.0)
fc7 = fluid.layers.fc( fc7 = fluid.layers.fc(
input=drop7, input=drop7,
size=4096, size=4096,
act='relu', act='relu',
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)), initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[6] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[6] + "_weights"))
stdv = 1.0 / math.sqrt(fc7.shape[1] * 1.0) stdv = 1.0 / math.sqrt(fc7.shape[1] * 1.0)
out = fluid.layers.fc( out = fluid.layers.fc(
input=fc7, input=fc7,
size=class_dim, size=class_dim,
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)), initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[7] + "_offset"),
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=layer_name[7] + "_weights"))
return out return out
...@@ -7,6 +7,7 @@ import time ...@@ -7,6 +7,7 @@ import time
import sys import sys
import paddle.fluid as fluid import paddle.fluid as fluid
import math import math
from paddle.fluid.param_attr import ParamAttr
__all__ = ["DPN", "DPN68", "DPN92", "DPN98", "DPN107", "DPN131"] __all__ = ["DPN", "DPN68", "DPN92", "DPN98", "DPN107", "DPN131"]
...@@ -52,16 +53,30 @@ class DPN(object): ...@@ -52,16 +53,30 @@ class DPN(object):
padding=init_padding, padding=init_padding,
groups=1, groups=1,
act=None, act=None,
bias_attr=False) bias_attr=False,
name="conv1",
param_attr=ParamAttr(name="conv1_weights"), )
conv1_x_1 = fluid.layers.batch_norm( conv1_x_1 = fluid.layers.batch_norm(
input=conv1_x_1, act='relu', is_test=False) input=conv1_x_1,
act='relu',
is_test=False,
name="conv1_bn",
param_attr=ParamAttr(name='conv1_bn_scale'),
bias_attr=ParamAttr('conv1_bn_offset'),
moving_mean_name='conv1_bn_mean',
moving_variance_name='conv1_bn_variance', )
convX_x_x = fluid.layers.pool2d( convX_x_x = fluid.layers.pool2d(
input=conv1_x_1, input=conv1_x_1,
pool_size=3, pool_size=3,
pool_stride=2, pool_stride=2,
pool_padding=1, pool_padding=1,
pool_type='max') pool_type='max',
name="pool1")
#conv2 - conv5
match_list, num = [], 0
for gc in range(4): for gc in range(4):
bw = bws[gc] bw = bws[gc]
inc = inc_sec[gc] inc = inc_sec[gc]
...@@ -69,32 +84,46 @@ class DPN(object): ...@@ -69,32 +84,46 @@ class DPN(object):
if gc == 0: if gc == 0:
_type1 = 'proj' _type1 = 'proj'
_type2 = 'normal' _type2 = 'normal'
match = 1
else: else:
_type1 = 'down' _type1 = 'down'
_type2 = 'normal' _type2 = 'normal'
convX_x_x = self.dual_path_factory(convX_x_x, R, R, bw, inc, G, match = match + k_sec[gc - 1]
_type1) match_list.append(match)
convX_x_x = self.dual_path_factory(
convX_x_x, R, R, bw, inc, G, _type1, name="dpn" + str(match))
for i_ly in range(2, k_sec[gc] + 1): for i_ly in range(2, k_sec[gc] + 1):
convX_x_x = self.dual_path_factory(convX_x_x, R, R, bw, inc, G, num += 1
_type2) if num in match_list:
num += 1
convX_x_x = self.dual_path_factory(
convX_x_x, R, R, bw, inc, G, _type2, name="dpn" + str(num))
conv5_x_x = fluid.layers.concat(convX_x_x, axis=1) conv5_x_x = fluid.layers.concat(convX_x_x, axis=1)
conv5_x_x = fluid.layers.batch_norm( conv5_x_x = fluid.layers.batch_norm(
input=conv5_x_x, act='relu', is_test=False) input=conv5_x_x,
act='relu',
is_test=False,
name="final_concat_bn",
param_attr=ParamAttr(name='final_concat_bn_scale'),
bias_attr=ParamAttr('final_concat_bn_offset'),
moving_mean_name='final_concat_bn_mean',
moving_variance_name='final_concat_bn_variance', )
pool5 = fluid.layers.pool2d( pool5 = fluid.layers.pool2d(
input=conv5_x_x, input=conv5_x_x,
pool_size=7, pool_size=7,
pool_stride=1, pool_stride=1,
pool_padding=0, pool_padding=0,
pool_type='avg') pool_type='avg', )
#stdv = 1.0 / math.sqrt(pool5.shape[1] * 1.0)
stdv = 0.01 stdv = 0.01
param_attr = fluid.param_attr.ParamAttr( param_attr = fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)) initializer=fluid.initializer.Uniform(-stdv, stdv))
fc6 = fluid.layers.fc(input=pool5, fc6 = fluid.layers.fc(input=pool5,
size=class_dim, size=class_dim,
param_attr=param_attr) param_attr=param_attr,
name="fc6")
return fc6 return fc6
...@@ -172,7 +201,8 @@ class DPN(object): ...@@ -172,7 +201,8 @@ class DPN(object):
num_1x1_c, num_1x1_c,
inc, inc,
G, G,
_type='normal'): _type='normal',
name=None):
kw = 3 kw = 3
kh = 3 kh = 3
pw = (kw - 1) // 2 pw = (kw - 1) // 2
...@@ -201,35 +231,50 @@ class DPN(object): ...@@ -201,35 +231,50 @@ class DPN(object):
num_filter=(num_1x1_c + 2 * inc), num_filter=(num_1x1_c + 2 * inc),
kernel=(1, 1), kernel=(1, 1),
pad=(0, 0), pad=(0, 0),
stride=(key_stride, key_stride)) stride=(key_stride, key_stride),
name=name + "_match")
data_o1, data_o2 = fluid.layers.split( data_o1, data_o2 = fluid.layers.split(
c1x1_w, num_or_sections=[num_1x1_c, 2 * inc], dim=1) c1x1_w,
num_or_sections=[num_1x1_c, 2 * inc],
dim=1,
name=name + "_match_conv_Slice")
else: else:
data_o1 = data[0] data_o1 = data[0]
data_o2 = data[1] data_o2 = data[1]
# MAIN # MAIN
c1x1_a = self.bn_ac_conv( c1x1_a = self.bn_ac_conv(
data=data_in, num_filter=num_1x1_a, kernel=(1, 1), pad=(0, 0)) data=data_in,
num_filter=num_1x1_a,
kernel=(1, 1),
pad=(0, 0),
name=name + "_conv1")
c3x3_b = self.bn_ac_conv( c3x3_b = self.bn_ac_conv(
data=c1x1_a, data=c1x1_a,
num_filter=num_3x3_b, num_filter=num_3x3_b,
kernel=(kw, kh), kernel=(kw, kh),
pad=(pw, ph), pad=(pw, ph),
stride=(key_stride, key_stride), stride=(key_stride, key_stride),
num_group=G) num_group=G,
name=name + "_conv2")
c1x1_c = self.bn_ac_conv( c1x1_c = self.bn_ac_conv(
data=c3x3_b, data=c3x3_b,
num_filter=(num_1x1_c + inc), num_filter=(num_1x1_c + inc),
kernel=(1, 1), kernel=(1, 1),
pad=(0, 0)) pad=(0, 0),
name=name + "_conv3")
c1x1_c1, c1x1_c2 = fluid.layers.split( c1x1_c1, c1x1_c2 = fluid.layers.split(
c1x1_c, num_or_sections=[num_1x1_c, inc], dim=1) c1x1_c,
num_or_sections=[num_1x1_c, inc],
dim=1,
name=name + "_conv3_Slice")
# OUTPUTS # OUTPUTS
summ = fluid.layers.elementwise_add(x=data_o1, y=c1x1_c1) summ = fluid.layers.elementwise_add(
dense = fluid.layers.concat([data_o2, c1x1_c2], axis=1) x=data_o1, y=c1x1_c1, name=name + "_elewise")
dense = fluid.layers.concat(
[data_o2, c1x1_c2], axis=1, name=name + "_concat")
return [summ, dense] return [summ, dense]
...@@ -239,8 +284,17 @@ class DPN(object): ...@@ -239,8 +284,17 @@ class DPN(object):
kernel, kernel,
pad, pad,
stride=(1, 1), stride=(1, 1),
num_group=1): num_group=1,
bn_ac = fluid.layers.batch_norm(input=data, act='relu', is_test=False) name=None):
bn_ac = fluid.layers.batch_norm(
input=data,
act='relu',
is_test=False,
name=name + '.output.1',
param_attr=ParamAttr(name=name + '_bn_scale'),
bias_attr=ParamAttr(name + '_bn_offset'),
moving_mean_name=name + '_bn_mean',
moving_variance_name=name + '_bn_variance', )
bn_ac_conv = fluid.layers.conv2d( bn_ac_conv = fluid.layers.conv2d(
input=bn_ac, input=bn_ac,
num_filters=num_filter, num_filters=num_filter,
...@@ -249,7 +303,8 @@ class DPN(object): ...@@ -249,7 +303,8 @@ class DPN(object):
padding=pad, padding=pad,
groups=num_group, groups=num_group,
act=None, act=None,
bias_attr=False) bias_attr=False,
param_attr=ParamAttr(name=name + "_weights"))
return bn_ac_conv return bn_ac_conv
...@@ -259,7 +314,7 @@ def DPN68(): ...@@ -259,7 +314,7 @@ def DPN68():
def DPN92(): def DPN92():
model = DPN(layers=92) onvodel = DPN(layers=92)
return model return model
......
...@@ -3,6 +3,7 @@ from __future__ import division ...@@ -3,6 +3,7 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
from paddle.fluid.param_attr import ParamAttr
__all__ = ['GoogleNet'] __all__ = ['GoogleNet']
...@@ -29,11 +30,13 @@ class GoogleNet(): ...@@ -29,11 +30,13 @@ class GoogleNet():
filter_size, filter_size,
stride=1, stride=1,
groups=1, groups=1,
act=None): act=None,
name=None):
channels = input.shape[1] channels = input.shape[1]
stdv = (3.0 / (filter_size**2 * channels))**0.5 stdv = (3.0 / (filter_size**2 * channels))**0.5
param_attr = fluid.param_attr.ParamAttr( param_attr = ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=name + "_weights")
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
...@@ -43,43 +46,63 @@ class GoogleNet(): ...@@ -43,43 +46,63 @@ class GoogleNet():
groups=groups, groups=groups,
act=act, act=act,
param_attr=param_attr, param_attr=param_attr,
bias_attr=False) bias_attr=False,
name=name)
return conv return conv
def xavier(self, channels, filter_size): def xavier(self, channels, filter_size, name):
stdv = (3.0 / (filter_size**2 * channels))**0.5 stdv = (3.0 / (filter_size**2 * channels))**0.5
param_attr = fluid.param_attr.ParamAttr( param_attr = ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=name + "_weights")
return param_attr return param_attr
def inception(self, name, input, channels, filter1, filter3R, filter3, def inception(self,
filter5R, filter5, proj): input,
channels,
filter1,
filter3R,
filter3,
filter5R,
filter5,
proj,
name=None):
conv1 = self.conv_layer( conv1 = self.conv_layer(
input=input, num_filters=filter1, filter_size=1, stride=1, act=None) input=input,
num_filters=filter1,
filter_size=1,
stride=1,
act=None,
name="inception_" + name + "_1x1")
conv3r = self.conv_layer( conv3r = self.conv_layer(
input=input, input=input,
num_filters=filter3R, num_filters=filter3R,
filter_size=1, filter_size=1,
stride=1, stride=1,
act=None) act=None,
name="inception_" + name + "_3x3_reduce")
conv3 = self.conv_layer( conv3 = self.conv_layer(
input=conv3r, input=conv3r,
num_filters=filter3, num_filters=filter3,
filter_size=3, filter_size=3,
stride=1, stride=1,
act=None) act=None,
name="inception_" + name + "_3x3")
conv5r = self.conv_layer( conv5r = self.conv_layer(
input=input, input=input,
num_filters=filter5R, num_filters=filter5R,
filter_size=1, filter_size=1,
stride=1, stride=1,
act=None) act=None,
name="inception_" + name + "_5x5_reduce")
conv5 = self.conv_layer( conv5 = self.conv_layer(
input=conv5r, input=conv5r,
num_filters=filter5, num_filters=filter5,
filter_size=5, filter_size=5,
stride=1, stride=1,
act=None) act=None,
name="inception_" + name + "_5x5")
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=input, input=input,
pool_size=3, pool_size=3,
...@@ -87,81 +110,124 @@ class GoogleNet(): ...@@ -87,81 +110,124 @@ class GoogleNet():
pool_padding=1, pool_padding=1,
pool_type='max') pool_type='max')
convprj = fluid.layers.conv2d( convprj = fluid.layers.conv2d(
input=pool, filter_size=1, num_filters=proj, stride=1, padding=0) input=pool,
filter_size=1,
num_filters=proj,
stride=1,
padding=0,
name="inception_" + name + "_3x3_proj",
param_attr=ParamAttr(
name="inception_" + name + "_3x3_proj_weights"),
bias_attr=False)
cat = fluid.layers.concat(input=[conv1, conv3, conv5, convprj], axis=1) cat = fluid.layers.concat(input=[conv1, conv3, conv5, convprj], axis=1)
cat = fluid.layers.relu(cat) cat = fluid.layers.relu(cat)
return cat return cat
def net(self, input, class_dim=1000): def net(self, input, class_dim=1000):
conv = self.conv_layer( conv = self.conv_layer(
input=input, num_filters=64, filter_size=7, stride=2, act=None) input=input,
num_filters=64,
filter_size=7,
stride=2,
act=None,
name="conv1")
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=conv, pool_size=3, pool_type='max', pool_stride=2) input=conv, pool_size=3, pool_type='max', pool_stride=2)
conv = self.conv_layer( conv = self.conv_layer(
input=pool, num_filters=64, filter_size=1, stride=1, act=None) input=pool,
num_filters=64,
filter_size=1,
stride=1,
act=None,
name="conv2_1x1")
conv = self.conv_layer( conv = self.conv_layer(
input=conv, num_filters=192, filter_size=3, stride=1, act=None) input=conv,
num_filters=192,
filter_size=3,
stride=1,
act=None,
name="conv2_3x3")
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=conv, pool_size=3, pool_type='max', pool_stride=2) input=conv, pool_size=3, pool_type='max', pool_stride=2)
ince3a = self.inception("ince3a", pool, 192, 64, 96, 128, 16, 32, 32) ince3a = self.inception(pool, 192, 64, 96, 128, 16, 32, 32, "ince3a")
ince3b = self.inception("ince3b", ince3a, 256, 128, 128, 192, 32, 96, ince3b = self.inception(ince3a, 256, 128, 128, 192, 32, 96, 64,
64) "ince3b")
pool3 = fluid.layers.pool2d( pool3 = fluid.layers.pool2d(
input=ince3b, pool_size=3, pool_type='max', pool_stride=2) input=ince3b, pool_size=3, pool_type='max', pool_stride=2)
ince4a = self.inception("ince4a", pool3, 480, 192, 96, 208, 16, 48, 64) ince4a = self.inception(pool3, 480, 192, 96, 208, 16, 48, 64, "ince4a")
ince4b = self.inception("ince4b", ince4a, 512, 160, 112, 224, 24, 64, ince4b = self.inception(ince4a, 512, 160, 112, 224, 24, 64, 64,
64) "ince4b")
ince4c = self.inception("ince4c", ince4b, 512, 128, 128, 256, 24, 64, ince4c = self.inception(ince4b, 512, 128, 128, 256, 24, 64, 64,
64) "ince4c")
ince4d = self.inception("ince4d", ince4c, 512, 112, 144, 288, 32, 64, ince4d = self.inception(ince4c, 512, 112, 144, 288, 32, 64, 64,
64) "ince4d")
ince4e = self.inception("ince4e", ince4d, 528, 256, 160, 320, 32, 128, ince4e = self.inception(ince4d, 528, 256, 160, 320, 32, 128, 128,
128) "ince4e")
pool4 = fluid.layers.pool2d( pool4 = fluid.layers.pool2d(
input=ince4e, pool_size=3, pool_type='max', pool_stride=2) input=ince4e, pool_size=3, pool_type='max', pool_stride=2)
ince5a = self.inception("ince5a", pool4, 832, 256, 160, 320, 32, 128, ince5a = self.inception(pool4, 832, 256, 160, 320, 32, 128, 128,
128) "ince5a")
ince5b = self.inception("ince5b", ince5a, 832, 384, 192, 384, 48, 128, ince5b = self.inception(ince5a, 832, 384, 192, 384, 48, 128, 128,
128) "ince5b")
pool5 = fluid.layers.pool2d( pool5 = fluid.layers.pool2d(
input=ince5b, pool_size=7, pool_type='avg', pool_stride=7) input=ince5b, pool_size=7, pool_type='avg', pool_stride=7)
dropout = fluid.layers.dropout(x=pool5, dropout_prob=0.4) dropout = fluid.layers.dropout(x=pool5, dropout_prob=0.4)
out = fluid.layers.fc(input=dropout, out = fluid.layers.fc(input=dropout,
size=class_dim, size=class_dim,
act='softmax', act='softmax',
param_attr=self.xavier(1024, 1)) param_attr=self.xavier(1024, 1, "out"),
name="out",
bias_attr=ParamAttr(name="out_offset"))
pool_o1 = fluid.layers.pool2d( pool_o1 = fluid.layers.pool2d(
input=ince4a, pool_size=5, pool_type='avg', pool_stride=3) input=ince4a, pool_size=5, pool_type='avg', pool_stride=3)
conv_o1 = self.conv_layer( conv_o1 = self.conv_layer(
input=pool_o1, num_filters=128, filter_size=1, stride=1, act=None) input=pool_o1,
num_filters=128,
filter_size=1,
stride=1,
act=None,
name="conv_o1")
fc_o1 = fluid.layers.fc(input=conv_o1, fc_o1 = fluid.layers.fc(input=conv_o1,
size=1024, size=1024,
act='relu', act='relu',
param_attr=self.xavier(2048, 1)) param_attr=self.xavier(2048, 1, "fc_o1"),
name="fc_o1",
bias_attr=ParamAttr(name="fc_o1_offset"))
dropout_o1 = fluid.layers.dropout(x=fc_o1, dropout_prob=0.7) dropout_o1 = fluid.layers.dropout(x=fc_o1, dropout_prob=0.7)
out1 = fluid.layers.fc(input=dropout_o1, out1 = fluid.layers.fc(input=dropout_o1,
size=class_dim, size=class_dim,
act='softmax', act='softmax',
param_attr=self.xavier(1024, 1)) param_attr=self.xavier(1024, 1, "out1"),
name="out1",
bias_attr=ParamAttr(name="out1_offset"))
pool_o2 = fluid.layers.pool2d( pool_o2 = fluid.layers.pool2d(
input=ince4d, pool_size=5, pool_type='avg', pool_stride=3) input=ince4d, pool_size=5, pool_type='avg', pool_stride=3)
conv_o2 = self.conv_layer( conv_o2 = self.conv_layer(
input=pool_o2, num_filters=128, filter_size=1, stride=1, act=None) input=pool_o2,
num_filters=128,
filter_size=1,
stride=1,
act=None,
name="conv_o2")
fc_o2 = fluid.layers.fc(input=conv_o2, fc_o2 = fluid.layers.fc(input=conv_o2,
size=1024, size=1024,
act='relu', act='relu',
param_attr=self.xavier(2048, 1)) param_attr=self.xavier(2048, 1, "fc_o2"),
name="fc_o2",
bias_attr=ParamAttr(name="fc_o2_offset"))
dropout_o2 = fluid.layers.dropout(x=fc_o2, dropout_prob=0.7) dropout_o2 = fluid.layers.dropout(x=fc_o2, dropout_prob=0.7)
out2 = fluid.layers.fc(input=dropout_o2, out2 = fluid.layers.fc(input=dropout_o2,
size=class_dim, size=class_dim,
act='softmax', act='softmax',
param_attr=self.xavier(1024, 1)) param_attr=self.xavier(1024, 1, "out2"),
name="out2",
bias_attr=ParamAttr(name="out2_offset"))
# last fc layer is "out" # last fc layer is "out"
return out, out1, out2 return out, out1, out2
...@@ -4,6 +4,7 @@ from __future__ import print_function ...@@ -4,6 +4,7 @@ from __future__ import print_function
import paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import math import math
from paddle.fluid.param_attr import ParamAttr
__all__ = ['InceptionV4'] __all__ = ['InceptionV4']
...@@ -28,15 +29,15 @@ class InceptionV4(): ...@@ -28,15 +29,15 @@ class InceptionV4():
x = self.inception_stem(input) x = self.inception_stem(input)
for i in range(4): for i in range(4):
x = self.inceptionA(x) x = self.inceptionA(x, name=str(i + 1))
x = self.reductionA(x) x = self.reductionA(x)
for i in range(7): for i in range(7):
x = self.inceptionB(x) x = self.inceptionB(x, name=str(i + 1))
x = self.reductionB(x) x = self.reductionB(x)
for i in range(3): for i in range(3):
x = self.inceptionC(x) x = self.inceptionC(x, name=str(i + 1))
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=x, pool_size=8, pool_type='avg', global_pooling=True) input=x, pool_size=8, pool_type='avg', global_pooling=True)
...@@ -47,8 +48,12 @@ class InceptionV4(): ...@@ -47,8 +48,12 @@ class InceptionV4():
out = fluid.layers.fc( out = fluid.layers.fc(
input=drop, input=drop,
size=class_dim, size=class_dim,
param_attr=fluid.param_attr.ParamAttr( param_attr=ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name="final_fc_weights"),
bias_attr=ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv),
name="final_fc_offset"))
return out return out
def conv_bn_layer(self, def conv_bn_layer(self,
...@@ -58,7 +63,8 @@ class InceptionV4(): ...@@ -58,7 +63,8 @@ class InceptionV4():
stride=1, stride=1,
padding=0, padding=0,
groups=1, groups=1,
act='relu'): act='relu',
name=None):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=data, input=data,
num_filters=num_filters, num_filters=num_filters,
...@@ -67,32 +73,58 @@ class InceptionV4(): ...@@ -67,32 +73,58 @@ class InceptionV4():
padding=padding, padding=padding,
groups=groups, groups=groups,
act=None, act=None,
bias_attr=False) param_attr=ParamAttr(name=name + "_weights"),
return fluid.layers.batch_norm(input=conv, act=act) bias_attr=False,
name=name)
def inception_stem(self, data): bn_name = name + "_bn"
conv = self.conv_bn_layer(data, 32, 3, stride=2, act='relu') return fluid.layers.batch_norm(
conv = self.conv_bn_layer(conv, 32, 3, act='relu') input=conv,
conv = self.conv_bn_layer(conv, 64, 3, padding=1, act='relu') act=act,
name=bn_name,
param_attr=ParamAttr(name=bn_name + "_scale"),
bias_attr=ParamAttr(name=bn_name + "_offset"),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
def inception_stem(self, data, name=None):
conv = self.conv_bn_layer(
data, 32, 3, stride=2, act='relu', name="conv1_3x3_s2")
conv = self.conv_bn_layer(conv, 32, 3, act='relu', name="conv2_3x3_s1")
conv = self.conv_bn_layer(
conv, 64, 3, padding=1, act='relu', name="conv3_3x3_s1")
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=conv, pool_size=3, pool_stride=2, pool_type='max') input=conv, pool_size=3, pool_stride=2, pool_type='max')
conv2 = self.conv_bn_layer(conv, 96, 3, stride=2, act='relu') conv2 = self.conv_bn_layer(
conv, 96, 3, stride=2, act='relu', name="inception_stem1_3x3_s2")
concat = fluid.layers.concat([pool1, conv2], axis=1) concat = fluid.layers.concat([pool1, conv2], axis=1)
conv1 = self.conv_bn_layer(concat, 64, 1, act='relu') conv1 = self.conv_bn_layer(
conv1 = self.conv_bn_layer(conv1, 96, 3, act='relu') concat, 64, 1, act='relu', name="inception_stem2_3x3_reduce")
conv1 = self.conv_bn_layer(
conv1, 96, 3, act='relu', name="inception_stem2_3x3")
conv2 = self.conv_bn_layer(concat, 64, 1, act='relu')
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(
conv2, 64, (7, 1), padding=(3, 0), act='relu') concat, 64, 1, act='relu', name="inception_stem2_1x7_reduce")
conv2 = self.conv_bn_layer(
conv2,
64, (7, 1),
padding=(3, 0),
act='relu',
name="inception_stem2_1x7")
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(
conv2, 64, (1, 7), padding=(0, 3), act='relu') conv2,
conv2 = self.conv_bn_layer(conv2, 96, 3, act='relu') 64, (1, 7),
padding=(0, 3),
act='relu',
name="inception_stem2_7x1")
conv2 = self.conv_bn_layer(
conv2, 96, 3, act='relu', name="inception_stem2_3x3_2")
concat = fluid.layers.concat([conv1, conv2], axis=1) concat = fluid.layers.concat([conv1, conv2], axis=1)
conv1 = self.conv_bn_layer(concat, 192, 3, stride=2, act='relu') conv1 = self.conv_bn_layer(
concat, 192, 3, stride=2, act='relu', name="inception_stem3_3x3_s2")
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=concat, pool_size=3, pool_stride=2, pool_type='max') input=concat, pool_size=3, pool_stride=2, pool_type='max')
...@@ -100,105 +132,207 @@ class InceptionV4(): ...@@ -100,105 +132,207 @@ class InceptionV4():
return concat return concat
def inceptionA(self, data): def inceptionA(self, data, name=None):
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=data, pool_size=3, pool_padding=1, pool_type='avg') input=data, pool_size=3, pool_padding=1, pool_type='avg')
conv1 = self.conv_bn_layer(pool1, 96, 1, act='relu') conv1 = self.conv_bn_layer(
pool1, 96, 1, act='relu', name="inception_a" + name + "_1x1")
conv2 = self.conv_bn_layer(data, 96, 1, act='relu') conv2 = self.conv_bn_layer(
data, 96, 1, act='relu', name="inception_a" + name + "_1x1_2")
conv3 = self.conv_bn_layer(data, 64, 1, act='relu') conv3 = self.conv_bn_layer(
conv3 = self.conv_bn_layer(conv3, 96, 3, padding=1, act='relu') data, 64, 1, act='relu', name="inception_a" + name + "_3x3_reduce")
conv3 = self.conv_bn_layer(
conv3,
96,
3,
padding=1,
act='relu',
name="inception_a" + name + "_3x3")
conv4 = self.conv_bn_layer(data, 64, 1, act='relu') conv4 = self.conv_bn_layer(
conv4 = self.conv_bn_layer(conv4, 96, 3, padding=1, act='relu') data,
conv4 = self.conv_bn_layer(conv4, 96, 3, padding=1, act='relu') 64,
1,
act='relu',
name="inception_a" + name + "_3x3_2_reduce")
conv4 = self.conv_bn_layer(
conv4,
96,
3,
padding=1,
act='relu',
name="inception_a" + name + "_3x3_2")
conv4 = self.conv_bn_layer(
conv4,
96,
3,
padding=1,
act='relu',
name="inception_a" + name + "_3x3_3")
concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1) concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1)
return concat return concat
def reductionA(self, data): def reductionA(self, data, name=None):
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=data, pool_size=3, pool_stride=2, pool_type='max') input=data, pool_size=3, pool_stride=2, pool_type='max')
conv2 = self.conv_bn_layer(data, 384, 3, stride=2, act='relu') conv2 = self.conv_bn_layer(
data, 384, 3, stride=2, act='relu', name="reduction_a_3x3")
conv3 = self.conv_bn_layer(data, 192, 1, act='relu') conv3 = self.conv_bn_layer(
conv3 = self.conv_bn_layer(conv3, 224, 3, padding=1, act='relu') data, 192, 1, act='relu', name="reduction_a_3x3_2_reduce")
conv3 = self.conv_bn_layer(conv3, 256, 3, stride=2, act='relu') conv3 = self.conv_bn_layer(
conv3, 224, 3, padding=1, act='relu', name="reduction_a_3x3_2")
conv3 = self.conv_bn_layer(
conv3, 256, 3, stride=2, act='relu', name="reduction_a_3x3_3")
concat = fluid.layers.concat([pool1, conv2, conv3], axis=1) concat = fluid.layers.concat([pool1, conv2, conv3], axis=1)
return concat return concat
def inceptionB(self, data): def inceptionB(self, data, name=None):
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=data, pool_size=3, pool_padding=1, pool_type='avg') input=data, pool_size=3, pool_padding=1, pool_type='avg')
conv1 = self.conv_bn_layer(pool1, 128, 1, act='relu') conv1 = self.conv_bn_layer(
pool1, 128, 1, act='relu', name="inception_b" + name + "_1x1")
conv2 = self.conv_bn_layer(data, 384, 1, act='relu') conv2 = self.conv_bn_layer(
data, 384, 1, act='relu', name="inception_b" + name + "_1x1_2")
conv3 = self.conv_bn_layer(data, 192, 1, act='relu')
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(
conv3, 224, (1, 7), padding=(0, 3), act='relu') data, 192, 1, act='relu', name="inception_b" + name + "_1x7_reduce")
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(
conv3, 256, (7, 1), padding=(3, 0), act='relu') conv3,
224, (1, 7),
padding=(0, 3),
act='relu',
name="inception_b" + name + "_1x7")
conv3 = self.conv_bn_layer(
conv3,
256, (7, 1),
padding=(3, 0),
act='relu',
name="inception_b" + name + "_7x1")
conv4 = self.conv_bn_layer(data, 192, 1, act='relu')
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
conv4, 192, (1, 7), padding=(0, 3), act='relu') data,
192,
1,
act='relu',
name="inception_b" + name + "_7x1_2_reduce")
conv4 = self.conv_bn_layer(
conv4,
192, (1, 7),
padding=(0, 3),
act='relu',
name="inception_b" + name + "_1x7_2")
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
conv4, 224, (7, 1), padding=(3, 0), act='relu') conv4,
224, (7, 1),
padding=(3, 0),
act='relu',
name="inception_b" + name + "_7x1_2")
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
conv4, 224, (1, 7), padding=(0, 3), act='relu') conv4,
224, (1, 7),
padding=(0, 3),
act='relu',
name="inception_b" + name + "_1x7_3")
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
conv4, 256, (7, 1), padding=(3, 0), act='relu') conv4,
256, (7, 1),
padding=(3, 0),
act='relu',
name="inception_b" + name + "_7x1_3")
concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1) concat = fluid.layers.concat([conv1, conv2, conv3, conv4], axis=1)
return concat return concat
def reductionB(self, data): def reductionB(self, data, name=None):
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=data, pool_size=3, pool_stride=2, pool_type='max') input=data, pool_size=3, pool_stride=2, pool_type='max')
conv2 = self.conv_bn_layer(data, 192, 1, act='relu') conv2 = self.conv_bn_layer(
conv2 = self.conv_bn_layer(conv2, 192, 3, stride=2, act='relu') data, 192, 1, act='relu', name="reduction_b_3x3_reduce")
conv2 = self.conv_bn_layer(
conv2, 192, 3, stride=2, act='relu', name="reduction_b_3x3")
conv3 = self.conv_bn_layer(data, 256, 1, act='relu')
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(
conv3, 256, (1, 7), padding=(0, 3), act='relu') data, 256, 1, act='relu', name="reduction_b_1x7_reduce")
conv3 = self.conv_bn_layer(
conv3,
256, (1, 7),
padding=(0, 3),
act='relu',
name="reduction_b_1x7")
conv3 = self.conv_bn_layer(
conv3,
320, (7, 1),
padding=(3, 0),
act='relu',
name="reduction_b_7x1")
conv3 = self.conv_bn_layer( conv3 = self.conv_bn_layer(
conv3, 320, (7, 1), padding=(3, 0), act='relu') conv3, 320, 3, stride=2, act='relu', name="reduction_b_3x3_2")
conv3 = self.conv_bn_layer(conv3, 320, 3, stride=2, act='relu')
concat = fluid.layers.concat([pool1, conv2, conv3], axis=1) concat = fluid.layers.concat([pool1, conv2, conv3], axis=1)
return concat return concat
def inceptionC(self, data): def inceptionC(self, data, name=None):
pool1 = fluid.layers.pool2d( pool1 = fluid.layers.pool2d(
input=data, pool_size=3, pool_padding=1, pool_type='avg') input=data, pool_size=3, pool_padding=1, pool_type='avg')
conv1 = self.conv_bn_layer(pool1, 256, 1, act='relu') conv1 = self.conv_bn_layer(
pool1, 256, 1, act='relu', name="inception_c" + name + "_1x1")
conv2 = self.conv_bn_layer(data, 256, 1, act='relu') conv2 = self.conv_bn_layer(
data, 256, 1, act='relu', name="inception_c" + name + "_1x1_2")
conv3 = self.conv_bn_layer(data, 384, 1, act='relu') conv3 = self.conv_bn_layer(
data, 384, 1, act='relu', name="inception_c" + name + "_1x1_3")
conv3_1 = self.conv_bn_layer( conv3_1 = self.conv_bn_layer(
conv3, 256, (1, 3), padding=(0, 1), act='relu') conv3,
256, (1, 3),
padding=(0, 1),
act='relu',
name="inception_c" + name + "_1x3")
conv3_2 = self.conv_bn_layer( conv3_2 = self.conv_bn_layer(
conv3, 256, (3, 1), padding=(1, 0), act='relu') conv3,
256, (3, 1),
padding=(1, 0),
act='relu',
name="inception_c" + name + "_3x1")
conv4 = self.conv_bn_layer(data, 384, 1, act='relu')
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
conv4, 448, (1, 3), padding=(0, 1), act='relu') data, 384, 1, act='relu', name="inception_c" + name + "_1x1_4")
conv4 = self.conv_bn_layer(
conv4,
448, (1, 3),
padding=(0, 1),
act='relu',
name="inception_c" + name + "_1x3_2")
conv4 = self.conv_bn_layer( conv4 = self.conv_bn_layer(
conv4, 512, (3, 1), padding=(1, 0), act='relu') conv4,
512, (3, 1),
padding=(1, 0),
act='relu',
name="inception_c" + name + "_3x1_2")
conv4_1 = self.conv_bn_layer( conv4_1 = self.conv_bn_layer(
conv4, 256, (1, 3), padding=(0, 1), act='relu') conv4,
256, (1, 3),
padding=(0, 1),
act='relu',
name="inception_c" + name + "_1x3_3")
conv4_2 = self.conv_bn_layer( conv4_2 = self.conv_bn_layer(
conv4, 256, (3, 1), padding=(1, 0), act='relu') conv4,
256, (3, 1),
padding=(1, 0),
act='relu',
name="inception_c" + name + "_3x1_3")
concat = fluid.layers.concat( concat = fluid.layers.concat(
[conv1, conv2, conv3_1, conv3_2, conv4_1, conv4_2], axis=1) [conv1, conv2, conv3_1, conv3_2, conv4_1, conv4_2], axis=1)
......
...@@ -32,7 +32,8 @@ class MobileNet(): ...@@ -32,7 +32,8 @@ class MobileNet():
channels=3, channels=3,
num_filters=int(32 * scale), num_filters=int(32 * scale),
stride=2, stride=2,
padding=1) padding=1,
name="conv1")
# 56x56 # 56x56
input = self.depthwise_separable( input = self.depthwise_separable(
...@@ -41,7 +42,8 @@ class MobileNet(): ...@@ -41,7 +42,8 @@ class MobileNet():
num_filters2=64, num_filters2=64,
num_groups=32, num_groups=32,
stride=1, stride=1,
scale=scale) scale=scale,
name="conv2_1")
input = self.depthwise_separable( input = self.depthwise_separable(
input, input,
...@@ -49,7 +51,8 @@ class MobileNet(): ...@@ -49,7 +51,8 @@ class MobileNet():
num_filters2=128, num_filters2=128,
num_groups=64, num_groups=64,
stride=2, stride=2,
scale=scale) scale=scale,
name="conv2_2")
# 28x28 # 28x28
input = self.depthwise_separable( input = self.depthwise_separable(
...@@ -58,7 +61,8 @@ class MobileNet(): ...@@ -58,7 +61,8 @@ class MobileNet():
num_filters2=128, num_filters2=128,
num_groups=128, num_groups=128,
stride=1, stride=1,
scale=scale) scale=scale,
name="conv3_1")
input = self.depthwise_separable( input = self.depthwise_separable(
input, input,
...@@ -66,7 +70,8 @@ class MobileNet(): ...@@ -66,7 +70,8 @@ class MobileNet():
num_filters2=256, num_filters2=256,
num_groups=128, num_groups=128,
stride=2, stride=2,
scale=scale) scale=scale,
name="conv3_2")
# 14x14 # 14x14
input = self.depthwise_separable( input = self.depthwise_separable(
...@@ -75,7 +80,8 @@ class MobileNet(): ...@@ -75,7 +80,8 @@ class MobileNet():
num_filters2=256, num_filters2=256,
num_groups=256, num_groups=256,
stride=1, stride=1,
scale=scale) scale=scale,
name="conv4_1")
input = self.depthwise_separable( input = self.depthwise_separable(
input, input,
...@@ -83,7 +89,8 @@ class MobileNet(): ...@@ -83,7 +89,8 @@ class MobileNet():
num_filters2=512, num_filters2=512,
num_groups=256, num_groups=256,
stride=2, stride=2,
scale=scale) scale=scale,
name="conv4_2")
# 14x14 # 14x14
for i in range(5): for i in range(5):
...@@ -93,7 +100,8 @@ class MobileNet(): ...@@ -93,7 +100,8 @@ class MobileNet():
num_filters2=512, num_filters2=512,
num_groups=512, num_groups=512,
stride=1, stride=1,
scale=scale) scale=scale,
name="conv5" + "_" + str(i + 1))
# 7x7 # 7x7
input = self.depthwise_separable( input = self.depthwise_separable(
input, input,
...@@ -101,7 +109,8 @@ class MobileNet(): ...@@ -101,7 +109,8 @@ class MobileNet():
num_filters2=1024, num_filters2=1024,
num_groups=512, num_groups=512,
stride=2, stride=2,
scale=scale) scale=scale,
name="conv5_6")
input = self.depthwise_separable( input = self.depthwise_separable(
input, input,
...@@ -109,7 +118,8 @@ class MobileNet(): ...@@ -109,7 +118,8 @@ class MobileNet():
num_filters2=1024, num_filters2=1024,
num_groups=1024, num_groups=1024,
stride=1, stride=1,
scale=scale) scale=scale,
name="conv6")
input = fluid.layers.pool2d( input = fluid.layers.pool2d(
input=input, input=input,
...@@ -120,7 +130,9 @@ class MobileNet(): ...@@ -120,7 +130,9 @@ class MobileNet():
output = fluid.layers.fc(input=input, output = fluid.layers.fc(input=input,
size=class_dim, size=class_dim,
param_attr=ParamAttr(initializer=MSRA())) param_attr=ParamAttr(
initializer=MSRA(), name="fc7_weights"),
bias_attr=ParamAttr(name="fc7_offset"))
return output return output
def conv_bn_layer(self, def conv_bn_layer(self,
...@@ -132,7 +144,8 @@ class MobileNet(): ...@@ -132,7 +144,8 @@ class MobileNet():
channels=None, channels=None,
num_groups=1, num_groups=1,
act='relu', act='relu',
use_cudnn=True): use_cudnn=True,
name=None):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
...@@ -142,12 +155,26 @@ class MobileNet(): ...@@ -142,12 +155,26 @@ class MobileNet():
groups=num_groups, groups=num_groups,
act=None, act=None,
use_cudnn=use_cudnn, use_cudnn=use_cudnn,
param_attr=ParamAttr(initializer=MSRA()), param_attr=ParamAttr(
initializer=MSRA(), name=name + "_weights"),
bias_attr=False) bias_attr=False)
return fluid.layers.batch_norm(input=conv, act=act) bn_name = name + "_bn"
return fluid.layers.batch_norm(
def depthwise_separable(self, input, num_filters1, num_filters2, num_groups, input=conv,
stride, scale): act=act,
param_attr=ParamAttr(name=bn_name + "_scale"),
bias_attr=ParamAttr(name=bn_name + "_offset"),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
def depthwise_separable(self,
input,
num_filters1,
num_filters2,
num_groups,
stride,
scale,
name=None):
depthwise_conv = self.conv_bn_layer( depthwise_conv = self.conv_bn_layer(
input=input, input=input,
filter_size=3, filter_size=3,
...@@ -155,12 +182,14 @@ class MobileNet(): ...@@ -155,12 +182,14 @@ class MobileNet():
stride=stride, stride=stride,
padding=1, padding=1,
num_groups=int(num_groups * scale), num_groups=int(num_groups * scale),
use_cudnn=False) use_cudnn=False,
name=name + "_dw")
pointwise_conv = self.conv_bn_layer( pointwise_conv = self.conv_bn_layer(
input=depthwise_conv, input=depthwise_conv,
filter_size=1, filter_size=1,
num_filters=int(num_filters2 * scale), num_filters=int(num_filters2 * scale),
stride=1, stride=1,
padding=0) padding=0,
name=name + "_sep")
return pointwise_conv return pointwise_conv
...@@ -36,33 +36,40 @@ class MobileNetV2(): ...@@ -36,33 +36,40 @@ class MobileNetV2():
(6, 320, 1, 1), (6, 320, 1, 1),
] ]
#conv1
input = self.conv_bn_layer( input = self.conv_bn_layer(
input, input,
num_filters=int(32 * scale), num_filters=int(32 * scale),
filter_size=3, filter_size=3,
stride=2, stride=2,
padding=1, padding=1,
if_act=True) if_act=True,
name='conv1_1')
# bottleneck sequences
i = 1
in_c = int(32 * scale) in_c = int(32 * scale)
for layer_setting in bottleneck_params_list: for layer_setting in bottleneck_params_list:
t, c, n, s = layer_setting t, c, n, s = layer_setting
i += 1
input = self.invresi_blocks( input = self.invresi_blocks(
input=input, input=input,
in_c=in_c, in_c=in_c,
t=t, t=t,
c=int(c * scale), c=int(c * scale),
n=n, n=n,
s=s, ) s=s,
name='conv' + str(i))
in_c = int(c * scale) in_c = int(c * scale)
#last_conv
input = self.conv_bn_layer( input = self.conv_bn_layer(
input=input, input=input,
num_filters=int(1280 * scale) if scale > 1.0 else 1280, num_filters=int(1280 * scale) if scale > 1.0 else 1280,
filter_size=1, filter_size=1,
stride=1, stride=1,
padding=0, padding=0,
if_act=True) if_act=True,
name='conv9')
input = fluid.layers.pool2d( input = fluid.layers.pool2d(
input=input, input=input,
...@@ -73,7 +80,8 @@ class MobileNetV2(): ...@@ -73,7 +80,8 @@ class MobileNetV2():
output = fluid.layers.fc(input=input, output = fluid.layers.fc(input=input,
size=class_dim, size=class_dim,
param_attr=ParamAttr(initializer=MSRA())) param_attr=ParamAttr(name='fc10_weights'),
bias_attr=ParamAttr(name='fc10_offset'))
return output return output
def conv_bn_layer(self, def conv_bn_layer(self,
...@@ -84,8 +92,9 @@ class MobileNetV2(): ...@@ -84,8 +92,9 @@ class MobileNetV2():
padding, padding,
channels=None, channels=None,
num_groups=1, num_groups=1,
use_cudnn=True, if_act=True,
if_act=True): name=None,
use_cudnn=True):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
...@@ -95,9 +104,15 @@ class MobileNetV2(): ...@@ -95,9 +104,15 @@ class MobileNetV2():
groups=num_groups, groups=num_groups,
act=None, act=None,
use_cudnn=use_cudnn, use_cudnn=use_cudnn,
param_attr=ParamAttr(initializer=MSRA()), param_attr=ParamAttr(name=name + '_weights'),
bias_attr=False) bias_attr=False)
bn = fluid.layers.batch_norm(input=conv) bn_name = name + '_bn'
bn = fluid.layers.batch_norm(
input=conv,
param_attr=ParamAttr(name=bn_name + "_scale"),
bias_attr=ParamAttr(name=bn_name + "_offset"),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
if if_act: if if_act:
return fluid.layers.relu6(bn) return fluid.layers.relu6(bn)
else: else:
...@@ -106,10 +121,18 @@ class MobileNetV2(): ...@@ -106,10 +121,18 @@ class MobileNetV2():
def shortcut(self, input, data_residual): def shortcut(self, input, data_residual):
return fluid.layers.elementwise_add(input, data_residual) return fluid.layers.elementwise_add(input, data_residual)
def inverted_residual_unit(self, input, num_in_filter, num_filters, def inverted_residual_unit(self,
ifshortcut, stride, filter_size, padding, input,
expansion_factor): num_in_filter,
num_filters,
ifshortcut,
stride,
filter_size,
padding,
expansion_factor,
name=None):
num_expfilter = int(round(num_in_filter * expansion_factor)) num_expfilter = int(round(num_in_filter * expansion_factor))
channel_expand = self.conv_bn_layer( channel_expand = self.conv_bn_layer(
input=input, input=input,
num_filters=num_expfilter, num_filters=num_expfilter,
...@@ -117,7 +140,9 @@ class MobileNetV2(): ...@@ -117,7 +140,9 @@ class MobileNetV2():
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True) if_act=True,
name=name + '_expand')
bottleneck_conv = self.conv_bn_layer( bottleneck_conv = self.conv_bn_layer(
input=channel_expand, input=channel_expand,
num_filters=num_expfilter, num_filters=num_expfilter,
...@@ -126,7 +151,9 @@ class MobileNetV2(): ...@@ -126,7 +151,9 @@ class MobileNetV2():
padding=padding, padding=padding,
num_groups=num_expfilter, num_groups=num_expfilter,
if_act=True, if_act=True,
name=name + '_dwise',
use_cudnn=False) use_cudnn=False)
linear_out = self.conv_bn_layer( linear_out = self.conv_bn_layer(
input=bottleneck_conv, input=bottleneck_conv,
num_filters=num_filters, num_filters=num_filters,
...@@ -134,14 +161,15 @@ class MobileNetV2(): ...@@ -134,14 +161,15 @@ class MobileNetV2():
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=False) if_act=False,
name=name + '_linear')
if ifshortcut: if ifshortcut:
out = self.shortcut(input=input, data_residual=linear_out) out = self.shortcut(input=input, data_residual=linear_out)
return out return out
else: else:
return linear_out return linear_out
def invresi_blocks(self, input, in_c, t, c, n, s): def invresi_blocks(self, input, in_c, t, c, n, s, name=None):
first_block = self.inverted_residual_unit( first_block = self.inverted_residual_unit(
input=input, input=input,
num_in_filter=in_c, num_in_filter=in_c,
...@@ -150,7 +178,8 @@ class MobileNetV2(): ...@@ -150,7 +178,8 @@ class MobileNetV2():
stride=s, stride=s,
filter_size=3, filter_size=3,
padding=1, padding=1,
expansion_factor=t) expansion_factor=t,
name=name + '_1')
last_residual_block = first_block last_residual_block = first_block
last_c = c last_c = c
...@@ -164,5 +193,6 @@ class MobileNetV2(): ...@@ -164,5 +193,6 @@ class MobileNetV2():
stride=1, stride=1,
filter_size=3, filter_size=3,
padding=1, padding=1,
expansion_factor=t) expansion_factor=t,
name=name + '_' + str(i + 1))
return last_residual_block return last_residual_block
...@@ -4,8 +4,9 @@ from __future__ import print_function ...@@ -4,8 +4,9 @@ from __future__ import print_function
import paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import math import math
from paddle.fluid.param_attr import ParamAttr
__all__ = ["ResNet", "ResNet50", "ResNet101", "ResNet152"] __all__ = ["ResNet", "ResNet18", "ResNet34", "ResNet50", "ResNet101", "ResNet152"]
train_parameters = { train_parameters = {
"input_size": [3, 224, 224], "input_size": [3, 224, 224],
...@@ -27,11 +28,13 @@ class ResNet(): ...@@ -27,11 +28,13 @@ class ResNet():
def net(self, input, class_dim=1000): def net(self, input, class_dim=1000):
layers = self.layers layers = self.layers
supported_layers = [50, 101, 152] supported_layers = [18, 34, 50, 101, 152]
assert layers in supported_layers, \ assert layers in supported_layers, \
"supported layers are {} but input layer is {}".format(supported_layers, layers) "supported layers are {} but input layer is {}".format(supported_layers, layers)
if layers == 50: if layers == 18:
depth = [2, 2, 2, 2]
elif layers == 34 or layers == 50:
depth = [3, 4, 6, 3] depth = [3, 4, 6, 3]
elif layers == 101: elif layers == 101:
depth = [3, 4, 23, 3] depth = [3, 4, 23, 3]
...@@ -40,29 +43,53 @@ class ResNet(): ...@@ -40,29 +43,53 @@ class ResNet():
num_filters = [64, 128, 256, 512] num_filters = [64, 128, 256, 512]
conv = self.conv_bn_layer( conv = self.conv_bn_layer(
input=input, num_filters=64, filter_size=7, stride=2, act='relu') input=input, num_filters=64, filter_size=7, stride=2, act='relu',name="conv1")
conv = fluid.layers.pool2d( conv = fluid.layers.pool2d(
input=conv, input=conv,
pool_size=3, pool_size=3,
pool_stride=2, pool_stride=2,
pool_padding=1, pool_padding=1,
pool_type='max') pool_type='max')
if layers >= 50:
for block in range(len(depth)): for block in range(len(depth)):
for i in range(depth[block]): for i in range(depth[block]):
conv = self.bottleneck_block( if layers in [101, 152] and block == 2:
input=conv, if i == 0:
num_filters=num_filters[block], conv_name="res"+str(block+2)+"a"
stride=2 if i == 0 and block != 0 else 1) else:
conv_name="res"+str(block+2)+"b"+str(i)
pool = fluid.layers.pool2d( else:
input=conv, pool_size=7, pool_type='avg', global_pooling=True) conv_name="res"+str(block+2)+chr(97+i)
stdv = 1.0 / math.sqrt(pool.shape[1] * 1.0) conv = self.bottleneck_block(
out = fluid.layers.fc(input=pool, input=conv,
size=class_dim, num_filters=num_filters[block],
param_attr=fluid.param_attr.ParamAttr( stride=2 if i == 0 and block != 0 else 1, name=conv_name)
initializer=fluid.initializer.Uniform(-stdv,
stdv))) pool = fluid.layers.pool2d(
input=conv, pool_size=7, pool_type='avg', global_pooling=True)
stdv = 1.0 / math.sqrt(pool.shape[1] * 1.0)
out = fluid.layers.fc(input=pool,
size=class_dim,
param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)))
else:
for block in range(len(depth)):
for i in range(depth[block]):
conv_name="res"+str(block+2)+chr(97+i)
conv = self.basic_block(
input=conv,
num_filters=num_filters[block],
stride=2 if i == 0 and block != 0 else 1,
is_first=block==i==0,
name=conv_name)
pool = fluid.layers.pool2d(
input=conv, pool_size=7, pool_type='avg', global_pooling=True)
stdv = 1.0 / math.sqrt(pool.shape[1] * 1.0)
out = fluid.layers.fc(input=pool,
size=class_dim,
param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Uniform(-stdv, stdv)))
return out return out
def conv_bn_layer(self, def conv_bn_layer(self,
...@@ -71,40 +98,73 @@ class ResNet(): ...@@ -71,40 +98,73 @@ class ResNet():
filter_size, filter_size,
stride=1, stride=1,
groups=1, groups=1,
act=None): act=None,
name=None):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
filter_size=filter_size, filter_size=filter_size,
stride=stride, stride=stride,
padding=(filter_size - 1) // 2, padding=(filter_size - 1) / 2,
groups=groups, groups=groups,
act=None, act=None,
bias_attr=False) param_attr=ParamAttr(name=name + "_weights"),
return fluid.layers.batch_norm(input=conv, act=act) bias_attr=False,
name=name + '.conv2d.output.1')
def shortcut(self, input, ch_out, stride):
if name == "conv1":
bn_name = "bn_" + name
else:
bn_name = "bn" + name[3:]
return fluid.layers.batch_norm(input=conv,
act=act,
name=bn_name+'.output.1',
param_attr=ParamAttr(name=bn_name + '_scale'),
bias_attr=ParamAttr(bn_name + '_offset'),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance',)
def shortcut(self, input, ch_out, stride, is_first, name):
ch_in = input.shape[1] ch_in = input.shape[1]
if ch_in != ch_out or stride != 1: if ch_in != ch_out or stride != 1 or is_first == True:
return self.conv_bn_layer(input, ch_out, 1, stride) return self.conv_bn_layer(input, ch_out, 1, stride, name=name)
else: else:
return input return input
def bottleneck_block(self, input, num_filters, stride): def bottleneck_block(self, input, num_filters, stride, name):
conv0 = self.conv_bn_layer( conv0 = self.conv_bn_layer(
input=input, num_filters=num_filters, filter_size=1, act='relu') input=input, num_filters=num_filters, filter_size=1, act='relu',name=name+"_branch2a")
conv1 = self.conv_bn_layer( conv1 = self.conv_bn_layer(
input=conv0, input=conv0,
num_filters=num_filters, num_filters=num_filters,
filter_size=3, filter_size=3,
stride=stride, stride=stride,
act='relu') act='relu',
name=name+"_branch2b")
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(
input=conv1, num_filters=num_filters * 4, filter_size=1, act=None) input=conv1, num_filters=num_filters * 4, filter_size=1, act=None, name=name+"_branch2c")
short = self.shortcut(input, num_filters * 4, stride, is_first=False, name=name + "_branch1")
return fluid.layers.elementwise_add(x=short, y=conv2, act='relu',name=name+".add.output.5")
def basic_block(self, input, num_filters, stride, is_first, name):
conv0 = self.conv_bn_layer(input=input, num_filters=num_filters, filter_size=3, act='relu', stride=stride,
name=name+"_branch2a")
conv1 = self.conv_bn_layer(input=conv0, num_filters=num_filters, filter_size=3, act=None,
name=name+"_branch2b")
short = self.shortcut(input, num_filters, stride, is_first, name=name + "_branch1")
return fluid.layers.elementwise_add(x=short, y=conv1, act='relu')
def ResNet18():
model = ResNet(layers=18)
return model
short = self.shortcut(input, num_filters * 4, stride)
return fluid.layers.elementwise_add(x=short, y=conv2, act='relu') def ResNet34():
model = ResNet(layers=34)
return model
def ResNet50(): def ResNet50():
......
...@@ -4,6 +4,7 @@ from __future__ import print_function ...@@ -4,6 +4,7 @@ from __future__ import print_function
import paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import math import math
from paddle.fluid.param_attr import ParamAttr
__all__ = [ __all__ = [
"SE_ResNeXt", "SE_ResNeXt50_32x4d", "SE_ResNeXt101_32x4d", "SE_ResNeXt", "SE_ResNeXt50_32x4d", "SE_ResNeXt101_32x4d",
...@@ -18,7 +19,7 @@ train_parameters = { ...@@ -18,7 +19,7 @@ train_parameters = {
"learning_strategy": { "learning_strategy": {
"name": "piecewise_decay", "name": "piecewise_decay",
"batch_size": 256, "batch_size": 256,
"epochs": [30, 60, 90], "epochs": [40, 80, 100],
"steps": [0.1, 0.01, 0.001, 0.0001] "steps": [0.1, 0.01, 0.001, 0.0001]
} }
} }
...@@ -45,7 +46,8 @@ class SE_ResNeXt(): ...@@ -45,7 +46,8 @@ class SE_ResNeXt():
num_filters=64, num_filters=64,
filter_size=7, filter_size=7,
stride=2, stride=2,
act='relu') act='relu',
name='conv1', )
conv = fluid.layers.pool2d( conv = fluid.layers.pool2d(
input=conv, input=conv,
pool_size=3, pool_size=3,
...@@ -63,7 +65,8 @@ class SE_ResNeXt(): ...@@ -63,7 +65,8 @@ class SE_ResNeXt():
num_filters=64, num_filters=64,
filter_size=7, filter_size=7,
stride=2, stride=2,
act='relu') act='relu',
name="conv1", )
conv = fluid.layers.pool2d( conv = fluid.layers.pool2d(
input=conv, input=conv,
pool_size=3, pool_size=3,
...@@ -81,67 +84,94 @@ class SE_ResNeXt(): ...@@ -81,67 +84,94 @@ class SE_ResNeXt():
num_filters=64, num_filters=64,
filter_size=3, filter_size=3,
stride=2, stride=2,
act='relu') act='relu',
name='conv1')
conv = self.conv_bn_layer( conv = self.conv_bn_layer(
input=conv, num_filters=64, filter_size=3, stride=1, act='relu') input=conv,
num_filters=64,
filter_size=3,
stride=1,
act='relu',
name='conv2')
conv = self.conv_bn_layer( conv = self.conv_bn_layer(
input=conv, input=conv,
num_filters=128, num_filters=128,
filter_size=3, filter_size=3,
stride=1, stride=1,
act='relu') act='relu',
name='conv3')
conv = fluid.layers.pool2d( conv = fluid.layers.pool2d(
input=conv, pool_size=3, pool_stride=2, pool_padding=1, \ input=conv, pool_size=3, pool_stride=2, pool_padding=1, \
pool_type='max') pool_type='max')
n = 1 if layers == 50 or layers == 101 else 3
for block in range(len(depth)): for block in range(len(depth)):
n += 1
for i in range(depth[block]): for i in range(depth[block]):
conv = self.bottleneck_block( conv = self.bottleneck_block(
input=conv, input=conv,
num_filters=num_filters[block], num_filters=num_filters[block],
stride=2 if i == 0 and block != 0 else 1, stride=2 if i == 0 and block != 0 else 1,
cardinality=cardinality, cardinality=cardinality,
reduction_ratio=reduction_ratio) reduction_ratio=reduction_ratio,
name=str(n) + '_' + str(i + 1))
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=conv, pool_size=7, pool_type='avg', global_pooling=True) input=conv, pool_size=7, pool_type='avg', global_pooling=True)
drop = fluid.layers.dropout( drop = fluid.layers.dropout(
x=pool, dropout_prob=0.5, seed=self.params['dropout_seed']) x=pool, dropout_prob=0.5, seed=self.params['dropout_seed'])
stdv = 1.0 / math.sqrt(drop.shape[1] * 1.0) stdv = 1.0 / math.sqrt(drop.shape[1] * 1.0)
out = fluid.layers.fc(input=drop, out = fluid.layers.fc(
size=class_dim, input=drop,
param_attr=fluid.param_attr.ParamAttr( size=class_dim,
initializer=fluid.initializer.Uniform(-stdv, param_attr=ParamAttr(
stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name='fc6_weights'),
bias_attr=ParamAttr(name='fc6_offset'))
return out return out
def shortcut(self, input, ch_out, stride): def shortcut(self, input, ch_out, stride, name):
ch_in = input.shape[1] ch_in = input.shape[1]
if ch_in != ch_out or stride != 1: if ch_in != ch_out or stride != 1:
filter_size = 1 filter_size = 1
return self.conv_bn_layer(input, ch_out, filter_size, stride) return self.conv_bn_layer(
input, ch_out, filter_size, stride, name='conv' + name + '_prj')
else: else:
return input return input
def bottleneck_block(self, input, num_filters, stride, cardinality, def bottleneck_block(self,
reduction_ratio): input,
num_filters,
stride,
cardinality,
reduction_ratio,
name=None):
conv0 = self.conv_bn_layer( conv0 = self.conv_bn_layer(
input=input, num_filters=num_filters, filter_size=1, act='relu') input=input,
num_filters=num_filters,
filter_size=1,
act='relu',
name='conv' + name + '_x1')
conv1 = self.conv_bn_layer( conv1 = self.conv_bn_layer(
input=conv0, input=conv0,
num_filters=num_filters, num_filters=num_filters,
filter_size=3, filter_size=3,
stride=stride, stride=stride,
groups=cardinality, groups=cardinality,
act='relu') act='relu',
name='conv' + name + '_x2')
conv2 = self.conv_bn_layer( conv2 = self.conv_bn_layer(
input=conv1, num_filters=num_filters * 2, filter_size=1, act=None) input=conv1,
num_filters=num_filters * 2,
filter_size=1,
act=None,
name='conv' + name + '_x3')
scale = self.squeeze_excitation( scale = self.squeeze_excitation(
input=conv2, input=conv2,
num_channels=num_filters * 2, num_channels=num_filters * 2,
reduction_ratio=reduction_ratio) reduction_ratio=reduction_ratio,
name='fc' + name)
short = self.shortcut(input, num_filters * 2, stride) short = self.shortcut(input, num_filters * 2, stride, name=name)
return fluid.layers.elementwise_add(x=short, y=scale, act='relu') return fluid.layers.elementwise_add(x=short, y=scale, act='relu')
...@@ -151,7 +181,8 @@ class SE_ResNeXt(): ...@@ -151,7 +181,8 @@ class SE_ResNeXt():
filter_size, filter_size,
stride=1, stride=1,
groups=1, groups=1,
act=None): act=None,
name=None):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
...@@ -160,26 +191,42 @@ class SE_ResNeXt(): ...@@ -160,26 +191,42 @@ class SE_ResNeXt():
padding=(filter_size - 1) // 2, padding=(filter_size - 1) // 2,
groups=groups, groups=groups,
act=None, act=None,
bias_attr=False) bias_attr=False,
return fluid.layers.batch_norm(input=conv, act=act) param_attr=ParamAttr(name=name + '_weights'), )
bn_name = name + "_bn"
def squeeze_excitation(self, input, num_channels, reduction_ratio): return fluid.layers.batch_norm(
input=conv,
act=act,
param_attr=ParamAttr(name=bn_name + '_scale'),
bias_attr=ParamAttr(bn_name + '_offset'),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
def squeeze_excitation(self,
input,
num_channels,
reduction_ratio,
name=None):
pool = fluid.layers.pool2d( pool = fluid.layers.pool2d(
input=input, pool_size=0, pool_type='avg', global_pooling=True) input=input, pool_size=0, pool_type='avg', global_pooling=True)
stdv = 1.0 / math.sqrt(pool.shape[1] * 1.0) stdv = 1.0 / math.sqrt(pool.shape[1] * 1.0)
squeeze = fluid.layers.fc(input=pool, squeeze = fluid.layers.fc(
size=num_channels // reduction_ratio, input=pool,
act='relu', size=num_channels // reduction_ratio,
param_attr=fluid.param_attr.ParamAttr( act='relu',
initializer=fluid.initializer.Uniform( param_attr=fluid.param_attr.ParamAttr(
-stdv, stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=name + '_sqz_weights'),
bias_attr=ParamAttr(name=name + '_sqz_offset'))
stdv = 1.0 / math.sqrt(squeeze.shape[1] * 1.0) stdv = 1.0 / math.sqrt(squeeze.shape[1] * 1.0)
excitation = fluid.layers.fc(input=squeeze, excitation = fluid.layers.fc(
size=num_channels, input=squeeze,
act='sigmoid', size=num_channels,
param_attr=fluid.param_attr.ParamAttr( act='sigmoid',
initializer=fluid.initializer.Uniform( param_attr=fluid.param_attr.ParamAttr(
-stdv, stdv))) initializer=fluid.initializer.Uniform(-stdv, stdv),
name=name + '_exc_weights'),
bias_attr=ParamAttr(name=name + '_exc_offset'))
scale = fluid.layers.elementwise_mul(x=input, y=excitation, axis=0) scale = fluid.layers.elementwise_mul(x=input, y=excitation, axis=0)
return scale return scale
......
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import paddle.fluid as fluid import paddle.fluid as fluid
from paddle.fluid.initializer import MSRA from paddle.fluid.initializer import MSRA
from paddle.fluid.param_attr import ParamAttr from paddle.fluid.param_attr import ParamAttr
__all__ = [ __all__ = ['ShuffleNetV2', 'ShuffleNetV2_x0_5_swish', 'ShuffleNetV2_x1_0_swish', 'ShuffleNetV2_x1_5_swish',
'ShuffleNetV2', 'ShuffleNetV2_x0_5', 'ShuffleNetV2_x1_0', 'ShuffleNetV2_x2_0_swish', 'ShuffleNetV2_x8_0_swish']
'ShuffleNetV2_x1_5', 'ShuffleNetV2_x2_0'
]
train_parameters = { train_parameters = {
"input_size": [3, 224, 224], "input_size": [3, 224, 224],
...@@ -29,82 +24,65 @@ class ShuffleNetV2(): ...@@ -29,82 +24,65 @@ class ShuffleNetV2():
self.scale = scale self.scale = scale
def net(self, input, class_dim=1000): def net(self, input, class_dim=1000):
scale = self.scale scale = self.scale
stage_repeats = [4, 8, 4] stage_repeats = [4, 8, 4]
if scale == 0.5: if scale == 0.5:
stage_out_channels = [-1, 24, 48, 96, 192, 1024] stage_out_channels = [-1, 24, 48, 96, 192, 1024]
elif scale == 1.0: elif scale == 1.0:
stage_out_channels = [-1, 24, 116, 232, 464, 1024] stage_out_channels = [-1, 24, 116, 232, 464, 1024]
elif scale == 1.5: elif scale == 1.5:
stage_out_channels = [-1, 24, 176, 352, 704, 1024] stage_out_channels = [-1, 24, 176, 352, 704, 1024]
elif scale == 2.0: elif scale == 2.0:
stage_out_channels = [-1, 24, 224, 488, 976, 2048] stage_out_channels = [-1, 24, 224, 488, 976, 2048]
elif scale == 8.0:
stage_out_channels = [-1, 48, 896, 1952, 3904, 8192]
else: else:
raise ValueError("""{} groups is not supported for raise ValueError(
"""{} groups is not supported for
1x1 Grouped Convolutions""".format(num_groups)) 1x1 Grouped Convolutions""".format(num_groups))
#conv1 #conv1
input_channel = stage_out_channels[1] input_channel = stage_out_channels[1]
conv1 = self.conv_bn_layer( conv1 = self.conv_bn_layer(input=input, filter_size=3, num_filters=input_channel, padding=1, stride=2,name='stage1_conv')
input=input, pool1 = fluid.layers.pool2d(input=conv1, pool_size=3, pool_stride=2, pool_padding=1, pool_type='max')
filter_size=3,
num_filters=input_channel,
padding=1,
stride=2)
pool1 = fluid.layers.pool2d(
input=conv1,
pool_size=3,
pool_stride=2,
pool_padding=1,
pool_type='max')
conv = pool1 conv = pool1
# bottleneck sequences # bottleneck sequences
for idxstage in range(len(stage_repeats)): for idxstage in range(len(stage_repeats)):
numrepeat = stage_repeats[idxstage] numrepeat = stage_repeats[idxstage]
output_channel = stage_out_channels[idxstage + 2] output_channel = stage_out_channels[idxstage+2]
for i in range(numrepeat): for i in range(numrepeat):
if i == 0: if i == 0:
conv = self.inverted_residual_unit( conv = self.inverted_residual_unit(input=conv, num_filters=output_channel, stride=2,
input=conv, benchmodel=2,name=str(idxstage+2)+'_'+str(i+1))
num_filters=output_channel,
stride=2,
benchmodel=2)
else: else:
conv = self.inverted_residual_unit( conv = self.inverted_residual_unit(input=conv, num_filters=output_channel, stride=1,
input=conv, benchmodel=1,name=str(idxstage+2)+'_'+str(i+1))
num_filters=output_channel,
stride=1, conv_last = self.conv_bn_layer(input=conv, filter_size=1, num_filters=stage_out_channels[-1],
benchmodel=1) padding=0, stride=1, name='conv5')
pool_last = fluid.layers.pool2d(input=conv_last, pool_size=7, pool_stride=1, pool_padding=0, pool_type='avg')
conv_last = self.conv_bn_layer(
input=conv,
filter_size=1,
num_filters=stage_out_channels[-1],
padding=0,
stride=1)
pool_last = fluid.layers.pool2d(
input=conv_last,
pool_size=7,
pool_stride=7,
pool_padding=0,
pool_type='avg')
output = fluid.layers.fc(input=pool_last, output = fluid.layers.fc(input=pool_last,
size=class_dim, size=class_dim,
param_attr=ParamAttr(initializer=MSRA())) param_attr=ParamAttr(initializer=MSRA(),name='fc6_weights'),
bias_attr=ParamAttr(name='fc6_offset'))
return output return output
def conv_bn_layer(self, def conv_bn_layer(self,
input, input,
filter_size, filter_size,
num_filters, num_filters,
stride, stride,
padding, padding,
num_groups=1, num_groups=1,
use_cudnn=True, use_cudnn=True,
if_act=True): if_act=True,
name=None):
# print(num_groups)
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
input=input, input=input,
num_filters=num_filters, num_filters=num_filters,
...@@ -114,139 +92,164 @@ class ShuffleNetV2(): ...@@ -114,139 +92,164 @@ class ShuffleNetV2():
groups=num_groups, groups=num_groups,
act=None, act=None,
use_cudnn=use_cudnn, use_cudnn=use_cudnn,
param_attr=ParamAttr(initializer=MSRA()), param_attr=ParamAttr(initializer=MSRA(),name=name+'_weights'),
bias_attr=False) bias_attr=False)
out = int((input.shape[2] - 1)/float(stride) + 1)
# print(input.shape[1],(out, out), num_filters, (filter_size, filter_size), stride,
# (filter_size - 1) / 2, num_groups, name)
bn_name = name + '_bn'
if if_act: if if_act:
return fluid.layers.batch_norm(input=conv, act='relu') return fluid.layers.batch_norm(input=conv, act='swish',
param_attr = ParamAttr(name=bn_name+"_scale"),
bias_attr=ParamAttr(name=bn_name+"_offset"),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
else: else:
return fluid.layers.batch_norm(input=conv) return fluid.layers.batch_norm(input=conv,
param_attr = ParamAttr(name=bn_name+"_scale"),
bias_attr=ParamAttr(name=bn_name+"_offset"),
moving_mean_name=bn_name + '_mean',
moving_variance_name=bn_name + '_variance')
def channel_shuffle(self, x, groups): def channel_shuffle(self, x, groups):
batchsize, num_channels, height, width = x.shape[0], x.shape[ batchsize, num_channels, height, width = x.shape[0], x.shape[1], x.shape[2], x.shape[3]
1], x.shape[2], x.shape[3]
channels_per_group = num_channels // groups channels_per_group = num_channels // groups
# reshape # reshape
x = fluid.layers.reshape( x = fluid.layers.reshape(x=x, shape=[batchsize, groups, channels_per_group, height, width])
x=x, shape=[batchsize, groups, channels_per_group, height, width])
x = fluid.layers.transpose(x=x, perm=[0, 2, 1, 3, 4]) x = fluid.layers.transpose(x=x, perm=[0,2,1,3,4])
# flatten # flatten
x = fluid.layers.reshape( x = fluid.layers.reshape(x=x, shape=[batchsize, num_channels, height, width])
x=x, shape=[batchsize, num_channels, height, width])
return x return x
def inverted_residual_unit(self, input, num_filters, stride, benchmodel):
def inverted_residual_unit(self, input, num_filters, stride, benchmodel, name=None):
assert stride in [1, 2], \ assert stride in [1, 2], \
"supported stride are {} but your stride is {}".format([1,2], stride) "supported stride are {} but your stride is {}".format([1,2], stride)
oup_inc = num_filters // 2 oup_inc = num_filters//2
inp = input.shape[1] inp = input.shape[1]
if benchmodel == 1: if benchmodel == 1:
x1, x2 = fluid.layers.split( x1, x2 = fluid.layers.split(
input, input, num_or_sections=[input.shape[1]//2, input.shape[1]//2], dim=1)
num_or_sections=[input.shape[1] // 2, input.shape[1] // 2], # x1 = input[:, :(input.shape[1]//2), :, :]
dim=1) # x2 = input[:, (input.shape[1]//2):, :, :]
conv_pw = self.conv_bn_layer( conv_pw = self.conv_bn_layer(
input=x2, input=x2,
num_filters=oup_inc, num_filters=oup_inc,
filter_size=1, filter_size=1,
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True) if_act=True,
name='stage_'+name+'_conv1')
conv_dw = self.conv_bn_layer( conv_dw = self.conv_bn_layer(
input=conv_pw, input=conv_pw,
num_filters=oup_inc, num_filters=oup_inc,
filter_size=3, filter_size=3,
stride=stride, stride=stride,
padding=1, padding=1,
num_groups=oup_inc, num_groups=oup_inc,
if_act=False) if_act=False,
use_cudnn=False,
name='stage_'+name+'_conv2')
conv_linear = self.conv_bn_layer( conv_linear = self.conv_bn_layer(
input=conv_dw, input=conv_dw,
num_filters=oup_inc, num_filters=oup_inc,
filter_size=1, filter_size=1,
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True) if_act=True,
name='stage_'+name+'_conv3')
out = fluid.layers.concat([x1, conv_linear], axis=1) out = fluid.layers.concat([x1, conv_linear], axis=1)
else: else:
#branch1 #branch1
conv_dw = self.conv_bn_layer( conv_dw_1 = self.conv_bn_layer(
input=input, input=input,
num_filters=inp, num_filters=inp,
filter_size=3, filter_size=3,
stride=stride, stride=stride,
padding=1, padding=1,
num_groups=inp, num_groups=inp,
if_act=False) if_act=False,
use_cudnn=False,
name='stage_'+name+'_conv4')
conv_linear_1 = self.conv_bn_layer( conv_linear_1 = self.conv_bn_layer(
input=conv_dw, input=conv_dw_1,
num_filters=oup_inc, num_filters=oup_inc,
filter_size=1, filter_size=1,
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True) if_act=True,
name='stage_'+name+'_conv5')
#branch2 #branch2
conv_pw = self.conv_bn_layer( conv_pw_2 = self.conv_bn_layer(
input=input, input=input,
num_filters=oup_inc, num_filters=oup_inc,
filter_size=1, filter_size=1,
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True) if_act=True,
name='stage_'+name+'_conv1')
conv_dw = self.conv_bn_layer(
input=conv_pw, conv_dw_2 = self.conv_bn_layer(
num_filters=oup_inc, input=conv_pw_2,
filter_size=3, num_filters=oup_inc,
stride=stride, filter_size=3,
stride=stride,
padding=1, padding=1,
num_groups=oup_inc, num_groups=oup_inc,
if_act=False) if_act=False,
use_cudnn=False,
name='stage_'+name+'_conv2')
conv_linear_2 = self.conv_bn_layer( conv_linear_2 = self.conv_bn_layer(
input=conv_dw, input=conv_dw_2,
num_filters=oup_inc, num_filters=oup_inc,
filter_size=1, filter_size=1,
stride=1, stride=1,
padding=0, padding=0,
num_groups=1, num_groups=1,
if_act=True) if_act=True,
name='stage_'+name+'_conv3')
out = fluid.layers.concat([conv_linear_1, conv_linear_2], axis=1) out = fluid.layers.concat([conv_linear_1, conv_linear_2], axis=1)
return self.channel_shuffle(out, 2) return self.channel_shuffle(out, 2)
def ShuffleNetV2_x0_5_swish():
def ShuffleNetV2_x0_5():
model = ShuffleNetV2(scale=0.5) model = ShuffleNetV2(scale=0.5)
return model return model
def ShuffleNetV2_x1_0_swish():
def ShuffleNetV2_x1_0():
model = ShuffleNetV2(scale=1.0) model = ShuffleNetV2(scale=1.0)
return model return model
def ShuffleNetV2_x1_5_swish():
def ShuffleNetV2_x1_5():
model = ShuffleNetV2(scale=1.5) model = ShuffleNetV2(scale=1.5)
return model return model
def ShuffleNetV2_x2_0_swish():
def ShuffleNetV2_x2_0():
model = ShuffleNetV2(scale=2.0) model = ShuffleNetV2(scale=2.0)
return model return model
def ShuffleNetV2_x8_0_swish():
model = ShuffleNetV2(scale=8.0)
return model
...@@ -36,42 +36,37 @@ class VGGNet(): ...@@ -36,42 +36,37 @@ class VGGNet():
"supported layers are {} but input layer is {}".format(vgg_spec.keys(), layers) "supported layers are {} but input layer is {}".format(vgg_spec.keys(), layers)
nums = vgg_spec[layers] nums = vgg_spec[layers]
conv1 = self.conv_block(input, 64, nums[0]) conv1 = self.conv_block(input, 64, nums[0], name="conv1_")
conv2 = self.conv_block(conv1, 128, nums[1]) conv2 = self.conv_block(conv1, 128, nums[1], name="conv2_")
conv3 = self.conv_block(conv2, 256, nums[2]) conv3 = self.conv_block(conv2, 256, nums[2], name="conv3_")
conv4 = self.conv_block(conv3, 512, nums[3]) conv4 = self.conv_block(conv3, 512, nums[3], name="conv4_")
conv5 = self.conv_block(conv4, 512, nums[4]) conv5 = self.conv_block(conv4, 512, nums[4], name="conv5_")
fc_dim = 4096 fc_dim = 4096
fc_name = ["fc6", "fc7", "fc8"]
fc1 = fluid.layers.fc( fc1 = fluid.layers.fc(
input=conv5, input=conv5,
size=fc_dim, size=fc_dim,
act='relu', act='relu',
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(name=fc_name[0] + "_weights"),
initializer=fluid.initializer.Normal(scale=0.005)), bias_attr=fluid.param_attr.ParamAttr(name=fc_name[0] + "_offset"))
bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Constant(value=0.1)))
fc1 = fluid.layers.dropout(x=fc1, dropout_prob=0.5) fc1 = fluid.layers.dropout(x=fc1, dropout_prob=0.5)
fc2 = fluid.layers.fc( fc2 = fluid.layers.fc(
input=fc1, input=fc1,
size=fc_dim, size=fc_dim,
act='relu', act='relu',
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(name=fc_name[1] + "_weights"),
initializer=fluid.initializer.Normal(scale=0.005)), bias_attr=fluid.param_attr.ParamAttr(name=fc_name[1] + "_offset"))
bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Constant(value=0.1)))
fc2 = fluid.layers.dropout(x=fc2, dropout_prob=0.5) fc2 = fluid.layers.dropout(x=fc2, dropout_prob=0.5)
out = fluid.layers.fc( out = fluid.layers.fc(
input=fc2, input=fc2,
size=class_dim, size=class_dim,
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(name=fc_name[2] + "_weights"),
initializer=fluid.initializer.Normal(scale=0.005)), bias_attr=fluid.param_attr.ParamAttr(name=fc_name[2] + "_offset"))
bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Constant(value=0.1)))
return out return out
def conv_block(self, input, num_filter, groups): def conv_block(self, input, num_filter, groups, name=None):
conv = input conv = input
for i in range(groups): for i in range(groups):
conv = fluid.layers.conv2d( conv = fluid.layers.conv2d(
...@@ -82,9 +77,9 @@ class VGGNet(): ...@@ -82,9 +77,9 @@ class VGGNet():
padding=1, padding=1,
act='relu', act='relu',
param_attr=fluid.param_attr.ParamAttr( param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Normal(scale=0.01)), name=name + str(i + 1) + "_weights"),
bias_attr=fluid.param_attr.ParamAttr( bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Constant(value=0.0))) name=name + str(i + 1) + "_offset"))
return fluid.layers.pool2d( return fluid.layers.pool2d(
input=conv, pool_size=2, pool_type='max', pool_stride=2) input=conv, pool_size=2, pool_type='max', pool_stride=2)
......
...@@ -156,13 +156,12 @@ def _reader_creator(file_list, ...@@ -156,13 +156,12 @@ def _reader_creator(file_list,
for line in lines: for line in lines:
if mode == 'train' or mode == 'val': if mode == 'train' or mode == 'val':
img_path, label = line.split() img_path, label = line.split()
#img_path = img_path.replace("JPEG", "jpeg")
img_path = os.path.join(data_dir, img_path) img_path = os.path.join(data_dir, img_path)
yield img_path, int(label) yield img_path, int(label)
elif mode == 'test': elif mode == 'test':
img_path, label = line.split() img_path, label = line.split()
#img_path = img_path.replace("JPEG", "jpeg")
img_path = os.path.join(data_dir, img_path) img_path = os.path.join(data_dir, img_path)
yield [img_path] yield [img_path]
mapper = functools.partial( mapper = functools.partial(
...@@ -185,9 +184,11 @@ def train(data_dir=DATA_DIR, pass_id_as_seed=0): ...@@ -185,9 +184,11 @@ def train(data_dir=DATA_DIR, pass_id_as_seed=0):
def val(data_dir=DATA_DIR): def val(data_dir=DATA_DIR):
file_list = os.path.join(data_dir, 'val_list.txt') file_list = os.path.join(data_dir, 'val_list.txt')
return _reader_creator(file_list, 'val', shuffle=False, data_dir=data_dir) return _reader_creator(file_list, 'val', shuffle=False,
data_dir=data_dir)
def test(data_dir=DATA_DIR): def test(data_dir=DATA_DIR):
file_list = os.path.join(data_dir, 'val_list.txt') file_list = os.path.join(data_dir, 'val_list.txt')
return _reader_creator(file_list, 'test', shuffle=False, data_dir=data_dir) return _reader_creator(file_list, 'test', shuffle=False,
data_dir=data_dir)
...@@ -16,7 +16,6 @@ THREAD = 8 ...@@ -16,7 +16,6 @@ THREAD = 8
BUF_SIZE = 102400 BUF_SIZE = 102400
DATA_DIR = 'data/ILSVRC2012' DATA_DIR = 'data/ILSVRC2012'
img_mean = np.array([0.485, 0.456, 0.406]).reshape((3, 1, 1)) img_mean = np.array([0.485, 0.456, 0.406]).reshape((3, 1, 1))
img_std = np.array([0.229, 0.224, 0.225]).reshape((3, 1, 1)) img_std = np.array([0.229, 0.224, 0.225]).reshape((3, 1, 1))
...@@ -40,8 +39,9 @@ def random_crop(img, size, scale=None, ratio=None): ...@@ -40,8 +39,9 @@ def random_crop(img, size, scale=None, ratio=None):
w = 1. * aspect_ratio w = 1. * aspect_ratio
h = 1. / aspect_ratio h = 1. / aspect_ratio
bound = min((float(img.shape[1]) / img.shape[0]) / (w**2),
(float(img.shape[0]) / img.shape[1]) / (h**2)) bound = min((float(img.shape[0]) / img.shape[1]) / (w**2),
(float(img.shape[1]) / img.shape[0]) / (h**2))
scale_max = min(scale[1], bound) scale_max = min(scale[1], bound)
scale_min = min(scale[0], bound) scale_min = min(scale[0], bound)
...@@ -50,15 +50,14 @@ def random_crop(img, size, scale=None, ratio=None): ...@@ -50,15 +50,14 @@ def random_crop(img, size, scale=None, ratio=None):
target_size = math.sqrt(target_area) target_size = math.sqrt(target_area)
w = int(target_size * w) w = int(target_size * w)
h = int(target_size * h) h = int(target_size * h)
i = np.random.randint(0, img.shape[0] - w + 1)
j = np.random.randint(0, img.shape[1] - h + 1)
i = np.random.randint(0, img.size[0] - w + 1) img = img[i:i + w, j:j + h, :]
j = np.random.randint(0, img.size[1] - h + 1)
img = img[i:i + h, j:j + w, :] resized = cv2.resize(img, (size, size), interpolation=cv2.INTER_LANCZOS4)
resized = cv2.resize(img, (size, size))
return resized return resized
def distort_color(img): def distort_color(img):
return img return img
...@@ -68,7 +67,7 @@ def resize_short(img, target_size): ...@@ -68,7 +67,7 @@ def resize_short(img, target_size):
percent = float(target_size) / min(img.shape[0], img.shape[1]) percent = float(target_size) / min(img.shape[0], img.shape[1])
resized_width = int(round(img.shape[1] * percent)) resized_width = int(round(img.shape[1] * percent))
resized_height = int(round(img.shape[0] * percent)) resized_height = int(round(img.shape[0] * percent))
resized = cv2.resize(img, (resized_width, resized_height)) resized = cv2.resize(img, (resized_width, resized_height), interpolation=cv2.INTER_LANCZOS4)
return resized return resized
...@@ -140,16 +139,19 @@ def _reader_creator(file_list, ...@@ -140,16 +139,19 @@ def _reader_creator(file_list,
shuffle=False, shuffle=False,
color_jitter=False, color_jitter=False,
rotate=False, rotate=False,
data_dir=DATA_DIR): data_dir=DATA_DIR,
pass_id_as_seed=0):
def reader(): def reader():
with open(file_list) as flist: with open(file_list) as flist:
full_lines = [line.strip() for line in flist] full_lines = [line.strip() for line in flist]
if shuffle: if shuffle:
np.random.shuffle(lines) if pass_id_as_seed:
np.random.seed(pass_id_as_seed)
np.random.shuffle(full_lines)
if mode == 'train' and os.getenv('PADDLE_TRAINING_ROLE'): if mode == 'train' and os.getenv('PADDLE_TRAINING_ROLE'):
# distributed mode if the env var `PADDLE_TRAINING_ROLE` exits # distributed mode if the env var `PADDLE_TRAINING_ROLE` exits
trainer_id = int(os.getenv("PADDLE_TRAINER_ID", "0")) trainer_id = int(os.getenv("PADDLE_TRAINER_ID", "0"))
trainer_count = int(os.getenv("PADDLE_TRAINERS", "1")) trainer_count = int(os.getenv("PADDLE_TRAINERS_NUM", "1"))
per_node_lines = len(full_lines) // trainer_count per_node_lines = len(full_lines) // trainer_count
lines = full_lines[trainer_id * per_node_lines:(trainer_id + 1) lines = full_lines[trainer_id * per_node_lines:(trainer_id + 1)
* per_node_lines] * per_node_lines]
...@@ -159,6 +161,7 @@ def _reader_creator(file_list, ...@@ -159,6 +161,7 @@ def _reader_creator(file_list,
len(full_lines))) len(full_lines)))
else: else:
lines = full_lines lines = full_lines
for line in lines: for line in lines:
if mode == 'train' or mode == 'val': if mode == 'train' or mode == 'val':
img_path, label = line.split() img_path, label = line.split()
...@@ -166,21 +169,25 @@ def _reader_creator(file_list, ...@@ -166,21 +169,25 @@ def _reader_creator(file_list,
img_path = os.path.join(data_dir, img_path) img_path = os.path.join(data_dir, img_path)
yield img_path, int(label) yield img_path, int(label)
elif mode == 'test': elif mode == 'test':
img_path = os.path.join(DATA_DIR, line) img_path, label = line.split()
img_path = img_path.replace("JPEG", "jpeg")
img_path = os.path.join(data_dir, img_path)
yield [img_path] yield [img_path]
image_mapper = functools.partial( image_mapper = functools.partial(
process_image, process_image,
mode=mode, mode=mode,
color_jitter=color_jitter, color_jitter=color_jitter,
rotate=color_jitter, rotate=rotate,
crop_size=224) crop_size=224)
reader = paddle.reader.xmap_readers( reader = paddle.reader.xmap_readers(
image_mapper, reader, THREAD, BUF_SIZE, order=False) image_mapper, reader, THREAD, BUF_SIZE, order=False)
return reader return reader
def train(data_dir=DATA_DIR): def train(data_dir=DATA_DIR, pass_id_as_seed=0):
file_list = os.path.join(data_dir, 'train_list.txt') file_list = os.path.join(data_dir, 'train_list.txt')
return _reader_creator( return _reader_creator(
file_list, file_list,
...@@ -188,14 +195,17 @@ def train(data_dir=DATA_DIR): ...@@ -188,14 +195,17 @@ def train(data_dir=DATA_DIR):
shuffle=True, shuffle=True,
color_jitter=False, color_jitter=False,
rotate=False, rotate=False,
data_dir=data_dir) data_dir=data_dir,
pass_id_as_seed=pass_id_as_seed)
def val(data_dir=DATA_DIR): def val(data_dir=DATA_DIR):
file_list = os.path.join(data_dir, 'val_list.txt') file_list = os.path.join(data_dir, 'val_list.txt')
return _reader_creator(file_list, 'val', shuffle=False, data_dir=data_dir) return _reader_creator(file_list, 'val', shuffle=False,
data_dir=data_dir)
def test(data_dir=DATA_DIR): def test(data_dir=DATA_DIR):
file_list = os.path.join(data_dir, 'val_list.txt') file_list = os.path.join(data_dir, 'val_list.txt')
return _reader_creator(file_list, 'test', shuffle=False, data_dir=data_dir) return _reader_creator(file_list, 'test', shuffle=False,
data_dir=data_dir)
...@@ -12,7 +12,6 @@ python train.py \ ...@@ -12,7 +12,6 @@ python train.py \
--lr=0.1 \ --lr=0.1 \
--num_epochs=200 \ --num_epochs=200 \
--l2_decay=1.2e-4 \ --l2_decay=1.2e-4 \
--model_category=models_name \
# >log_SE_ResNeXt50_32x4d.txt 2>&1 & # >log_SE_ResNeXt50_32x4d.txt 2>&1 &
#AlexNet: #AlexNet:
#python train.py \ #python train.py \
...@@ -23,7 +22,6 @@ python train.py \ ...@@ -23,7 +22,6 @@ python train.py \
# --image_shape=3,224,224 \ # --image_shape=3,224,224 \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --with_mem_opt=True \ # --with_mem_opt=True \
# --model_category=models_name \
# --lr_strategy=piecewise_decay \ # --lr_strategy=piecewise_decay \
# --num_epochs=120 \ # --num_epochs=120 \
# --lr=0.01 \ # --lr=0.01 \
...@@ -38,7 +36,6 @@ python train.py \ ...@@ -38,7 +36,6 @@ python train.py \
# --image_shape=3,224,224 \ # --image_shape=3,224,224 \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --with_mem_opt=True \ # --with_mem_opt=True \
# --model_category=models_name \
# --lr_strategy=piecewise_decay \ # --lr_strategy=piecewise_decay \
# --num_epochs=120 \ # --num_epochs=120 \
# --lr=0.1 \ # --lr=0.1 \
...@@ -51,12 +48,63 @@ python train.py \ ...@@ -51,12 +48,63 @@ python train.py \
# --class_dim=1000 \ # --class_dim=1000 \
# --image_shape=3,224,224 \ # --image_shape=3,224,224 \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --model_category=models_name \
# --with_mem_opt=True \ # --with_mem_opt=True \
# --lr_strategy=cosine_decay \ # --lr_strategy=cosine_decay \
# --num_epochs=240 \ # --num_epochs=240 \
# --lr=0.1 \ # --lr=0.1 \
# --l2_decay=4e-5 # --l2_decay=4e-5
#ResNet18:
#python train.py \
# --model=ResNet18 \
# --batch_size=256 \
# --total_images=1281167 \
# --class_dim=1000 \
# --image_shape=3,224,224 \
# --model_save_dir=output/ \
# --with_mem_opt=True \
# --lr_strategy=cosine_decay \
# --lr=0.1 \
# --num_epochs=120 \
# --l2_decay=1e-4
#ResNet34:
#python train.py \
# --model=ResNet34 \
# --batch_size=256 \
# --total_images=1281167 \
# --class_dim=1000 \
# --image_shape=3,224,224 \
# --model_save_dir=output/ \
# --with_mem_opt=True \
# --lr_strategy=cosine_decay \
# --lr=0.1 \
# --num_epochs=120 \
# --l2_decay=1e-4
#ShuffleNetv2:
#python train.py \
# --model=ShuffleNetV2 \
# --batch_size=1024 \
# --total_images=1281167 \
# --class_dim=1000 \
# --image_shape=3,224,224 \
# --model_save_dir=output/ \
# --with_mem_opt=True \
# --lr_strategy=cosine_decay_with_warmup \
# --lr=0.5 \
# --num_epochs=240 \
# --l2_decay=4e-5
#GoogleNet:
#python train.py \
# --model=GoogleNet \
# --batch_size=256 \
# --total_images=1281167 \
# --class_dim=1000 \
# --image_shape=3,224,224 \
# --model_save_dir=output/ \
# --with_mem_opt=True \
# --lr_strategy=cosine_decay \
# --lr=0.01 \
# --num_epochs=200 \
# --l2_decay=1e-4
#ResNet50: #ResNet50:
#python train.py \ #python train.py \
# --model=ResNet50 \ # --model=ResNet50 \
...@@ -66,7 +114,6 @@ python train.py \ ...@@ -66,7 +114,6 @@ python train.py \
# --image_shape=3,224,224 \ # --image_shape=3,224,224 \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --with_mem_opt=True \ # --with_mem_opt=True \
# --model_category=models_name \
# --lr_strategy=piecewise_decay \ # --lr_strategy=piecewise_decay \
# --num_epochs=120 \ # --num_epochs=120 \
# --lr=0.1 \ # --lr=0.1 \
...@@ -80,7 +127,6 @@ python train.py \ ...@@ -80,7 +127,6 @@ python train.py \
# --class_dim=1000 \ # --class_dim=1000 \
# --image_shape=3,224,224 \ # --image_shape=3,224,224 \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --model_category=models_name \
# --with_mem_opt=True \ # --with_mem_opt=True \
# --lr_strategy=piecewise_decay \ # --lr_strategy=piecewise_decay \
# --num_epochs=120 \ # --num_epochs=120 \
...@@ -96,7 +142,6 @@ python train.py \ ...@@ -96,7 +142,6 @@ python train.py \
# --image_shape=3,224,224 \ # --image_shape=3,224,224 \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --lr_strategy=piecewise_decay \ # --lr_strategy=piecewise_decay \
# --model_category=models_name \
# --with_mem_opt=True \ # --with_mem_opt=True \
# --lr=0.1 \ # --lr=0.1 \
# --num_epochs=120 \ # --num_epochs=120 \
...@@ -111,7 +156,6 @@ python train.py \ ...@@ -111,7 +156,6 @@ python train.py \
# --class_dim=1000 \ # --class_dim=1000 \
# --image_shape=3,224,224 \ # --image_shape=3,224,224 \
# --lr_strategy=cosine_decay \ # --lr_strategy=cosine_decay \
# --model_category=models_name \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --lr=0.1 \ # --lr=0.1 \
# --num_epochs=200 \ # --num_epochs=200 \
...@@ -126,7 +170,6 @@ python train.py \ ...@@ -126,7 +170,6 @@ python train.py \
# --class_dim=1000 \ # --class_dim=1000 \
# --image_shape=3,224,224 \ # --image_shape=3,224,224 \
# --lr_strategy=cosine_decay \ # --lr_strategy=cosine_decay \
# --model_category=models_name \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --lr=0.1 \ # --lr=0.1 \
# --num_epochs=200 \ # --num_epochs=200 \
...@@ -141,7 +184,6 @@ python train.py \ ...@@ -141,7 +184,6 @@ python train.py \
# --image_shape=3,224,224 \ # --image_shape=3,224,224 \
# --lr_strategy=cosine_decay \ # --lr_strategy=cosine_decay \
# --class_dim=1000 \ # --class_dim=1000 \
# --model_category=models_name \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --lr=0.1 \ # --lr=0.1 \
# --num_epochs=90 \ # --num_epochs=90 \
...@@ -158,7 +200,6 @@ python train.py \ ...@@ -158,7 +200,6 @@ python train.py \
# --lr_strategy=cosine_decay \ # --lr_strategy=cosine_decay \
# --lr=0.01 \ # --lr=0.01 \
# --num_epochs=90 \ # --num_epochs=90 \
# --model_category=models_name \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --with_mem_opt=True \ # --with_mem_opt=True \
# --l2_decay=3e-4 # --l2_decay=3e-4
...@@ -171,7 +212,6 @@ python train.py \ ...@@ -171,7 +212,6 @@ python train.py \
# --class_dim=1000 \ # --class_dim=1000 \
# --lr_strategy=cosine_decay \ # --lr_strategy=cosine_decay \
# --image_shape=3,224,224 \ # --image_shape=3,224,224 \
# --model_category=models_name \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --lr=0.01 \ # --lr=0.01 \
# --num_epochs=90 \ # --num_epochs=90 \
...@@ -189,7 +229,6 @@ python train.py \ ...@@ -189,7 +229,6 @@ python train.py \
# --lr=0.01 \ # --lr=0.01 \
# --num_epochs=90 \ # --num_epochs=90 \
# --with_mem_opt=True \ # --with_mem_opt=True \
# --model_category=models_name \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --l2_decay=3e-4 # --l2_decay=3e-4
...@@ -204,7 +243,6 @@ python train.py \ ...@@ -204,7 +243,6 @@ python train.py \
# --lr=0.001 \ # --lr=0.001 \
# --num_epochs=120 \ # --num_epochs=120 \
# --with_mem_opt=False \ # --with_mem_opt=False \
# --model_category=models_name \
# --model_save_dir=output/ \ # --model_save_dir=output/ \
# --lr_strategy=adam \ # --lr_strategy=adam \
# --use_gpu=False # --use_gpu=False
......
...@@ -10,14 +10,15 @@ import math ...@@ -10,14 +10,15 @@ import math
import paddle import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import paddle.dataset.flowers as flowers import paddle.dataset.flowers as flowers
import reader import reader as reader
import argparse import argparse
import functools import functools
import subprocess import subprocess
import utils import utils
from utils.learning_rate import cosine_decay import models
from utils.fp16_utils import create_master_params_grads, master_param_to_train_param from utils.fp16_utils import create_master_params_grads, master_param_to_train_param
from utility import add_arguments, print_arguments from utils.utility import add_arguments, print_arguments
from utils.learning_rate import cosine_decay_with_warmup
IMAGENET1000 = 1281167 IMAGENET1000 = 1281167
...@@ -44,19 +45,6 @@ add_arg('fp16', bool, False, "Enable half precision ...@@ -44,19 +45,6 @@ add_arg('fp16', bool, False, "Enable half precision
add_arg('scale_loss', float, 1.0, "Scale loss for fp16." ) add_arg('scale_loss', float, 1.0, "Scale loss for fp16." )
add_arg('l2_decay', float, 1e-4, "L2_decay parameter.") add_arg('l2_decay', float, 1e-4, "L2_decay parameter.")
add_arg('momentum_rate', float, 0.9, "momentum_rate.") add_arg('momentum_rate', float, 0.9, "momentum_rate.")
# yapf: enable
def set_models(model_category):
global models
assert model_category in ["models", "models_name"
], "{} is not in lists: {}".format(
model_category, ["models", "models_name"])
if model_category == "models_name":
import models_name as models
else:
import models as models
def optimizer_setting(params): def optimizer_setting(params):
ls = params["learning_strategy"] ls = params["learning_strategy"]
...@@ -68,8 +56,7 @@ def optimizer_setting(params): ...@@ -68,8 +56,7 @@ def optimizer_setting(params):
else: else:
total_images = params["total_images"] total_images = params["total_images"]
batch_size = ls["batch_size"] batch_size = ls["batch_size"]
step = int(total_images / batch_size + 1) step = int(math.ceil(float(total_images) / batch_size))
bd = [step * e for e in ls["epochs"]] bd = [step * e for e in ls["epochs"]]
base_lr = params["lr"] base_lr = params["lr"]
lr = [] lr = []
...@@ -88,16 +75,34 @@ def optimizer_setting(params): ...@@ -88,16 +75,34 @@ def optimizer_setting(params):
batch_size = ls["batch_size"] batch_size = ls["batch_size"]
l2_decay = params["l2_decay"] l2_decay = params["l2_decay"]
momentum_rate = params["momentum_rate"] momentum_rate = params["momentum_rate"]
step = int(total_images / batch_size + 1) step = int(math.ceil(float(total_images) / batch_size))
lr = params["lr"]
num_epochs = params["num_epochs"]
optimizer = fluid.optimizer.Momentum(
learning_rate=fluid.layers.cosine_decay(
learning_rate=lr, step_each_epoch=step, epochs=num_epochs),
momentum=momentum_rate,
regularization=fluid.regularizer.L2Decay(l2_decay))
elif ls["name"] == "cosine_warmup_decay":
if "total_images" not in params:
total_images = IMAGENET1000
else:
total_images = params["total_images"]
batch_size = ls["batch_size"]
l2_decay = params["l2_decay"]
momentum_rate = params["momentum_rate"]
step = int(math.ceil(float(total_images) / batch_size))
lr = params["lr"] lr = params["lr"]
num_epochs = params["num_epochs"] num_epochs = params["num_epochs"]
optimizer = fluid.optimizer.Momentum( optimizer = fluid.optimizer.Momentum(
learning_rate=cosine_decay( learning_rate=cosine_decay_with_warmup(
learning_rate=lr, step_each_epoch=step, epochs=num_epochs), learning_rate=lr, step_each_epoch=step, epochs=num_epochs),
momentum=momentum_rate, momentum=momentum_rate,
regularization=fluid.regularizer.L2Decay(l2_decay)) regularization=fluid.regularizer.L2Decay(l2_decay))
elif ls["name"] == "linear_decay": elif ls["name"] == "linear_decay":
if "total_images" not in params: if "total_images" not in params:
total_images = IMAGENET1000 total_images = IMAGENET1000
...@@ -119,6 +124,25 @@ def optimizer_setting(params): ...@@ -119,6 +124,25 @@ def optimizer_setting(params):
elif ls["name"] == "adam": elif ls["name"] == "adam":
lr = params["lr"] lr = params["lr"]
optimizer = fluid.optimizer.Adam(learning_rate=lr) optimizer = fluid.optimizer.Adam(learning_rate=lr)
elif ls["name"] == "rmsprop_cosine":
if "total_images" not in params:
total_images = IMAGENET1000
else:
total_images = params["total_images"]
batch_size = ls["batch_size"]
l2_decay = params["l2_decay"]
momentum_rate = params["momentum_rate"]
step = int(math.ceil(float(total_images) / batch_size))
lr = params["lr"]
num_epochs = params["num_epochs"]
optimizer = fluid.optimizer.RMSProp(
learning_rate=fluid.layers.cosine_decay(
learning_rate=lr, step_each_epoch=step, epochs=num_epochs),
momentum=momentum_rate,
regularization=fluid.regularizer.L2Decay(l2_decay),
# RMSProp Optimizer: Apply epsilon=1 on ImageNet.
epsilon=1
)
else: else:
lr = params["lr"] lr = params["lr"]
l2_decay = params["l2_decay"] l2_decay = params["l2_decay"]
...@@ -130,7 +154,6 @@ def optimizer_setting(params): ...@@ -130,7 +154,6 @@ def optimizer_setting(params):
return optimizer return optimizer
def net_config(image, label, model, args): def net_config(image, label, model, args):
model_list = [m for m in dir(models) if "__" not in m] model_list = [m for m in dir(models) if "__" not in m]
assert args.model in model_list, "{} is not lists: {}".format(args.model, assert args.model in model_list, "{} is not lists: {}".format(args.model,
...@@ -220,6 +243,13 @@ def build_program(is_train, main_prog, startup_prog, args): ...@@ -220,6 +243,13 @@ def build_program(is_train, main_prog, startup_prog, args):
else: else:
return py_reader, avg_cost, acc_top1, acc_top5 return py_reader, avg_cost, acc_top1, acc_top5
def get_device_num():
visible_device = os.getenv('CUDA_VISIBLE_DEVICES')
if visible_device:
device_num = len(visible_device.split(','))
else:
device_num = subprocess.check_output(['nvidia-smi','-L']).decode().count('\n')
return device_num
def train(args): def train(args):
# parameters from arguments # parameters from arguments
...@@ -268,12 +298,7 @@ def train(args): ...@@ -268,12 +298,7 @@ def train(args):
exe, pretrained_model, main_program=train_prog, predicate=if_exist) exe, pretrained_model, main_program=train_prog, predicate=if_exist)
if args.use_gpu: if args.use_gpu:
visible_device = os.getenv('CUDA_VISIBLE_DEVICES') device_num = get_device_num()
if visible_device:
device_num = len(visible_device.split(','))
else:
device_num = subprocess.check_output(
['nvidia-smi', '-L']).decode().count('\n')
else: else:
device_num = 1 device_num = 1
train_batch_size = args.batch_size / device_num train_batch_size = args.batch_size / device_num
...@@ -345,8 +370,8 @@ def train(args): ...@@ -345,8 +370,8 @@ def train(args):
if batch_id % 10 == 0: if batch_id % 10 == 0:
print("Pass {0}, trainbatch {1}, loss {2}, \ print("Pass {0}, trainbatch {1}, loss {2}, \
acc1 {3}, acc5 {4}, lr{5}, time {6}" acc1 {3}, acc5 {4}, lr {5}, time {6}"
.format(pass_id, batch_id, loss, acc1, acc5, "%.5f" % .format(pass_id, batch_id, "%.5f"%loss, "%.5f"%acc1, "%.5f"%acc5, "%.5f" %
lr, "%2.2f sec" % period)) lr, "%2.2f sec" % period))
sys.stdout.flush() sys.stdout.flush()
batch_id += 1 batch_id += 1
...@@ -378,7 +403,7 @@ def train(args): ...@@ -378,7 +403,7 @@ def train(args):
if test_batch_id % 10 == 0: if test_batch_id % 10 == 0:
print("Pass {0},testbatch {1},loss {2}, \ print("Pass {0},testbatch {1},loss {2}, \
acc1 {3},acc5 {4},time {5}" acc1 {3},acc5 {4},time {5}"
.format(pass_id, test_batch_id, loss, acc1, acc5, .format(pass_id, test_batch_id, "%.5f"%loss,"%.5f"%acc1, "%.5f"%acc5,
"%2.2f sec" % period)) "%2.2f sec" % period))
sys.stdout.flush() sys.stdout.flush()
test_batch_id += 1 test_batch_id += 1
...@@ -391,8 +416,8 @@ def train(args): ...@@ -391,8 +416,8 @@ def train(args):
print("End pass {0}, train_loss {1}, train_acc1 {2}, train_acc5 {3}, " print("End pass {0}, train_loss {1}, train_acc1 {2}, train_acc5 {3}, "
"test_loss {4}, test_acc1 {5}, test_acc5 {6}".format( "test_loss {4}, test_acc1 {5}, test_acc5 {6}".format(
pass_id, train_loss, train_acc1, train_acc5, test_loss, pass_id, "%.5f"%train_loss, "%.5f"%train_acc1, "%.5f"%train_acc5, "%.5f"%test_loss,
test_acc1, test_acc5)) "%.5f"%test_acc1, "%.5f"%test_acc5))
sys.stdout.flush() sys.stdout.flush()
model_path = os.path.join(model_save_dir + '/' + model_name, model_path = os.path.join(model_save_dir + '/' + model_name,
...@@ -429,7 +454,6 @@ def train(args): ...@@ -429,7 +454,6 @@ def train(args):
def main(): def main():
args = parser.parse_args() args = parser.parse_args()
set_models(args.model_category)
print_arguments(args) print_arguments(args)
train(args) train(args)
......
from .learning_rate import cosine_decay, lr_warmup from .learning_rate import cosine_decay, lr_warmup
from .fp16_utils import create_master_params_grads, master_param_to_train_param from .fp16_utils import create_master_params_grads, master_param_to_train_param
from .utility import add_arguments, print_arguments
...@@ -21,6 +21,33 @@ def cosine_decay(learning_rate, step_each_epoch, epochs=120): ...@@ -21,6 +21,33 @@ def cosine_decay(learning_rate, step_each_epoch, epochs=120):
(ops.cos(epoch * (math.pi / epochs)) + 1)/2 (ops.cos(epoch * (math.pi / epochs)) + 1)/2
return decayed_lr return decayed_lr
def cosine_decay_with_warmup(learning_rate, step_each_epoch, epochs=120):
"""Applies cosine decay to the learning rate.
lr = 0.05 * (math.cos(epoch * (math.pi / 120)) + 1)
decrease lr for every mini-batch and start with warmup.
"""
global_step = _decay_step_counter()
lr = fluid.layers.tensor.create_global_var(
shape=[1],
value=0.0,
dtype='float32',
persistable=True,
name="learning_rate")
warmup_epoch = fluid.layers.fill_constant(
shape=[1], dtype='float32', value=float(5), force_cpu=True)
with init_on_cpu():
epoch = ops.floor(global_step / step_each_epoch)
with control_flow.Switch() as switch:
with switch.case(epoch < warmup_epoch):
decayed_lr = learning_rate * (global_step / (step_each_epoch * warmup_epoch))
fluid.layers.tensor.assign(input=decayed_lr, output=lr)
with switch.default():
decayed_lr = learning_rate * \
(ops.cos((global_step - warmup_epoch * step_each_epoch) * (math.pi / (epochs * step_each_epoch))) + 1)/2
fluid.layers.tensor.assign(input=decayed_lr, output=lr)
return lr
def lr_warmup(learning_rate, warmup_steps, start_lr, end_lr): def lr_warmup(learning_rate, warmup_steps, start_lr, end_lr):
""" Applies linear learning rate warmup for distributed training """ Applies linear learning rate warmup for distributed training
......
...@@ -37,10 +37,10 @@ def print_arguments(args): ...@@ -37,10 +37,10 @@ def print_arguments(args):
:param args: Input argparse.Namespace for printing. :param args: Input argparse.Namespace for printing.
:type args: argparse.Namespace :type args: argparse.Namespace
""" """
print("----------- Configuration Arguments -----------") print("------------- Configuration Arguments -------------")
for arg, value in sorted(six.iteritems(vars(args))): for arg, value in sorted(six.iteritems(vars(args))):
print("%s: %s" % (arg, value)) print("%25s : %s" % (arg, value))
print("------------------------------------------------") print("----------------------------------------------------")
def add_arguments(argname, type, default, help, argparser, **kwargs): def add_arguments(argname, type, default, help, argparser, **kwargs):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册