未验证 提交 a36148cf 编写于 作者: L lilong12 提交者: GitHub

update documents (#22)

* update README.md and move other documents into README.md
上级 1cf2e6d4
此差异已折叠。
# PLSC API简介
## 默认配置参数
PLSC大规模分类库提供了默认配置参数,用于设置训练、评估和模型相关的信息,如训练数据集目录、训练轮数等。
这些参数信息位于plsc.config模块中,下面给出这些参数的含义和默认值。
### 训练相关
| 参数名称 | 参数含义 | 默认值 |
| :------- | :------- | :----- |
| train_batch_size | 训练阶段batch size的值 | 128 |
| dataset_dir | 数据集根目录 | './train_data' |
| train_image_num | 训练图像的数量 | 5822653 |
| train_epochs | 训练轮数 | 120 |
| warmup_epochs | warmup轮数 | 0 |
| lr | 初始学习率 | 0.1 |
| lr_steps | 学习率衰减的步数 | (100000,160000,220000) |
### 评估相关
| 参数名称 | 参数含义 | 默认值 |
| :------- | :------- | :----- |
| val_targets | 验证数据集名称,以逗号分隔,如'lfw,cfp_fp' | lfw |
| test_batch_size | 评估阶段batch size的值 | 120 |
| with_test | 是否在每轮训练之后开始评估模型 | True |
### 模型相关
| 参数名称 | 参数含义 | 默认值 |
| :------- | :------- | :----- |
| model_name | 使用的模型的名称 | 'RestNet50' |
| checkpoint_dir | 预训练模型目录 | "" |
| model_save_dir | 训练模型的保存目录 | "./output" |
| loss_type | loss类型,可选值为softmax、arcface、dist_softmax和dist_arcface | 'dist_arcface' |
| num_classes | 分类类别的数量 | 85742 |
| image_shape | 图像尺寸列表,格式为CHW | [3, 112, 112] |
| margin | dist_arcface和arcface的margin参数 | 0.5 |
| scale | dist_arcface和arcface的scale参数 | 64.0 |
| emb_size | 模型最后一层隐层的输出维度 | 512 |
备注:
* checkpoint_dir和model_save_dir的区别:checkpoint_dir用于在训练/评估前加载的预训练模型所在目录;model_save_dir指的是训练后模型的保存目录。
### 参数设置API
可以通过该组API修改默认参数,具体API及其描述见下表。
| API | 描述 | 参数说明 |
| :------------------- | :--------------------| :---------------------- |
| set_val_targets(targets) | 设置验证数据集 | 以逗号分隔的验证集名称,类型为字符串 |
| set_train_batch_size(size) | 设置训练batch size的值 | 类型为int |
| set_test_batch_size(size) | 设置评估batch size的值 | 类型为int |
| set_hdfs_info(fs_name, fs_ugi, directory) | 设置hdfs文件系统信息 | fs_name为hdfs地址,类型为字符串;fs_ugi为逗号分隔的用户名和密码,类型为字符串;directory为hdfs上的路径 |
| set_model_save_dir(dir) | 设置模型保存路径model_save_dir | 类型为字符串 |
| set_dataset_dir(dir) | 设置数据集根目录dataset_dir | 类型为字符串 |
| set_train_image_num(num) | 设置训练图像的总数量 | 类型为int |
| set_calc_acc(calc) | 设置是否在训练时计算acc1和acc5值 | 类型为bool |
| set_class_num(num) | 设置分类类别的总数量 | 类型为int |
| set_emb_size(size) | 设置最后一层隐层的输出维度 | 类型为int |
| set_model(model) | 设置用户使用的自定义模型类实例 | BaseModel的子类 |
| set_train_epochs(num) | 设置训练的轮数 | 类型为int |
| set_checkpoint_dir(dir) | 设置用于加载的预训练模型的目录 | 类型为字符串 |
| set_warmup_epochs(num) | 设置warmup的轮数 | 类型为int |
| set_loss_type(loss_type) | 设置模型的loss类型 | 类型为字符串 |
| set_image_shape(size) | 设置图像尺寸,格式为CHW | 类型为元组 |
| set_optimizer(optimizer) | 设置训练阶段的optimizer | Optimizer类实例 |
| convert_for_prediction() | 将预训练模型转换为预测模型 | None |
| test() | 模型评估 | None |
| train() | 模型训练 | None |
备注:
当设置set_calc_acc的参数值为True,会在训练是计算acc1和acc5的值,但这会占用额外的显存空间。
上述API均为PaddlePaddle大规模分类库PLSC的Entry类的方法,需要通过该类的实例
调用,例如:
```python
from plsc import Entry
ins = Entry()
ins.set_class_num(85742)
ins.train()
```
# Base64格式图像预处理
## 简介
实际业务中,一种常见的训练数据存储格式是将图像数据编码为base64格式。训练数据文件的每一行存储一张图像的base64数据和该图像的标签,并通常以制表符('\t')分隔。
通常,所有训练数据文件的文件列表记录在一个单独的文件中,整个训练数据集的目录结构如下:
```shell
dataset
|-- file_list.txt
|-- dataset.part1
|-- dataset.part2
... ....
`-- dataset.part10
```
其中,file_list.txt记录训练数据的文件列表,每行代表一个文件,以上面的例子来说,file_list.txt的文件内容如下:
```shell
dataset.part1
dataset.part2
...
dataset.part10
```
而数据文件的每一行表示一张图像数据的base64表示,以及以制表符分隔的图像标签。
对于分布式训练,需要每张GPU卡处理相同数量的图像数据,并且通常需要在训练前做一次训练数据的全局shuffle。
本文档介绍Base64格式图像预处理工具,用于在对训练数据做全局shuffle,并将训练数据均分到多个数据文件,数据文件的数量和训练中使用的GPU卡数相同。当训练数据的总量不能整除GPU卡数时,通常会填充部分图像数据(填充的图像数据随机选自训练数据集),以保证总的训练图像数量是GPU卡数的整数倍。
## 工具使用方法
工具位于tools目录下。使用该工具时,需要安装sqlite3模块,可以通过下面的命令安装:
```shell
pip install sqlite3
```
可以通过下面的命令行查看工具的使用帮助信息:
```python
python tools/process_base64_files.py --help
```
该工具支持以下命令行选项:
* data_dir: 训练数据的根目录
* file_list: 记录训练数据文件的列表文件,如file_list.txt
* nranks: 训练所使用的GPU卡的数量。
可以通过以下命令行运行该工具:
```shell
python tools/process_base64_files.py --data_dir=./dataset --file_list=file_list.txt --nranks=8
```
那么,会生成8个数量数据文件,每个文件中包含相同数量的训练数据。
最终的目录格式如下:
```shell
dataset
|-- file_list.txt
|-- dataset.part1
|-- dataset.part2
... ....
`-- dataset.part8
```
# 自定义模型
默认地,PaddlePaddle大规模分类库构建基于ResNet50模型的训练模型。
PLSC提供了模型基类plsc.models.base_model.BaseModel,用户可以基于该基类构建自己的网络模型。用户自定义的模型类需要继承自该基类,并实现build_network方法,该方法用于构建用户自定义模型。
下面的例子给出如何使用BaseModel基类定义用户自己的网络模型, 以及如何使用。
```python
import paddle.fluid as fluid
from plsc import Entry
from plsc.models.base_model import BaseModel
class ResNet(BaseModel):
def __init__(self, layers=50, emb_dim=512):
super(ResNet, self).__init__()
self.layers = layers
self.emb_dim = emb_dim
def build_network(self,
input,
label,
is_train):
layers = self.layers
supported_layers = [50, 101, 152]
assert layers in supported_layers, \
"supported layers {}, but given {}".format(supported_layers, layers)
if layers == 50:
depth = [3, 4, 14, 3]
num_filters = [64, 128, 256, 512]
elif layers == 101:
depth = [3, 4, 23, 3]
num_filters = [256, 512, 1024, 2048]
elif layers == 152:
depth = [3, 8, 36, 3]
num_filters = [256, 512, 1024, 2048]
conv = self.conv_bn_layer(
input=input, num_filters=64, filter_size=3, stride=1,
pad=1, act='prelu', is_train=is_train)
for block in range(len(depth)):
for i in range(depth[block]):
conv = self.bottleneck_block(
input=conv,
num_filters=num_filters[block],
stride=2 if i == 0 else 1,
is_train=is_train)
bn = fluid.layers.batch_norm(input=conv, act=None, epsilon=2e-05,
is_test=False if is_train else True)
drop = fluid.layers.dropout(x=bn, dropout_prob=0.4,
dropout_implementation='upscale_in_train',
is_test=False if is_train else True)
fc = fluid.layers.fc(
input=drop,
size=self.emb_dim,
act=None,
param_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.Xavier(uniform=False, fan_in=0.0)),
bias_attr=fluid.param_attr.ParamAttr(
initializer=fluid.initializer.ConstantInitializer()))
emb = fluid.layers.batch_norm(input=fc, act=None, epsilon=2e-05,
is_test=False if is_train else True)
return emb
def conv_bn_layer(
... ...
if __name__ == "__main__":
ins = Entry()
ins.set_model(ResNet())
ins.train()
```
用户自定义模型类需要继承自基类BaseModel,并实现build_network方法,实现用户的自定义模型。
build_network方法的输入如下:
* input: 输入图像数据
* label: 图像类别
* is_train: 表示训练阶段还是测试/预测阶段
build_network方法返回用户自定义组网的输出变量。
# 分布式参数转换
## 简介
对于最后一层全连接层参数(W和b,假设参数b存在,否则,全连接参数仅为W),通常切分到所有训练GPU卡。那么,每个GPU卡上只保存部分全连接层参数。
当保存模型时,各个GPU卡的分布式参数均会得到保存。
在热启动或fine-tuning阶段,如果训练GPU卡数和热启动前或者预训练阶段使用的GPU卡数不同时,需要对分布式参数进行转换,以保证分布式参数的数量和训练使用的GPU卡数相同。
默认地,当使用train()方法时,会自动进行分布式参数的转换。
## 工具使用方法
分布式参数转换工具也可以单独使用,可以通过下面的命令查看使用方法:
```shell
python -m plsc.utils.process_distfc_parameter --help
```
该工具支持以下命令行选项:
| 选项 | 描述 |
| :---------------------- | :------------------- |
| name_feature | 分布式参数的名称特征,用于识别分布式参数。默认的,分布式参数的名称前缀为dist@arcface@rank@rankid或者dist@softmax@rank@rankid。其中,rankid为表示GPU卡的id。默认地,name_feature的值为@rank@。用户通常不需要改变该参数的值 |
| pretrain_nranks | 预训练阶段使用的GPU卡数 |
| nranks | 本次训练将使用的GPU卡数 |
| num_classes | 分类类别的数目 |
| emb_dim | 倒数第二层全连接层的输出维度,不包含batch size |
| pretrained_model_dir | 预训练模型的保存目录 |
| output_dir | 转换后分布式参数的保存目录 |
通常,在预训练模型中包含meta.pickle文件,该文件记录预训练阶段使用的GPU卡数,分类类别书和倒数第二层全连接层的输出维度,因此通常不需要指定pretrain_nranks、num_classes和emb_dim参数。
可以通过以下命令转换分布式参数:
```shell
python -m plsc.utils.process_distfc_parameter --nranks=4 --pretrained_model_dir=./output --output_dir=./output_post
```
需要注意的是,转换后的分布式参数保存目录只包含转换后的分布式参数,而不包含其它模型参数。因此,通常需要使用转换后的分布式参数替换预训练模型中的分布式参数。
# 预测模型导出
通常,PaddlePaddle大规模分类库在训练过程中保存的模型只保存模型参数信息,而不包括预测模型结构。为了部署PLSC预测库,需要将预训练模型导出为预测模型。预测模型包括预测所需要的模型参数和模型结构,用于后续地预测任务(参见[C++预测库使用](./serving.md)
预测模型包括预测所需要的模型参数和模型结构,用于后续地预测任务(参见[C++预测库使用](./serving.md))。
可以通过下面的代码将预训练模型导出为预测模型:
```python
from plsc import Entry
if __name__ == "__main__":
ins = Entry()
ins.set_checkpoint_dir('./pretrain_model')
ins.set_model_save_dir('./inference_model')
ins.convert_for_prediction()
```
其中'./pretrain_model'目录为预训练模型目录,'./inference_model'为用于预测的模型目录。
# 安装说明
## 1. 安装PaddlePaddle
版本要求:
* PaddlePaddle >= 1.6.2
* Python 2.7+ (python2 only)
关于PaddlePaddle对操作系统、CUDA、cuDNN等软件版本的兼容信息,请查看[PaddlePaddle安装说明](https://www.paddlepaddle.org.cn/documentation/docs/zh/beginners_guide/install/index_cn.html)
备注:当前版本尚不完全兼容PY3。
### pip安装
当前,需要在GPU版本的PaddlePaddle下使用大规模分类库。
```shell
pip install paddlepaddle-gpu
```
### Conda安装
PaddlePaddle支持Conda安装,减少相关依赖模块的安装成本。conda相关使用说明可以参考[Anaconda](https://www.anaconda.com/distribution/)
```shell
conda install -c paddle paddlepaddle-gpu cudatoolkit=9.0
```
* 请安装NVIDIA NCCL >= 2.4.7,并在Linux系统下运行。
更多安装方式和信息请参考[PaddlePaddle安装说明](https://www.paddlepaddle.org.cn/documentation/docs/zh/beginners_guide/install/index_cn.html)
## 2. 安装依赖包
```shell
pip install -r requirements.txt
```
## 3. 安装大规模分类库
```shell
pip install plsc
```
# PLSC Serving
### 安装
server端
需要python3环境运行
```bash
pip3 install plsc-serving
```
client端
需要安装ujson
```bash
pip install ujson
```
复制[client脚本](./serving/client/face_service/face_service.py)到使用路径
### 使用
server端
目前仅支持在GPU机器上进行预测,运行环境要求cuda版本>=9.0。
```python
from plsc_serving.run import PLSCServer
fs = PLSCServer()
#设定使用的模型文路径,str类型,绝对路径
fs.with_model(model_path = '/XXX/XXX')
#跑单个进程,gpu_index指定使用的gpu,int类型,默认为0;port指定使用的端口,int类型,默认为8866
fs.run(gpu_index = 0, port = 8010)
```
client端
```python
from face_service import FaceService
with open('./data/00000000.jpg', 'rb') as f:
image = f.read()
fc = FaceService()
#添加server端连接,str类型,默认本机8010端口
fc.connect('127.0.0.1:8010')
#调用server端预测,输入为样本列表list类型,返回值为样本对应的embedding结果,list类型,shape为 batch size * embedding size
result = fc.encode([image])
print(result[0])
bc.close()
```
# 模型训练和评估
PaddlePaddle大规模分类提供了从训练、评估到预测部署的全流程解决方案。本文档介绍如何使用PaddlePaddle大规模分类库快速完成训练、评估和预测部署。
## 数据准备
我们假设用户数据集的组织结构如下:
```shell
train_data/
|-- agedb_30.bin
|-- cfp_ff.bin
|-- cfp_fp.bin
|-- images
|-- label.txt
`-- lfw.bin
```
其中,*train_data*是用户数据的根目录,*agedb_30.bin**cfp_ff.bin**cfp_fp.bin**lfw.bin*分别是不同的验证数据集,且这些验证数据集不是全部必须的。本文档教程默认使用lfw.bin作为验证数据集,因此在浏览本教程时,请确保lfw.bin验证数据集可用。*images*目录包含JPEG格式的训练图像,*label.txt*中的每一行对应一张训练图像以及该图像的类别。
*label.txt*文件的内容示例如下:
```shell
images/00000000.jpg 0
images/00000001.jpg 0
images/00000002.jpg 0
images/00000003.jpg 0
images/00000004.jpg 0
images/00000005.jpg 0
images/00000006.jpg 0
images/00000007.jpg 0
... ...
```
## 模型训练
### 训练代码
下面的例子给出使用PLSC完成大规模分类训练的脚本*train.py*
```python
from plsc import Entry
if __name__ == "__main__":
ins = Entry()
ins.train()
```
1. 从plsc包导入Entry类,其是使用PLCS大规模分类库功能的接口类。
2. 生成Entry类的实例。
3. 调用Entry类的train方法,即可开始训练。
默认地,训练阶段每个训练轮次的之后会使用验证集验证模型的效果,当没有验证数据集时,可以使用*set_with_test(False)* API关闭验证功能。
### 开始训练
下面的例子给出如何使用上述脚本启动训练任务:
```shell
python -m paddle.distributed.launch \
--cluster_node_ips="127.0.0.1" \
--node_ip="127.0.0.1" \
--selected_gpus=0,1,2,3,4,5,6,7 \
train.py
```
paddle.distributed.launch模块用于启动多机/多卡分布式训练任务脚本,简化分布式训练任务启动过程,各个参数的含义如下:
* cluster_node_ips: 参与训练的节点的ip地址列表,以逗号分隔;
* node_ip: 当前训练节点的ip地址;
* selected_gpus: 每个训练节点所使用的gpu设备列表,以逗号分隔。
## 模型验证
本教程中,我们使用lfw.bin验证数据集评估训练模型的效果。
### 验证代码
下面的例子给出使用PLSC完成大规模分类验证的脚本*val.py*
```python
from plsc import Entry
if __name__ == "__main__":
ins = Entry()
ins.set_checkpoint("output/0")
ins.test()
```
默认地,PLSC将训练脚本保存在'./ouput'目录下,并以pass作为区分不同训练轮次模型的子目录,例如'./output/0'目录下保存完成第一个轮次的训练后保存的模型。
在模型评估阶段,我们首先需要设置训练模型的目录,接着调用Entry类的test方法开始模型验证。
numpy>=1.12, <=1.16.4 ; python_version<"3.5"
numpy>=1.12 ; python_version>="3.5"
scikit-learn<=0.20 ; python_version<"3.5"
scikit-learn ; python_version>="3.5"
scipy>=0.19.0, <=1.2.1 ; python_version<"3.5"
scipy ; python_version>="3.5"
Pillow
sklearn
easydict
six
paddlepaddle-gpu
paddlepaddle-gpu>=1.6.2
......@@ -23,7 +23,16 @@ from plsc.version import plsc_version
REQUIRED_PACKAGES = [
'sklearn', 'easydict', 'Pillow', 'numpy', 'scipy', 'six'
'numpy>=1.12,<=1.16.4;python_version<"3.5"',
'numpy>=1.12;python_version>="3.5"',
'scikit-learn<=0.20;python_version<"3.5"',
'scikit-learn;python_version>="3.5"',
'scipy>=0.19.0,<=1.2.1;python_version<"3.5"',
'scipy;python_version>="3.5"',
'sklearn',
'easydict',
'Pillow',
'six'
]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册