未验证 提交 5173059d 编写于 作者: W wuzewu 提交者: GitHub

Update docs

上级 a0d3efa2
......@@ -2,65 +2,66 @@
<img src="./docs/imgs/paddlehub_logo.jpg" align="middle"
</p>
[![Build Status](https://travis-ci.org/PaddlePaddle/PaddleHub.svg?branch=release/v1.6)](https://travis-ci.org/PaddlePaddle/PaddleHub)
[![Build Status](https://travis-ci.org/PaddlePaddle/PaddleHub.svg?branch=release/v1.8)](https://travis-ci.org/PaddlePaddle/PaddleHub)
[![License](https://img.shields.io/badge/license-Apache%202-red.svg)](LICENSE)
[![Version](https://img.shields.io/github/release/PaddlePaddle/PaddleHub.svg)](https://github.com/PaddlePaddle/PaddleHub/releases)
![python version](https://img.shields.io/badge/python-3.6+-orange.svg)
![support os](https://img.shields.io/badge/os-linux%2C%20win%2C%20mac-yellow.svg)
## 简介
PaddleHub是飞桨生态的预训练模型应用工具,开发者可以便捷地使用高质量的预训练模型结合Fine-tune API快速完成模型迁移到部署的全流程工作。PaddleHub提供的预训练模型涵盖了图像分类、目标检测、词法分析、语义模型、情感分析、视频分类、图像生成、图像分割、文本审核、关键点检测等主流模型。更多详情可查看官网:https://www.paddlepaddle.org.cn/hub
PaddleHub以预训练模型应用为核心具备以下特点:
* **[模型即软件](#模型即软件)**,通过Python API或命令行实现模型调用,可快速体验或集成飞桨特色预训练模型。
* **[易用的迁移学习](#易用的迁移学习)**,通过Fine-tune API,内置多种优化策略,只需少量代码即可完成预训练模型的Fine-tuning。
* **[一键模型转服务](#一键模型转服务)**,简单一行命令即可搭建属于自己的深度学习模型API服务完成部署。
* **[自动超参优化](#自动超参优化)**,内置AutoDL Finetuner能力,一键启动自动化超参搜索。
<p align="center">
<img src="./docs/imgs/paddlehub_finetune.gif" align="middle"
</p>
<p align='center'>
十行代码完成ERNIE工业级文本分类
</p>
## 目录
* [安装](#%E5%AE%89%E8%A3%85)
* [特性](#特性)
* [FAQ](#faq)
* [用户交流群](#%E7%94%A8%E6%88%B7%E4%BA%A4%E6%B5%81%E7%BE%A4)
* [更新历史](#%E6%9B%B4%E6%96%B0%E5%8E%86%E5%8F%B2)
## 安装
### 环境依赖
* Python >= 3.6
* PaddlePaddle >= 1.7.0
* 操作系统: Windows/Mac/Linux
### 安装命令
在安装PaddleHub之前,请先安装PaddlePaddle深度学习框架,更多安装说明请查阅[飞桨快速安装](https://www.paddlepaddle.org.cn/install/quick)
```shell
pip install paddlehub
```
除上述依赖外,预训练模型和数据集的下载需要网络连接,请确保机器可以**正常访问网络**。若本地已存在相关预训练模型目录,则可以离线使用PaddleHub。
## 特性
### 模型即软件
- **模型即软件**:通过Python API或命令行实现模型调用,可快速体验或集成飞桨特色预训练模型。[-> 效果展示](#模型即软件)
- **易用的迁移学习**:通过Fine-tune API,只需少量代码即可完成预训练模型的Fine-tuning。[-> 效果展示](#易用的迁移学习)
- **一键模型转服务**:简单一行命令即可搭建属于自己的深度学习模型API服务完成部署。[-> 效果展示](#一键模型转服务)
## 文档教程 [[readthedocs]](https://paddlehub.readthedocs.io/zh_CN/develop/index.html)
- [概述](./docs/overview.md)
- [PIP安装](./docs/installation.md)
- [快速体验](./docs/quickstart.md)
- [丰富的预训练模型](./docs/pretrained_models.md)
- [飞桨优势特色模型](./docs/pretrained_models.md)
- [计算机视觉](./docs/pretrained_models.md)
- [图像分类](./docs/pretrained_models.md)
- [目标检测](./docs/pretrained_models.md)
- [图像分割](./docs/pretrained_models.md)
- [关键点检测](./docs/pretrained_models.md)
- [图像生成](./docs/pretrained_models.md)
- [自然语言处理](./docs/pretrained_models.md)
- [中文词法分析与词向量](./docs/pretrained_models.md)
- [情感分析](./docs/pretrained_models.md)
- [文本相似度计算](./docs/pretrained_models.md)
- [文本生成](./docs/pretrained_models.md)
- [语义表示](./docs/pretrained_models.md)
- [视频](./docs/pretrained_models.md)
- 使用教程
- [命令行工具](./docs/tutorial/cmdintro.md)
- [自定义数据](./docs/tutorial/how_to_load_data.md)
- [服务化部署](./docs/tutorial/serving.md)
- 进阶指南
- [文本Embedding服务](./docs/tutorial/bert_service.md)
- [语义相似度计算](./docs/tutorial/sentence_sim.md)
- API
- [hub.datasets](./docs/reference/datasets.md)
- [hub.finetune](./docs/reference/finetune.md)
- [hub.Module](./docs/reference/module.md)
- [hub.vision.transforms](./docs/reference/vision.md)
- [FAQ](./docs/faq.md)
- 社区交流
- [加入技术交流群](#欢迎加入PaddleHub技术交流群)
- [贡献预训练模型](./docs/contribution/contri_pretrained_model.md)
- [贡献代码](./docs/contribution/contri_pr.md)
- [更新历史](./docs/release.md)
- [许可证书](#许可证书)
- [致谢](#致谢)
## 效果展示
<a name="模型即软件"></a>
### 1、模型即软件
PaddleHub采用模型即软件的设计理念,所有的预训练模型与Python软件包类似,具备版本的概念,通过`hub install/uninstall` 可以便捷完成模型的升级和卸载。还可以通过Python的API或命令行实现快速预测的软件集成,更方便地应用和集成深度学习模型。
......@@ -96,60 +97,28 @@ $ hub run lac --input_text "现在,慕尼黑再保险公司不仅是此类行
}]
```
* 使用[情感分析](https://www.paddlepaddle.org.cn/hublist?filter=en_category&value=SentimentAnalysis)模型Senta对句子进行情感预测
```shell
$ hub run senta_bilstm --input_text "今天天气真好"
{'text': '今天天气真好', 'sentiment_label': 1, 'sentiment_key': 'positive', 'positive_probs': 0.9798, 'negative_probs': 0.0202}]
```
PaddleHub还提供图像分类、语义模型、视频分类、图像生成、图像分割、文本审核、关键点检测等主流模型,更多模型介绍,请前往[预训练模型介绍](./docs/pretrained_models.md)或者PaddleHub官网[https://www.paddlepaddle.org.cn/hub](https://www.paddlepaddle.org.cn/hub) 查看
* 使用[目标检测](https://www.paddlepaddle.org.cn/hublist?filter=en_category&value=ObjectDetection)模型Ultra-Light-Fast-Generic-Face-Detector-1MB对图片进行人脸识别
```shell
$ wget https://paddlehub.bj.bcebos.com/resources/test_image.jpg
$ hub run ultra_light_fast_generic_face_detector_1mb_640 --input_path test_image.jpg
```
<p align="center">
<img src="./docs/imgs/face_detection_result.jpeg" align="middle"
</p>
<a name="易用的迁移学习"></a>
* 使用[图像分割](https://www.paddlepaddle.org.cn/hublist?filter=en_category&value=ImageSegmentation)模型进行人像扣图和人体部件识别
### 2、易用的迁移学习
```shell
$ wget https://paddlehub.bj.bcebos.com/resources/test_image.jpg
$ hub run ace2p --input_path test_image.jpg
$ hub run deeplabv3p_xception65_humanseg --input_path test_image.jpg
```
通过Fine-tune API,只需要少量代码即可完成深度学习模型在计算机视觉场景下的迁移学习。
<p align="center">
<img src="./docs/imgs/img_seg_result.jpeg" width="35%" />
<img src="./docs/imgs/humanseg_test_res.png" width="35%" />
</p>
* [Demo示例](./demo)提供丰富的Fine-tune API的使用代码,包括[图像分类](./demo/image_classification)[图像着色](./demo/colorization)[风格迁移](./demo/style_transfer)、等场景的模型迁移示例。
<p align='center'>
&#8194;&#8194;&#8194&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;ACE2P人体部件分割&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;&#8194;
HumanSeg人像分割&#8194;&#8194;&#8194;
<p align="center">
<img src="./docs/imgs/paddlehub_finetune.gif" align="middle"
</p>
PaddleHub还提供图像分类、语义模型、视频分类、图像生成、图像分割、文本审核、关键点检测等主流模型,更多模型介绍,请前往[预训练模型介绍](./docs/pretrained_models.md)或者PaddleHub官网[https://www.paddlepaddle.org.cn/hub](https://www.paddlepaddle.org.cn/hub) 查看
### 易用的迁移学习
通过Fine-tune API,只需要少量代码即可完成深度学习模型在自然语言处理和计算机视觉场景下的迁移学习。
* [Demo示例](./demo)提供丰富的Fine-tune API的使用代码,包括[文本分类](./demo/text_classification)[序列标注](./demo/sequence_labeling)[多标签分类](./demo/multi_label_classification)[图像分类](./demo/image_classification)[检索式问答任务](./demo/qa_classification)[回归任务](./demo/regression)[句子语义相似度计算](./demo/sentence_similarity)[阅读理解任务](./demo/reading_comprehension)等场景的模型迁移示例。
<p align='center'>
十行代码完成图像风格迁移
</p>
* 如需在线快速体验,请点击[PaddleHub教程合集](https://aistudio.baidu.com/aistudio/projectdetail/231146),可使用AI Studio平台提供的GPU算力进行快速尝试。
更多Fine-tune API的使用教程可参考:
* [Fine-tune API](./docs/reference)
* [如何对自定义数据集进行Fine-tuning](./docs/tutorial/how_to_load_data.md)
* [如何自定义迁移任务](./docs/tutorial/how_to_define_task.md)
* [ULMFiT优化策略](./docs/tutorial/strategy_exp.md)
### 一键模型转服务
<a name="一键模型转服务"></a>
### 3、一键模型转服务
PaddleHub提供便捷的模型转服务的能力,只需简单一行命令即可完成模型的HTTP服务部署。通过以下命令即可快速启动LAC词法分析服务:
......@@ -157,19 +126,13 @@ PaddleHub提供便捷的模型转服务的能力,只需简单一行命令即
$ hub serving start --modules lac
```
更多关于模型服务化使用说明参见[PaddleHub模型一键能服务化部署](./docs/tutorial/serving.md)
**PaddleHub 1.5.0版本增加文本Embedding服务[Bert Service](./docs/tutorial/bert_service.md), 高性能地获取文本Embedding**
### 自动超参优化
PaddleHub内置AutoDL Finetuner能力,提供多种优化策略策略实现自动化超参搜索,使得模型在验证集上得到更好的结果,用户只需要一行命令`hub autofinetune`即可启动。更多详细使用说明请参见[PaddleHub超参优化](./docs/tutorial/autofinetune.md)
更多关于模型服务化使用说明参见[PaddleHub模型一键服务化部署](./docs/tutorial/serving.md)
## FAQ
**Q:** 利用PaddleHub Fine-tune如何适配自定义数据集?
**A:** 参考[PaddleHub适配自定义数据集完成Fine-tune](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub%E9%80%82%E9%85%8D%E8%87%AA%E5%AE%9A%E4%B9%89%E6%95%B0%E6%8D%AE%E5%AE%8C%E6%88%90FineTune)
**A:** 参考[PaddleHub使用自定义数据集完成Fine-tune](./docs/tutorial/how_to_load_data.md)
**Q:** 使用PaddleHub时,无法下载预置数据集、Module的等现象。
......@@ -183,25 +146,30 @@ paddlehub.server_check()
# 如果无法连接远端PaddleHub-Server,则显示Request Hub-Server unsuccessfully。
```
**Q:** 利用PaddleHub ERNIE/BERT进行Fine-tune时,运行出错并提示`paddle.fluid.core_avx.EnforceNotMet: Input ShapeTensor cannot be found in Op reshape2`等信息。
**A:** 预训练模型版本与PaddlePaddle版本不匹配。可尝试将PaddlePaddle和PaddleHub升级至最新版本,并将原ERNIE模型卸载。
```shell
$ pip install --upgrade paddlehub
$ hub uninstall ernie
```
**FAQ**
**[More](./docs/faq.md)**
当安装或者使用遇到问题时,可以通过[FAQ](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub-FAQ)查找解决方案。
如果在FAQ中没有找到解决方案,欢迎您将问题以[Github Issues](https://github.com/PaddlePaddle/PaddleHub/issues)的形式提交给我们,我们会第一时间进行跟进。
当您安装或者使用遇到问题时,如果在FAQ中没有找到解决方案,欢迎您将问题以[Github Issues](https://github.com/PaddlePaddle/PaddleHub/issues)的形式提交给我们,我们会第一时间进行跟进。
## 用户交流群
<a name="欢迎加入PaddleHub技术交流群"></a>
## 微信扫描二维码,欢迎加入PaddleHub技术交流群
* 飞桨PaddlePaddle 交流群:796771754(QQ群)
* 飞桨ERNIE交流群:760439550(QQ群)
<div align="center">
<img src="./docs/imgs/joinus.JPEG" width = "200" height = "200" />
</div>
如扫码失败,请添加微信15711058002,并备注“Hub”,运营同学会邀请您入群。
<a name="许可证书"></a>
## 许可证书
本项目的发布受<a href="./LICENSE">Apache 2.0 license</a>许可认证。
## 更新历史
<a name="致谢"></a>
## 致谢
我们非常欢迎您为PaddleHub贡献代码,也十分感谢您的反馈。
更多升级详情参考[更新历史](./RELEASE.md)
* 非常感谢[Austendeng](https://github.com/Austendeng)贡献了修复SequenceLabelReader的pr
* 非常感谢[cclauss](https://github.com/cclauss)贡献了优化travis-ci检查的pr
* 非常感谢[奇想天外](http://www.cheerthink.com/)贡献了口罩检测的demo
* 非常感谢[mhlwsk](https://github.com/mhlwsk)贡献了修复序列标注预测demo的pr
* 非常感谢[zbp-xxxp](https://github.com/zbp-xxxp)贡献了看图作诗的module
* 非常感谢[zbp-xxxp](https://github.com/zbp-xxxp)[七年期限](https://github.com/1084667371)联合贡献了看图写诗中秋特别版module
* 非常感谢[livingbody](https://github.com/livingbody)贡献了基于PaddleHub能力的风格迁移和中秋看图写诗微信小程序
......@@ -9,7 +9,7 @@ if __name__ == "__main__":
model = hub.Module(name='msgnet')
transform = T.Compose([T.Resize((256, 256), interpolation='LINEAR')])
styledata = MiniCOCO(transform)
scheduler = paddle.optimizer.lr.PolynomialDecay(learning_rate=0.001, power=0.9, decay_steps=100)
scheduler = paddle.optimizer.lr.PolynomialDecay(learning_rate=0.001, power=0.9, decay_steps=100)
optimizer = paddle.optimizer.Adam(learning_rate=scheduler, parameters=model.parameters())
trainer = Trainer(model, optimizer, checkpoint_dir='test_style_ckpt')
trainer.train(styledata, epochs=101, batch_size=4, eval_dataset=styledata, log_interval=10, save_interval=10)
# 如何编写一个PaddleHub Module
# 如何编写一个PaddleHub Module并发布上线
## 模型基本信息
## 一、准备工作
### 模型基本信息
我们准备编写一个PaddleHub Module,Module的基本信息如下:
```yaml
......@@ -27,21 +29,20 @@ hub run senta_test --input_text 这部电影太差劲了
<br/>
## 策略
### 策略
为了示例代码简单起见,我们使用一个非常简单的情感判断策略,当输入文本中带有词表中指定单词时,则判断文本倾向为负向,否则为正向
<br/>
## Module创建
## 二、创建Module
### step 1. 创建必要的目录与文件
创建一个senta_test的目录,并在senta_test目录下分别创建__init__.py、module.py、processor.py、vocab.list,其中
创建一个senta_test的目录,并在senta_test目录下分别创建module.py、processor.py、vocab.list,其中
|文件名|用途|
|-|-|
|\_\_init\_\_.py|空文件|
|module.py|主模块,提供Module的实现代码|
|processor.py|辅助模块,提供词表加载的方法|
|vocab.list|存放词表|
......@@ -50,7 +51,6 @@ hub run senta_test --input_text 这部电影太差劲了
➜ tree senta_test
senta_test/
├── vocab.list
├── __init__.py
├── module.py
└── processor.py
```
......@@ -90,12 +90,12 @@ module.py中需要有一个继承了hub.Module的类存在,该类负责实现
author_email="",
type="nlp/sentiment_analysis",
)
class SentaTest(hub.Module):
class SentaTest:
...
```
#### step 3_3. 执行必要的初始化
```python
def _initialize(self):
def __init__(self):
# add arg parser
self.parser = argparse.ArgumentParser(
description="Run the senta_test module.",
......@@ -109,7 +109,7 @@ def _initialize(self):
vocab_path = os.path.join(self.directory, "vocab.list")
self.vocab = load_vocab(vocab_path)
```
`注意`:执行类的初始化不能使用默认的__init__接口,而是应该重载实现_initialize接口。对象默认内置了directory属性,可以直接获取到Module所在路径
`注意`:执行类对象默认内置了directory属性,可以直接获取到Module所在路径
#### step 3_4. 完善预测逻辑
```python
def sentiment_classify(self, texts):
......@@ -158,13 +158,13 @@ def sentiment_classify(self, texts):
### 完整代码
* [module.py](../../demo/senta_module_sample/senta_test/module.py)
* [module.py](../../../modules/demo/senta_test/module.py)
* [processor.py](../../demo/senta_module_sample/senta_test/processor.py)
* [processor.py](../../../modules/demo/senta_test/processor.py)
<br/>
## 测试步骤
## 三、安装并测试Module
完成Module编写后,我们可以通过以下方式测试该Module
......@@ -172,7 +172,7 @@ def sentiment_classify(self, texts):
将Module安装到本机中,再通过Hub.Module(name=...)加载
```shell
hub install senta_test
hub install senta_test
```
```python
......@@ -195,7 +195,7 @@ senta_test.sentiment_classify(texts=["这部电影太差劲了"])
### 调用方法3
将senta_test作为路径加到环境变量中,直接加载SentaTest对象
```shell
export PYTHONPATH=senta_test:$PYTHONPATH
export PYTHONPATH=senta_test:$PYTHONPATH
```
```python
......@@ -208,6 +208,55 @@ SentaTest.sentiment_classify(texts=["这部电影太差劲了"])
将Module安装到本机中,再通过hub run运行
```shell
hub install senta_test
hub run senta_test --input_text "这部电影太差劲了"
➜ hub install senta_test
➜ hub run senta_test --input_text "这部电影太差劲了"
```
## 四、发布Module
在完成Module的开发和测试后,如果想要将模型分享给其他人使用,可以通过以下方式发布模型:
### 方式一、上传Module到PaddleHub官网
https://www.paddlepaddle.org.cn/hub
我们会在尽可能短的时间内完成Module的审核并给出反馈,通过审核并上线后,Module将展示在PaddleHub官网的`开发者贡献模型`中,用户可以像加载其他官方Module一样加载该Module。
### 方式二、上传Module到远程代码托管平台
PaddleHub也支持直接加载远程代码托管平台上的Module,具体步骤如下:
#### step 1. 创建新的仓库
在代码托管平台上创建一个新的Git仓库,添加前面所写Module的代码,为了方便区分管理不同的Module,我们创建一个modules目录,并将senta_test放在modules目录下
#### step 2. 新增配置文件`hubconf.py`
在根目录下,新增配置文件`hubconf.py`,文件中引用一个通过`moduleinfo`修饰的类,如下
```python
from modules.senta_test.module import SentaTest
```
*此时文件结构如下:*
```
hubconf.py
modules
├── senta_test/
├── vocab.list
├── module.py
└── processor.py
```
#### step 3. 完成提交并推送到远程仓库
#### step 4. 在本地加载远程仓库中的Module
为了方便体验,我们在GitHub和Gitee上都存放了SentaTest的代码,可以直接通过以下方式体验效果
```python
import paddlehub as hub
senta_test = hub.Module(name='senta_test', source='https://github.com/nepeplwu/myhub.git')
# senta_test = hub.Module(name='senta_test', source='https://gitee.com/nepeplwu/myhub.git')
print(senta_test.sentiment_classify(texts=["这部电影太差劲了"]))
```
......@@ -25,16 +25,6 @@ $ pip install paddlepaddle
$ pip install paddlepaddle-gpu
```
## 利用PaddleHub ernie/bert进行Finetune时,提示
`paddle.fluid.core_avx.EnforceNotMet: Input ShapeTensor cannot be found in Op reshape2`等信息
这是因为ernie/bert module的创建时和此时运行环境中PaddlePaddle版本不对应。
首先将PaddleHub升级至最新版本,同时将ernie卸载。
```shell
$ pip install --upgrade paddlehub
$ hub uninstall ernie
```
## 使用paddlehub时,无法下载预置数据集、module的等现象
下载数据集、module等,PaddleHub要求机器可以访问外网。可以使用server_check()可以检查本地与远端PaddleHub-Server的连接状态,使用方法如下:
......
docs/imgs/paddlehub_finetune.gif

540.3 KB | W: | H:

docs/imgs/paddlehub_finetune.gif

467.4 KB | W: | H:

docs/imgs/paddlehub_finetune.gif
docs/imgs/paddlehub_finetune.gif
docs/imgs/paddlehub_finetune.gif
docs/imgs/paddlehub_finetune.gif
  • 2-up
  • Swipe
  • Onion skin
......@@ -8,10 +8,12 @@ PaddleHub 文档
:titlesonly:
概述<overview>
安装<installation>
快速体验<quickstart>
教程<tutorial/tutorial_index>
安装<install>
快速体验<quick_experience/quick_index>
迁移学习<tutorial/tutorial_index>
部署预训练模型<tutorial/Serving_index>
API<reference/ref_index>
命令行参考<tutorial/cmdintro>
FAQ<faq>
社区贡献<contribution/contri_index.rst>
社区贡献<contribution/contri_index>
更新历史<release>
\ No newline at end of file
......@@ -3,7 +3,7 @@
## 环境依赖
* Python>=3.6
* PaddlePaddle>=1.7.0
* PaddlePaddle>=2.0.0rc
* 操作系统:Windows/Mac/Linux
## 安装命令
......
......@@ -8,12 +8,10 @@ PaddleHub以预训练模型应用为核心具备以下特点:
* **模型即软件:** 通过Python API或命令行实现模型调用,可快速体验或集成飞桨特色预训练模型。
* **易用的迁移学习:** 通过Fine-tune API,内置多种优化策略,只需少量代码即可完成预训练模型的Fine-tuning。
* **易用的迁移学习:** 通过Fine-tune API,只需少量代码即可完成预训练模型的Fine-tuning。
* **一键模型转服务:** 简单一行命令即可搭建属于自己的深度学习模型API服务完成部署。
* **自动超参优化:** 内置AutoDL Finetuner能力,一键启动自动化超参搜索。
![](./imgs/paddlehub_figure.jpg)
<p align='center'>
......@@ -31,18 +29,16 @@ PaddleHub采用模型即软件的设计理念,所有的预训练模型与Pytho
### 二、易用的迁移学习
迁移学习(Transfer Learning)通俗来讲,就是运用已有的知识来学习新的知识,核心是找到已有知识和新知识之间的相似性。PaddleHub提供了Fine-tune API,只需要少量代码即可完成深度学习模型在自然语言处理和计算机视觉场景下的迁移学习,可以在更短的时间完成模型的训练,同时模型具备更好的泛化能力。下图所示是基于PaddleHub,通过数十行代码完成ERNIE工业级文本分类示例:
迁移学习(Transfer Learning)通俗来讲,就是运用已有的知识来学习新的知识,核心是找到已有知识和新知识之间的相似性。PaddleHub提供了Fine-tune API,只需要少量代码即可完成深度学习模型在计算机视觉场景下的迁移学习,可以在更短的时间完成模型的训练,同时模型具备更好的泛化能力。下图所示是基于PaddleHub,通过数十行代码完成ERNIE工业级文本分类示例:
![](./imgs/paddlehub_finetune.gif)
<p align='center'>
十行代码完成ERNIE工业级文本分类
十行代码完成图像风格迁移
</p>
PaddleHub提供了使用Finetune-API和预训练模型完成[文本分类](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo/text_classification)[序列标注](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo/sequence_labeling)[多标签分类](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo/multi_label_classification)[图像分类](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo/image_classification)[检索式问答任务](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo/qa_classification)[回归任务](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo/regression)[句子语义相似度计算](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo/sentence_similarity)[阅读理解任务](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo/reading_comprehension)等迁移任务的使用示例,详细参见[demo](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo)。下图是PaddleHub的迁移学习全景图:
![](./imgs/paddlehub_finetune.jpg)
PaddleHub提供了使用Finetune-API和预训练模型完成[图像分类](../demo/image_classification)[图像着色](../demo/colorization)[风格迁移](../demo/style_transfer)等迁移任务的使用示例,详细参见[demo](../demo)
* 场景化使用
......@@ -72,13 +68,10 @@ PaddleHub提供了使用Finetune-API和预训练模型完成[文本分类](https
关于PaddleHub快捷完成迁移学习,更多信息参考:
[API](./reference/ref_index.md)
[API](./reference/ref_index.rst)
[自定义数据集如何Fine-tune](tutorial/how_to_load_data.md)
[实现自定义迁移任务](tutorial/how_to_define_task.md)
[ULMFiT优化策略](tutorial/strategy_exp.md)
### 三、一键模型转服务
......@@ -86,9 +79,3 @@ PaddleHub Serving是基于PaddleHub的一键模型服务部署工具,能够通
其主要包括利用Bert Service实现embedding服务化,以及利用预测模型实现预训练模型预测服务化两大功能。未来还将支持开发者使用PaddleHub Fine-tune API的模型服务化。
关于服务化部署详细信息参见[PaddleHub Serving一键服务部署](tutorial/serving.md)
### 四、自动超参优化
深度学习模型往往包含许多的超参数,而这些超参数的取值对模型性能起着至关重要的作用。因为模型参数空间大,目前超参调整都是通过手动,依赖人工经验或者不断尝试,且不同模型、样本数据和场景下不尽相同,所以需要大量尝试,时间成本和资源成本非常浪费。PaddleHub AutoDL Finetuner可以实现自动调整超参数,使得模型性能达到最优水平。它通过多种调优的算法来搜索最优超参。
AutoDL Finetuner详细信息参见[PaddleHub超参优化](tutorial/autofinetune.md)
# 通过命令行调用方式使用PaddleHub
本页面的代码/命令可在[AIStudio](https://aistudio.baidu.com/aistudio/projectdetail/643120)上在线运行,类似notebook的环境,只需通过浏览器即可访问,无需准备环境,非常方便开发者快速体验。
PaddleHub在设计时,为模型的管理和使用提供了命令行工具,也提供了通过命令行调用PaddleHub模型完成预测的方式。比如,前面章节中人像分割和文本分词的任务也可以通过命令行调用的方式实现。
### 体验前请提前安装好PaddleHub
```shell
# 安装最新版本,使用清华源更稳定、更迅速
$ pip install paddlehub --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple
```
### 人像扣图
```shell
# 下载待测试图片
$ wget https://paddlehub.bj.bcebos.com/resources/test_image.jpg
# 通过命令行方式实现人像扣图任务
$ hub run deeplabv3p_xception65_humanseg --input_path test_image.jpg --visualization=True --output_dir="humanseg_output"
```
--2020-07-22 12:19:52-- https://paddlehub.bj.bcebos.com/resources/test_image.jpg
Resolving paddlehub.bj.bcebos.com (paddlehub.bj.bcebos.com)... 182.61.200.195, 182.61.200.229
Connecting to paddlehub.bj.bcebos.com (paddlehub.bj.bcebos.com)|182.61.200.195|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 967120 (944K) [image/jpeg]
Saving to: ‘test_image.jpg’
test_image.jpg 100%[===================>] 944.45K 6.13MB/s in 0.2s
2020-07-22 12:19:53 (6.13 MB/s) - ‘test_image.jpg’ saved [967120/967120]
[{'save_path': 'humanseg_output/test_image.png', 'data': array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]], dtype=float32)}]
![png](../imgs/humanseg_test_res.png)
### 中文分词
```shell
#通过命令行方式实现文本分词任务
$ hub run lac --input_text "今天是个好日子"
```
Install Module lac
Downloading lac
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmpjcskpj8x/lac
[==================================================] 100.00%
Successfully installed lac-2.1.1
[{'word': ['今天', '是', '个', '好日子'], 'tag': ['TIME', 'v', 'q', 'n']}]
上面的命令中包含四个部分,分别是:
- hub 表示PaddleHub的命令。
- run 调用run执行模型的预测。
- deeplabv3p_xception65_humanseg、lac 表示要调用的算法模型。
- --input_path/--input_text 表示模型的输入数据,图像和文本的输入方式不同。
另外,命令行中`visualization=True`表示将结果可视化输出,`output_dir="humanseg_output"`表示预测结果的保存目录,可以到该路径下查看输出的图片。
再看一个文字识别和一个口罩检测的例子。
### OCR文字识别
```shell
# 下载待测试的图片
$ wget https://paddlehub.bj.bcebos.com/model/image/ocr/test_ocr.jpg
# 该Module依赖于第三方库shapely和pyclipper,需提前安装
$ pip install shapely
$ pip install pyclipper
# 通过命令行方式实现文字识别任务
$ hub run chinese_ocr_db_crnn_mobile --input_path test_ocr.jpg --visualization=True --output_dir='ocr_result'
```
--2020-07-22 15:00:50-- https://paddlehub.bj.bcebos.com/model/image/ocr/test_ocr.jpg
Resolving paddlehub.bj.bcebos.com (paddlehub.bj.bcebos.com)... 182.61.200.195, 182.61.200.229
Connecting to paddlehub.bj.bcebos.com (paddlehub.bj.bcebos.com)|182.61.200.195|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 48680 (48K) [image/jpeg]
Saving to: ‘test_ocr.jpg’
test_ocr.jpg 100%[===================>] 47.54K --.-KB/s in 0.02s
2020-07-22 15:00:51 (2.88 MB/s) - ‘test_ocr.jpg’ saved [48680/48680]
Looking in indexes: https://pypi.mirrors.ustc.edu.cn/simple/
Requirement already satisfied: shapely in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (1.7.0)
Looking in indexes: https://pypi.mirrors.ustc.edu.cn/simple/
Requirement already satisfied: pyclipper in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (1.2.0)
[{'save_path': 'ocr_result/ndarray_1595401261.294494.jpg', 'data': [{'text': '纯臻营养护发素', 'confidence': 0.9438689351081848, 'text_box_position': [[24, 36], [304, 34], [304, 72], [24, 74]]}, {'text': '产品信息/参数', 'confidence': 0.9843138456344604, 'text_box_position': [[24, 80], [172, 80], [172, 104], [24, 104]]}, {'text': '(45元/每公斤,100公斤起订)', 'confidence': 0.9210420250892639, 'text_box_position': [[24, 109], [333, 109], [333, 136], [24, 136]]}, {'text': '每瓶22元,1000瓶起订)', 'confidence': 0.9685984253883362, 'text_box_position': [[22, 139], [283, 139], [283, 166], [22, 166]]}, {'text': '【品牌】', 'confidence': 0.9527574181556702, 'text_box_position': [[22, 174], [85, 174], [85, 198], [22, 198]]}, {'text': ':代加工方式/OEMODM', 'confidence': 0.9442129135131836, 'text_box_position': [[90, 176], [301, 176], [301, 196], [90, 196]]}, {'text': '【品名】', 'confidence': 0.8793742060661316, 'text_box_position': [[23, 205], [85, 205], [85, 229], [23, 229]]}, {'text': ':纯臻营养护发素', 'confidence': 0.9230973124504089, 'text_box_position': [[95, 204], [235, 206], [235, 229], [95, 227]]}, {'text': '【产品编号】', 'confidence': 0.9311650395393372, 'text_box_position': [[24, 238], [120, 238], [120, 260], [24, 260]]}, {'text': 'J:YM-X-3011', 'confidence': 0.8866629004478455, 'text_box_position': [[110, 239], [239, 239], [239, 256], [110, 256]]}, {'text': 'ODMOEM', 'confidence': 0.9916308522224426, 'text_box_position': [[414, 233], [430, 233], [430, 304], [414, 304]]}, {'text': '【净含量】:220ml', 'confidence': 0.8709315657615662, 'text_box_position': [[23, 268], [181, 268], [181, 292], [23, 292]]}, {'text': '【适用人群】', 'confidence': 0.9589888453483582, 'text_box_position': [[24, 301], [118, 301], [118, 321], [24, 321]]}, {'text': ':适合所有肤质', 'confidence': 0.935418963432312, 'text_box_position': [[131, 300], [254, 300], [254, 323], [131, 323]]}, {'text': '【主要成分】', 'confidence': 0.9366627335548401, 'text_box_position': [[24, 332], [117, 332], [117, 353], [24, 353]]}, {'text': '鲸蜡硬脂醇', 'confidence': 0.9033458828926086, 'text_box_position': [[138, 331], [235, 331], [235, 351], [138, 351]]}, {'text': '燕麦B-葡聚', 'confidence': 0.8497812747955322, 'text_box_position': [[248, 332], [345, 332], [345, 352], [248, 352]]}, {'text': '椰油酰胺丙基甜菜碱、', 'confidence': 0.8935506939888, 'text_box_position': [[54, 363], [232, 363], [232, 383], [54, 383]]}, {'text': '糖、', 'confidence': 0.8750994205474854, 'text_box_position': [[25, 364], [62, 364], [62, 383], [25, 383]]}, {'text': '泛酯', 'confidence': 0.5581164956092834, 'text_box_position': [[244, 363], [281, 363], [281, 382], [244, 382]]}, {'text': '(成品包材)', 'confidence': 0.9566792845726013, 'text_box_position': [[368, 367], [475, 367], [475, 388], [368, 388]]}, {'text': '【主要功能】', 'confidence': 0.9493741393089294, 'text_box_position': [[24, 395], [119, 395], [119, 416], [24, 416]]}, {'text': ':可紧致头发磷层', 'confidence': 0.9692543745040894, 'text_box_position': [[128, 397], [273, 397], [273, 414], [128, 414]]}, {'text': '美,从而达到', 'confidence': 0.8662520051002502, 'text_box_position': [[265, 395], [361, 395], [361, 415], [265, 415]]}, {'text': '即时持久改善头发光泽的效果,给干燥的头', 'confidence': 0.9690631031990051, 'text_box_position': [[25, 425], [372, 425], [372, 448], [25, 448]]}, {'text': '发足够的滋养', 'confidence': 0.8946213126182556, 'text_box_position': [[26, 457], [136, 457], [136, 477], [26, 477]]}]}]
```shell
# 查看预测结果
```
![png](../imgs/ocr_res.jpg)
### 口罩检测
```shell
# 下载待测试的图片
$ wget https://paddlehub.bj.bcebos.com/resources/test_mask_detection.jpg
# 通过命令行方式实现文字识别任务
$ hub run pyramidbox_lite_mobile_mask --input_path test_mask_detection.jpg --visualization=True --output_dir='detection_result'
```
--2020-07-22 15:08:11-- https://paddlehub.bj.bcebos.com/resources/test_mask_detection.jpg
Resolving paddlehub.bj.bcebos.com (paddlehub.bj.bcebos.com)... 182.61.200.229, 182.61.200.195
Connecting to paddlehub.bj.bcebos.com (paddlehub.bj.bcebos.com)|182.61.200.229|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 299133 (292K) [image/jpeg]
Saving to: ‘test_mask_detection.jpg’
test_mask_detection 100%[===================>] 292.12K --.-KB/s in 0.06s
2020-07-22 15:08:11 (4.55 MB/s) - ‘test_mask_detection.jpg’ saved [299133/299133]
Install Module pyramidbox_lite_mobile_mask
Downloading pyramidbox_lite_mobile_mask
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmp8oes9jid/pyramidbox_lite_mobile_mask
[==================================================] 100.00%
Successfully installed pyramidbox_lite_mobile_mask-1.3.0
Downloading pyramidbox_lite_mobile
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmpvhjhlr10/pyramidbox_lite_mobile
[==================================================] 100.00%
[{'data': [{'label': 'MASK', 'confidence': 0.9992434978485107, 'top': 181, 'bottom': 440, 'left': 457, 'right': 654}, {'label': 'MASK', 'confidence': 0.9224318265914917, 'top': 340, 'bottom': 578, 'left': 945, 'right': 1125}, {'label': 'NO MASK', 'confidence': 0.9996706247329712, 'top': 292, 'bottom': 500, 'left': 1166, 'right': 1323}], 'path': 'test_mask_detection.jpg'}]
```shell
# 查看预测结果
```
![png](../imgs/test_mask_detection_result.jpg)
### PaddleHub命令行工具简介
PaddleHub的命令行工具在开发时借鉴了Anaconda和PIP等软件包管理的理念,可以方便快捷的完成模型的搜索、下载、安装、升级、预测等功能。 下面概要介绍一下PaddleHub支持的12个命令,详细介绍可查看[命令行参考](../tutorial/cmdintro.md)章节。:
* install:用于将Module安装到本地,默认安装在{HUB_HOME}/.paddlehub/modules目录下;
* uninstall:卸载本地Module;
* show:用于查看本地已安装Module的属性或者指定目录下确定的Module的属性,包括其名字、版本、描述、作者等信息;
* download:用于下载百度飞桨PaddleHub提供的Module;
* search:通过关键字在服务端检索匹配的Module,当想要查找某个特定模型的Module时,使用search命令可以快速得到结果,例如hub search ssd命令,会查找所有包含了ssd字样的Module,命令支持正则表达式,例如hub search ^s.\*搜索所有以s开头的资源;
* list:列出本地已经安装的Module;
* run:用于执行Module的预测;
* version:显示PaddleHub版本信息;
* help:显示帮助信息;
* clear:PaddleHub在使用过程中会产生一些缓存数据,这部分数据默认存放在${HUB_HOME}/.paddlehub/cache目录下,用户可以通过clear命令来清空缓存;
* autofinetune:用于自动调整Fine-tune任务的超参数,具体使用详情参考[PaddleHub AutoDL Finetuner](https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.5/docs/tutorial/autofinetune.md)使用教程;
* config:用于查看和设置Paddlehub相关设置,包括对server地址、日志级别的设置;
* serving:用于一键部署Module预测服务,详细用法见[PaddleHub Serving一键服务部署](https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.5/docs/tutorial/serving.md)
## 小结
PaddleHub的产品理念是模型即软件,通过Python API或命令行实现模型调用,可快速体验或集成飞桨特色预训练模型。
此外,当用户想用少量数据来优化预训练模型时,PaddleHub也支持迁移学习,通过Fine-tune API,内置多种优化策略,只需少量代码即可完成预训练模型的Fine-tuning。具体可通过后面迁移学习的章节了解。
>值得注意的是,不是所有的Module都支持通过命令行预测 (例如BERT/ERNIE Transformer类模型,一般需要搭配任务进行Fine-tune), 也不是所有的Module都可用于Fine-tune(例如一般不建议用户使用词法分析LAC模型Fine-tune)。建议提前阅读[预训练模型的介绍文档](https://www.paddlepaddle.org.cn/hublist)了解使用场景。
# PaddleHub更多体验Demos
## PaddleHub官方Demo全集
官方Demo在AI Studio中均可在线运行,类似notebook的环境,只需通过浏览器即可访问,无需准备环境,非常方便开发者快速体验。
并将持续更新,建议收藏。
[https://aistudio.baidu.com/aistudio/personalcenter/thirdview/79927](https://aistudio.baidu.com/aistudio/personalcenter/thirdview/79927)
## PaddleHub开发者趣味实践作品
以下为前期PaddleHub课程或活动中,开发者们基于PaddleHub创作的趣味实践作品,均收录在AI Studio中,可在线运行,欢迎访问,希望对您有所启发。
1. [布剪刀石头【人脸识别切换本地窗口】](https://aistudio.baidu.com/aistudio/projectdetail/507630)
1. [秋水中的鱼【yesok舞蹈背景抠图转换并动漫风格迁移】](http://aistudio.baidu.com/aistudio/projectdetail/517066)
1. [Ninetailskim【在人脸上玩复古windows弹球】](https://aistudio.baidu.com/aistudio/projectdetail/518861)
1. [乌拉__【监控口罩,语音提醒,后台记录】](https://aistudio.baidu.com/aistudio/projectdetail/506931)
1. [九品炼丹师【影流之绿蛙蔡徐坤,人脸识别加头饰+ 人像分割变分身】](https://aistudio.baidu.com/aistudio/projectdetail/505168)
1. [七年期限【风格迁移以及本地部署】](https://aistudio.baidu.com/aistudio/projectdetail/520453)
1. [Fanas无敌【口红试色项目】](https://aistudio.baidu.com/aistudio/projectdetail/516520)
1. [skywalk163【用paddlehub统计飞桨源代码词频以及词云与人像展示】](https://aistudio.baidu.com/aistudio/projectdetail/519841)
1. [AIStudio261428【人脸识别+漫画表情包】](https://aistudio.baidu.com/aistudio/projectdetail/519616)
1. [土豆芽【六一儿童节邀请卡通人物来做客】](https://aistudio.baidu.com/aistudio/projectdetail/520925)
1. [大熊猫的感觉【变化的口罩】](https://aistudio.baidu.com/aistudio/projectdetail/520996)
1. [kly1997【一键旅游+戴墨镜】](https://aistudio.baidu.com/aistudio/projectdetail/518117)
1. [寞寞_默默【穿越到油画中】](https://aistudio.baidu.com/aistudio/projectdetail/516332)
1. [isse7【创意项目:风格“鬼脸”变换】](https://aistudio.baidu.com/aistudio/projectdetail/515307)
1. [Pda【人脸趣味变】](https://aistudio.baidu.com/aistudio/projectdetail/516306)
1. [Kgkzhiwen【我的新衣】](https://aistudio.baidu.com/aistudio/projectdetail/516663)
1. [哎呀呀好好学习【脸型自动调整】](https://aistudio.baidu.com/aistudio/projectdetail/513640)
1. [Tfboy【证件照换底】](https://aistudio.baidu.com/aistudio/projectdetail/509443)
1. [Leigangblog【我是明星脸】](https://aistudio.baidu.com/aistudio/projectdetail/505537)
1. [wpb3dm【时装模特换装】](https://aistudio.baidu.com/aistudio/projectdetail/519349)
1. [lsvine_bai【女友秒变神秘金发女神】](https://aistudio.baidu.com/aistudio/projectdetail/521784)
1. [Lemonadeqk【简单追星】](https://aistudio.baidu.com/aistudio/projectdetail/520488)
1. [XM1436gr【利用PaddleHub关键点检测实现AI换卡通脸】](https://aistudio.baidu.com/aistudio/projectdetail/514547)
1. [旺仔【人人都是圆眼萌仔】](https://aistudio.baidu.com/aistudio/projectdetail/519222)
1. [Arrowarcher【AI一键换发】](https://aistudio.baidu.com/aistudio/projectdetail/508270)
1. [WHY197598【移物换景基础】](https://aistudio.baidu.com/aistudio/projectdetail/517961)
1. [署名景逸【基于paddlehub人脸关键点检测的疲劳检测】](https://aistudio.baidu.com/aistudio/projectdetail/506024)
1. [thunder95【PaddleHub目光表情投票】](https://aistudio.baidu.com/aistudio/projectdetail/514205)
1. [上弦月C 【坟头蹦迪毕业照】](https://aistudio.baidu.com/aistudio/projectdetail/511253)
1. [如意_鸡蛋【左看像周润发,右看像刘德华】](https://aistudio.baidu.com/aistudio/projectdetail/507231)
# 通过Python代码调用方式使用PaddleHub
本页面的代码/命令可在[AIStudio](https://aistudio.baidu.com/aistudio/projectdetail/635335)上在线运行,类似notebook的环境,只需通过浏览器即可访问,无需准备环境,非常方便开发者快速体验。
## 计算机视觉任务的PaddleHub示例
先以计算机视觉任务为例,我们选用一张测试图片test.jpg,分别实现如下四项功能:
* 人像扣图([deeplabv3p_xception65_humanseg](https://www.paddlepaddle.org.cn/hubdetail?name=deeplabv3p_xception65_humanseg&en_category=ImageSegmentation)
* 人体部位分割([ace2p](https://www.paddlepaddle.org.cn/hubdetail?name=ace2p&en_category=ImageSegmentation)
* 人脸检测([ultra_light_fast_generic_face_detector_1mb_640](https://www.paddlepaddle.org.cn/hubdetail?name=ultra_light_fast_generic_face_detector_1mb_640&en_category=FaceDetection)
* 关键点检测([human_pose_estimation_resnet50_mpii](https://www.paddlepaddle.org.cn/hubdetail?name=human_pose_estimation_resnet50_mpii&en_category=KeyPointDetection)
>注:如果需要查找PaddleHub中可以调用哪些预训练模型,获取模型名称(如deeplabv3p_xception65_humanseg,后续代码中通过该名称调用模型),请参考[官网文档](https://www.paddlepaddle.org.cn/hublist),文档中已按照模型类别分好类,方便查找,并且提供了详细的模型介绍。
### 体验前请提前安装好PaddleHub
```shell
# 安装最新版本,使用清华源更稳定、更迅速
$ pip install paddlehub --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple
```
### 原图展示
```shell
# 下载待测试图片
$ wget https://paddlehub.bj.bcebos.com/resources/test_image.jpg
```
--2020-07-22 12:22:19-- https://paddlehub.bj.bcebos.com/resources/test_image.jpg
Resolving paddlehub.bj.bcebos.com (paddlehub.bj.bcebos.com)... 182.61.200.195, 182.61.200.229
Connecting to paddlehub.bj.bcebos.com (paddlehub.bj.bcebos.com)|182.61.200.195|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 967120 (944K) [image/jpeg]
Saving to: ‘test_image.jpg.1’
test_image.jpg.1 100%[===================>] 944.45K 5.51MB/s in 0.2s
2020-07-22 12:22:19 (5.51 MB/s) - ‘test_image.jpg.1’ saved [967120/967120]
![png](../imgs/humanseg_test.png)
### 人像扣图
PaddleHub采用模型即软件的设计理念,所有的预训练模型与Python软件包类似,具备版本的概念,通过`hub install``hub uninstall`命令可以便捷地完成模型的安装、升级和卸载。
> 使用如下命令默认下载最新版本的模型,如果需要指定版本,可在后面接版本号,如`==1.1.1`。
```shell
#安装预训练模型,deeplabv3p_xception65_humanseg是模型名称
$ hub install deeplabv3p_xception65_humanseg
```
Downloading deeplabv3p_xception65_humanseg
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmpo32jeve0/deeplabv3p_xception65_humanseg
[==================================================] 100.00%
Successfully installed deeplabv3p_xception65_humanseg-1.1.1
```python
# 导入paddlehub库
import paddlehub as hub
# 指定模型名称、待预测的图片路径、输出结果的路径,执行并输出预测结果
module = hub.Module(name="deeplabv3p_xception65_humanseg")
res = module.segmentation(paths = ["./test_image.jpg"], visualization=True, output_dir='humanseg_output')
```
[32m[2020-07-22 12:22:49,474] [ INFO] - Installing deeplabv3p_xception65_humanseg module [0m
Downloading deeplabv3p_xception65_humanseg
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmpzrrl1duq/deeplabv3p_xception65_humanseg
[==================================================] 100.00%
[32m[2020-07-22 12:23:11,811] [ INFO] - Successfully installed deeplabv3p_xception65_humanseg-1.1.1 [0m
![png](../imgs/output_8_3.png)
可以看到,使用Python代码调用PaddleHub只需要三行代码即可实现:
```
import paddlehub as hub # 导入PaddleHub代码库
module = hub.Module(name="deeplabv3p_xception65_humanseg") # 指定模型名称
res = module.segmentation(paths = ["./test.jpg"], visualization=True, output_dir='humanseg_output') # 指定模型的输入和输出路径,执行并输出预测结果,其中visualization=True表示将结果可视化输出
```
* 模型名称均通过`hub.Module` API来指定;
* `module.segmentation`用于执行图像分割类的预测任务,不同类型任务设计了不同的预测API,比如人脸检测任务采用`face_detection`函数执行预测,建议调用预训练模型之前先仔细查阅对应的模型介绍文档。
* 预测结果保存在`output_dir='humanseg_output'`目录下,可以到该路径下查看输出的图片。
其他任务的实现方式,均可参考这个“套路”。看一下接下来几个任务如何实现。
### 人体部位分割
```shell
#安装预训练模型
$ hub install ace2p
```
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
Downloading ace2p
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmpfsovt3f8/ace2p
[==================================================] 100.00%
Successfully installed ace2p-1.1.0
```python
# 导入paddlehub库
import paddlehub as hub
# 指定模型名称、待预测的图片路径、输出结果的路径,执行并输出预测结果
module = hub.Module(name="ace2p")
res = module.segmentation(paths = ["./test_image.jpg"], visualization=True, output_dir='ace2p_output')
```
[32m[2020-07-22 12:23:58,027] [ INFO] - Installing ace2p module [0m
Downloading ace2p
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmptrogpj6j/ace2p
[==================================================] 100.00%
[32m[2020-07-22 12:24:22,575] [ INFO] - Successfully installed ace2p-1.1.0 [0m
![png](../imgs/output_12_3.png)
### 人脸检测
```shell
#安装预训练模型
$ hub install ultra_light_fast_generic_face_detector_1mb_640
```
Downloading ultra_light_fast_generic_face_detector_1mb_640
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmpz82xnmy6/ultra_light_fast_generic_face_detector_1mb_640
[==================================================] 100.00%
Successfully installed ultra_light_fast_generic_face_detector_1mb_640-1.1.2
```python
# 导入paddlehub库
import paddlehub as hub
# 指定模型名称、待预测的图片路径、输出结果的路径,执行并输出预测结果
module = hub.Module(name="ultra_light_fast_generic_face_detector_1mb_640")
res = module.face_detection(paths = ["./test_image.jpg"], visualization=True, output_dir='face_detection_output')
```
[32m[2020-07-22 12:25:12,948] [ INFO] - Installing ultra_light_fast_generic_face_detector_1mb_640 module [0m
Downloading ultra_light_fast_generic_face_detector_1mb_640
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmpw44mo56p/ultra_light_fast_generic_face_detector_1mb_640
[==================================================] 100.00%
[32m[2020-07-22 12:25:14,698] [ INFO] - Successfully installed ultra_light_fast_generic_face_detector_1mb_640-1.1.2
![png](../imgs/output_15_3.png)
### 关键点检测
```shell
#安装预训练模型
$ hub install human_pose_estimation_resnet50_mpii
```
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/sklearn/externals/joblib/externals/cloudpickle/cloudpickle.py:47: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
Downloading human_pose_estimation_resnet50_mpii
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmpn_ppwkzq/human_pose_estimation_resnet50_mpii
[======== ] 17.99%
```python
# 导入paddlehub库
import paddlehub as hub
# 指定模型名称、待预测的图片路径、输出结果的路径,执行并输出预测结果
module = hub.Module(name="human_pose_estimation_resnet50_mpii")
res = module.keypoint_detection(paths = ["./test_image.jpg"], visualization=True, output_dir='keypoint_output')
```
[32m[2020-07-23 11:27:33,989] [ INFO] - Installing human_pose_estimation_resnet50_mpii module [0m
[32m[2020-07-23 11:27:33,992] [ INFO] - Module human_pose_estimation_resnet50_mpii already installed in /home/aistudio/.paddlehub/modules/human_pose_estimation_resnet50_mpii [0m
image saved in keypoint_output/test_imagetime=1595474855.jpg
![png](../imgs/output_18_2.png)
## 自然语言处理任务的PaddleHub示例
再看两个自然语言处理任务的示例,下面以中文分词和情感分类的任务为例介绍。
* 中文分词([lac](https://www.paddlepaddle.org.cn/hubdetail?name=lac&en_category=LexicalAnalysis)
* 情感分析([senta_bilstm](https://www.paddlepaddle.org.cn/hubdetail?name=senta_bilstm&en_category=SentimentAnalysis)
### 中文分词
```shell
#安装预训练模型
$ hub install lac
```
2020-07-22 10:03:09,866-INFO: font search path ['/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf', '/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/afm', '/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts']
2020-07-22 10:03:10,208-INFO: generated new fontManager
Downloading lac
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmp8ukaz690/lac
[==================================================] 100.00%
Successfully installed lac-2.1.1
```python
# 导入paddlehub库
import paddlehub as hub
# 指定模型名称、待分词的文本,执行并输出预测结果
lac = hub.Module(name="lac")
test_text = ["1996年,曾经是微软员工的加布·纽维尔和麦克·哈灵顿一同创建了Valve软件公司。他们在1996年下半年从id software取得了雷神之锤引擎的使用许可,用来开发半条命系列。"]
res = lac.lexical_analysis(texts = test_text)
# 打印预测结果
print("中文词法分析结果:", res)
```
[32m[2020-07-22 10:03:18,439] [ INFO] - Installing lac module[0m
[32m[2020-07-22 10:03:18,531] [ INFO] - Module lac already installed in /home/aistudio/.paddlehub/modules/lac [0m
中文词法分析结果: [{'word': ['1996年', ',', '曾经', '是', '微软', '员工', '的', '加布·纽维尔', '和', '麦克·哈灵顿', '一同', '创建', '了', 'Valve软件公司', '。', '他们', '在', '1996年下半年', '从', 'id', ' ', 'software', '取得', '了', '雷神之锤', '引擎', '的', '使用', '许可', ',', '用来', '开发', '半条命', '系列', '。'], 'tag': ['TIME', 'w', 'd', 'v', 'ORG', 'n', 'u', 'PER', 'c', 'PER', 'd', 'v', 'u', 'ORG', 'w', 'r', 'p', 'TIME', 'p', 'nz', 'w', 'n', 'v', 'u', 'n', 'n', 'u', 'vn', 'vn', 'w', 'v', 'v', 'n', 'n', 'w']}]
可以看到,与计算机视觉任务相比,输入和输出接口(这里需要输入文本,以函数参数的形式传入)存在差异,这与任务类型相关,具体可查看对应预训练模型的API介绍。
### 情感分类
```shell
#安装预训练模型
$ hub install senta_bilstm
```
Module senta_bilstm-1.1.0 already installed in /home/aistudio/.paddlehub/modules/senta_bilstm
```python
import paddlehub as hub
senta = hub.Module(name="senta_bilstm")
test_text = ["味道不错,确实不算太辣,适合不能吃辣的人。就在长江边上,抬头就能看到长江的风景。鸭肠、黄鳝都比较新鲜。"]
res = senta.sentiment_classify(texts = test_text)
print("情感分析结果:", res)
```
[32m[2020-07-22 10:34:06,922] [ INFO] - Installing senta_bilstm module [0m
[32m[2020-07-22 10:34:06,984] [ INFO] - Module senta_bilstm already installed in /home/aistudio/.paddlehub/modules/senta_bilstm
[32m[2020-07-22 10:34:08,937] [ INFO] - Installing lac module[0m
[32m[2020-07-22 10:34:08,939] [ INFO] - Module lac already installed in /home/aistudio/.paddlehub/modules/lac [0m
情感分析结果: [{'text': '味道不错,确实不算太辣,适合不能吃辣的人。就在长江边上,抬头就能看到长江的风景。鸭肠、黄鳝都比较新鲜。', 'sentiment_label': 1, 'sentiment_key': 'positive', 'positive_probs': 0.9771, 'negative_probs': 0.0229}]
## 总结
PaddleHub提供了丰富的预训练模型,包括图像分类、语义模型、视频分类、图像生成、图像分割、文本审核、关键点检测等主流模型,只需要3行Python代码即可快速调用,即时输出预测结果,非常方便。您可以尝试一下,从[预训练模型列表](https://www.paddlepaddle.org.cn/hublist)中选择一些模型体验一下。
快速体验
==================
PaddleHub有两种使用方式:Python代码调用和命令行调用。
命令行方式只需要一行命令即可快速体验PaddleHub提供的预训练模型的效果,是快速体验的绝佳选择;Python代码调用方式也仅需要三行代码,如果需要使用自己的数据Fine-tune并生成模型,则采用该方式。
命令行示例:
::
$ hub run chinese_ocr_db_crnn_mobile --input_path test_ocr.jpg
Python代码示例:
::
import paddlehub as hub
ocr = hub.Module(name="chinese_ocr_db_crnn_mobile")
result = ocr.recognize_text(paths = "./test_image.jpg"], visualization=True, output_dir='ocr_output')
样例结果示例:
.. image:: ../imgs/ocr_res.jpg
本章节提供这两种方法的快速体验方法,方便快速上手,同时提供了丰富的体验Demo,覆盖多场景领域,欢迎体验。具体使用时,当然还需要进一步了解详细的API接口参数、命令行参数解释,可参考后面的Python API接口和命令行参考章节。
.. toctree::
:maxdepth: 1
通过命令行调用方式使用PaddleHub<cmd_quick_run>
通过Python代码调用方式使用PaddleHub<python_use_hub>
PaddleHub更多体验Demos<more_demos>
## hub.config
在PaddleHub中,RunConfig代表了在对[Task](./task)进行Fine-tune时的运行配置。包括运行的epoch次数、batch的大小、是否使用GPU训练等。
### Class `hub.finetune.config.RunConfig`
```python
hub.RunConfig(
log_interval=10,
eval_interval=100,
use_data_parallel=True,
save_ckpt_interval=None,
use_cuda=False,
checkpoint_dir=None,
num_epoch=10,
batch_size=None,
enable_memory_optim=False,
strategy=None)`
```
**参数:**
* `log_interval`: 打印训练日志的周期,默认为10。
* `eval_interval`: 进行评估的周期,默认为100。
* `use_data_parallel`: 是否使用并行计算,默认True。打开该功能依赖nccl库。
* `save_ckpt_interval`: 保存checkpoint的周期,默认为None。
* `use_cuda`: 是否使用GPU训练和评估,默认为False。
* `checkpoint_dir`: checkpoint的保存目录,默认为None,此时会在工作目录下根据时间戳生成一个临时目录。
* `num_epoch`: 运行的epoch次数,默认为10。
* `batch_size`: batch大小,默认为None。
* `enable_memory_optim`: 是否进行内存优化,默认为False。
* `strategy`: finetune的策略。默认为None,此时会使用DefaultFinetuneStrategy策略。
**返回**
`RunConfig`
**示例**
```python
import paddlehub as hub
config = hub.RunConfig(
use_cuda=True,
num_epoch=10,
batch_size=32)
```
#### `log_interval`
获取RunConfig设置的log_interval属性
**示例**
```python
import paddlehub as hub
config = hub.RunConfig()
log_interval = config.log_interval()
```
#### `eval_interval`
获取RunConfig设置的eval_interval属性
**示例**
```python
import paddlehub as hub
config = hub.RunConfig()
eval_interval = config.eval_interval()
```
#### `use_pyreader`
获取RunConfig设置的use_pyreader属性
**示例**
```python
import paddlehub as hub
config = hub.RunConfig()
use_pyreader = config.use_pyreader()
```
#### `use_data_parallel`
获取RunConfig设置的use_data_parallel属性
**示例**
```python
import paddlehub as hub
config = hub.RunConfig()
use_data_parallel = config.use_data_parallel()
```
#### `save_ckpt_interval`
获取RunConfig设置的save_ckpt_interval属性
**示例**
```python
import paddlehub as hub
config = hub.RunConfig()
save_ckpt_interval = config.save_ckpt_interval()
```
#### `use_cuda`
获取RunConfig设置的use_cuda属性
**示例**
```python
import paddlehub as hub
config = hub.RunConfig()
use_cuda = config.use_cuda()
```
#### `checkpoint_dir`
获取RunConfig设置的checkpoint_dir属性
**示例**
```python
import paddlehub as hub
config = hub.RunConfig()
checkpoint_dir = config.checkpoint_dir()
```
#### `num_epoch`
获取RunConfig设置的num_epoch属性
**示例**
```python
import paddlehub as hub
config = hub.RunConfig()
num_epoch = config.num_epoch()
```
#### `batch_size`
获取RunConfig设置的batch_size属性
**示例**
```python
import paddlehub as hub
config = hub.RunConfig()
batch_size = config.batch_size()
```
#### `strategy`
获取RunConfig设置的strategy属性
**示例**
```python
import paddlehub as hub
config = hub.RunConfig()
strategy = config.strategy()
```
#### `enable_memory_optim`
获取RunConfig设置的enable_memory_optim属性
**示例**
```python
import paddlehub as hub
config = hub.RunConfig()
enable_memory_optim = config.enable_memory_optim()
```
**若您想在自定义数据集上完成Fine-tune,请查看[PaddleHub适配自定义数据完成Fine-tune](../tutorial/how_to_load_data.md)**
## hub.dataset
### Class `hub.dataset.ChnSentiCorp`
ChnSentiCorp 是中文情感分析数据集,其目标是判断一段文本的情感态度。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.ChnSentiCorp()
```
数据集样例
```text
label text_a
1 选择珠江花园的原因就是方便,有电动扶梯直接到达海边,周围餐馆、食廊、商场、超市、摊位一应俱全。酒店装修一般,但还算整洁。 泳池在大堂的屋顶,因此很小,>不过女儿倒是喜欢。 包的早餐是西式的,还算丰富。 服务吗,一般
1 15.4寸笔记本的键盘确实爽,基本跟台式机差不多了,蛮喜欢数字小键盘,输数字特方便,样子也很美观,做工也相当不错
0 房间太小。其他的都一般。。。。。。。。。
...
```
以上类别“0”表示反对态度,“1”表示支持态度。每个字段以tab键分隔。
### Class `hub.dataset.LCQMC`
LCQMC 是哈尔滨工业大学在自然语言处理国际顶会 COLING2018 构建的问答匹配中文数据集,其目标是判断两个问题的语义是否相同。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.LCQMC()
```
数据集样例
```text
text_a text_b label
喜欢打篮球的男生喜欢什么样的女生 爱打篮球的男生喜欢什么样的女生 1
我手机丢了,我想换个手机 我想买个新手机,求推荐 1
大家觉得她好看吗 大家觉得跑男好看吗? 0
...
```
以上类别“0”表示语义相同,“1”表示语义相反。每个字段以tab键分隔。
### Class `hub.dataset.NLPCC_DPQA`
NLPCC_DPQA 是由国际自然语言处理和中文计算会议NLPCC于2016年举办的评测任务,其目标是选择能够回答问题的答案。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.NLPCC_DPQA()
```
数据集样例
```text
qid text_a text_b label
0 黑缘粗角肖叶甲触角有多大? 触角近于体长之半,第1节粗大,棒状,第2节短,椭圆形,3、4两节细长,稍短于第5节,第5节基细端粗,末端6节明显粗大。 1
0 黑缘粗角肖叶甲触角有多大? 前胸前侧片前缘直;前胸后侧片具粗大刻点。 0
0 黑缘粗角肖叶甲触角有多大? 足粗壮;胫节具纵脊,外端角向外延伸,呈弯角状;爪具附齿。 0
1 暮光闪闪的姐姐是谁? 暮光闪闪是一匹雌性独角兽,后来在神秘魔法的影响下变成了空角兽(公主),她是《我的小马驹:友情是魔法》(英文名:My Little Pony:Friendship is Magic)中的主角之一。 0
1 暮光闪闪的姐姐是谁? 她是银甲闪闪(Shining Armor)的妹妹,同时也是韵律公主(Princess Cadance)的小姑子。 1
...
```
以上qid表示问题的序号,类别“0”表示相应问题的错误答案,类别“1”表示相应问题的正确答案。每个字段以tab键分隔。
### Class `hub.dataset.MSRA_NER`
MSRA-NER(SIGHAN 2006) 数据集由微软亚研院发布,其目标是命名实体识别,是指识别中文文本中具有特定意义的实体,主要包括人名、地名、机构名等。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.MSRA-NER()
```
数据集样例
```text
text_a label
海^B钓^B比^B赛^B地^B点^B在^B厦^B门^B与^B金^B门^B之^B间^B的^B海^B域^B。 O^BO^BO^BO^BO^BO^BO^BB-LOC^BI-LOC^BO^BB-LOC^BI-LOC^BO^BO^BO^BO^BO^BO
这^B座^B依^B山^B傍^B水^B的^B博^B物^B馆^B由^B国^B内^B一^B流^B的^B设^B计^B师^B主^B持^B设^B计^B,^B整^B个^B建^B筑^B群^B精^B美^B而^B恢^B宏^B。 O^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO
但^B作^B为^B一^B个^B共^B产^B党^B员^B、^B人^B民^B公^B仆^B,^B应^B当^B胸^B怀^B宽^B阔^B,^B真^B正^B做^B到^B“^B先^B天^B下^B之^B忧^B而^B忧^B,^B后^B天^B下^B之^B乐^B而^B乐^B”^B,^B淡^B化^B个^B人^B的^B名^B利^B得^B失^B和^B宠^B辱^B悲^B喜^B,^B把^B改^B革^B大^B业^B摆^B在^B首^B位^B,^B这^B样^B才^B能^B超^B越^B自^B我^B,^B摆^B脱
^B世^B俗^B,^B有^B所^B作^B为^B。 O^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO^BO
...
```
以上label是针对每一个字的标签,并且一句话中的每个字以不可见字符“\002”分隔(如上述“^B”)。每个字段以tab键分隔。标注规则如下表:
| 标签 | 定义 |
| ---- | ---- |
| B-LOC | 地点的起始位置 |
| I-LOC | 地点的中间或结束位置 |
| B-PER | 人名的起始位置 |
| I-PER | 人名的中间或结束位置 |
| B-ORG | 机构名的起始位置 |
| I-ORG | 机构名的中间或者结束位置 |
| O | 不关注的字 |
### Class `hub.dataset.Toxic`
Toxic 是英文多标签分类数据集,其目标是将一段话打上6个标签,toxic(恶意),severetoxic(穷凶极恶),obscene(猥琐),threat(恐吓),insult(侮辱),identityhate(种族歧视),这些标签并不是互斥的。即这段话可以打上多个标签。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.Toxic()
```
数据集样例
```text
id,comment_text,toxic,severe_toxic,obscene,threat,insult,identity_hate
0000997932d777bf,"Explanation
Why the edits made under my username Hardcore Metallica Fan were reverted? They weren't vandalisms, just closure on some GAs after I voted at New York Dolls FAC. And please don't remove the template from the talk page since I'm retired now.89.205.38.27",0,0,0,0,0,0
000103f0d9cfb60f,"D'aww! He matches this background colour I'm seemingly stuck with. Thanks. (talk) 21:51, January 11, 2016 (UTC)",0,0,0,0,0,0
0002bcb3da6cb337,COCKSUCKER BEFORE YOU PISS AROUND ON MY WORK,1,1,1,0,1,0
...
```
每个字段以","分隔。第一列表示样本ID,第二列表示样本文本数据,第3-8列表示相应样本是否含有对应的标签(0表示没有对应列的标签,1表示有对应列的标签)。如示例数据中的第三条数据,表示文本"COCKSUCKER BEFORE YOU PISS AROUND ON MY WORK"有标签toxic、severe_toxic、obscene和insult。
### Class `hub.dataset.SQUAD`
SQuAD 是英文阅读理解数据集,给定一个段落文本以及一个问题,其目标是在该段落中找到问题的答案位置。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.SQUAD()
```
关于该数据集详细信息可以参见[SQuAD官网介绍](https://rajpurkar.github.io/SQuAD-explorer/)
### Class `hub.dataset.GLUE`
GLUE是一个英文数据集集合,包含9项自然语言理解任务数据集:
- 文本分类任务数据集CoLA,其目标是给定一个句子,判断其语法正确性。
- 情感分析任务数据集吧SST-2,其目标是给定一个句子,判断其情感极性。
- 句子对分类任务数据集MRPC,其目标是给定两个句子,判断它们是否具有相同的语义关系。
- 回归任务数据集STS-B,其目标是给定两个句子,计算它们的语义相似性。
- 句子对分类任务数据集QQP,其目标是给定两个句子,判断它们是否具有相同的语义关系。
- 文本推理任务数据集MNLI,其目标是给定前提与假设,判断它们的逻辑关系(“矛盾“ / “中立” / “蕴含”)。该数据集又分为“匹配”与“不匹配”两个版本,“匹配”与“不匹配”指的是训练集与测试集的数据来源是否一致,是否属于相同领域风格的文本。在PaddleHub中,您可以通过“MNLI_m”和"MNLI_mm"来指定不同的版本
- 问题推理任务QNLI,其目标是给定问题,判断它的回答是否正确。
- 文本蕴含任务RTE,其目标是给定两个句子,判断它们是否具有蕴含关系。
- 文本蕴含任务WNLI,其目标是给定两个句子,判断它们是否具有蕴含关系。由于该数据集存在一些问题,我们暂时没有实现该数据集。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.GLUE(sub_dataset='SST-2')
MNLI_Matched = hub.dataset.GLUE(sub_dataset='MNLI_m')
MNLI_MisMatched = hub.dataset.GLUE(sub_dataset='MNLI_mm')
```
关于该数据集详细信息可以参见[GLUE官网介绍](https://gluebenchmark.com/)
### Class `hub.dataset.XNLI`
XNLI是一个跨语言自然语言推理数据集,其目标是给定前提与假设,判断它们的逻辑关系(“矛盾“ / “中立” / “蕴含”)。XNLI的验证集与测试集包含15种语言版本,在BERT与ERNIE中,它的训练集来自英文数据集MNLI,将其翻译至对应的语言版本即可。我们采用了相同的数据集方案,并划分了15种语言的数据集:
<table>
<thead>
</thead>
<tbody><tr>
<td align="center">ar - Arabic</td>
<td align="center">bg - Bulgarian</td>
<td align="center">de - German</td>
</tr>
<tr>
<td align="center">el - Greek</td>
<td align="center">en - English</td>
<td align="center">es - Spanish </td>
</tr>
<tr>
<td align="center">fr - French </td>
<td align="center">hi - Hindi</td>
<td align="center">ru - Russian</td>
</tr>
<tr>
<td align="center">sw - Swahili </td>
<td align="center">th - Thai</td>
<td align="center">tr - Turkish</td>
</tr>
<tr>
<td align="center">ur - Urdu </td>
<td align="center">vi - Vietnamese</td>
<td align="center">zh - Chinese</td>
</tr>
</tbody></table>
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.XNLI(language='zh')
```
以中文数据集为例:
```text
premise hypo label
从 概念 上 看 , 奶油 收入 有 两 个 基本 方面 产品 和 地理 . 产品 和 地理 是 什么 使 奶油 抹 霜 工作 . neutral
我们 的 一个 号码 会 非常 详细 地 执行 你 的 指示 我 团队 的 一个 成员 将 非常 精确 地 执行 你 的 命令 entailment
男 女 同性恋 . 异性恋者 contradiction
```
每个字段以tab键分隔。类别netral表示中立,类别entailment表示蕴含,类别contradiction表示矛盾。
### Class `hub.dataset.TNews`
TNews是今日头条中文新闻(短文本)分类数据集,其目标是为短新闻进行分类。该数据集总共15个类别,包括 "news_story", "news_culture", "news_entertainment", "news_sports", "104": "news_finance", "news_house", "news_car", "news_edu", "news_tech", "news_military", "news_travel", "news_world", "stock", "news_agriculture", "news_game"。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.TNews()
```
数据集样例:
```text
6552277613866385923_!_104_!_news_finance_!_股票中的突破形态_!_股票
6553229876915077646_!_102_!_news_entertainment_!_他是最帅的古装男神,10国语言六门武术,演技在线却常演配角!_!_三生三世十里桃花,张智尧,杨门女将之女儿当自强,陆
小凤,印象深刻,陆小凤传奇,杨宗保,花满楼,古剑奇谭
6553551207028228622_!_102_!_news_entertainment_!_陈伟霆和黄晓明真的有差别,难怪baby会选择黄晓明_!_陈伟霆,黄晓明,粉丝
```
每个字段以“\_!\_”进行分隔,第一列表示数据ID,第二列表示类别ID, 第三列表示类别,第四列表示短新闻文本,第五列表示文本关键词。
### Class `hub.dataset.INews`
INews是一个互联网情感分析任务,其目标是判断中文长文本的情感倾向,数据集总共分3类(0,1,2)。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.INews()
```
数据集样例:
```text
label_!_id_!_title_!_content
1_!_bbf2e8a4824149bea36e703bbe8b0795_!_问大家一下,g20峰会之后,杭州的外国人是不是一下子多起来了_!_问大家一下,g20峰会之后,杭州的外国人是不是一下子多起来了,尤其是在杭州定居的外国人?
```
每个字段以“\_!\_”进行分隔,第一列表示类别,第二列表示数据ID, 第三列表示新闻标题,第四列表示新闻文本。
### Class `hub.dataset.DRCD`
DRCD是台达阅读理解数据集,属于通用领域繁体中文机器阅读理解数据集。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.DRCD()
```
数据格式和SQuAD相同,关于该数据集详细信息参见[DRCD](https://github.com/DRCKnowledgeTeam/DRCD)
### Class `hub.dataset.CMRC2018`
CMRC2018聚焦基于篇章片段抽取的中文阅读理解,给定篇章、问题,其目标是从篇章中抽取出连续片段作为答案。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.CMRC2018()
```
数据格式和SQuAD相同,关于该数据集详细信息参见[CMRC](https://hfl-rc.github.io/cmrc2018/)
### Class `hub.dataset.BQ`
BQ是一个智能客服中文问句匹配数据集,该数据集是自动问答系统语料,共有120,000对句子对,并标注了句子对相似度值。数据中存在错别字、语法不规范等问题,但更加贴近工业场景。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.BQ()
```
数据集样例:
```text
请问一天是否都是限定只能转入或转出都是五万。 微众多少可以赎回短期理财 0
微粒咨询电话号码多少 你们的人工客服电话是多少 1
已经在银行换了新预留号码。 我现在换了电话号码,这个需要更换吗 1
```
每个字段以tab键分隔,第1,2列表示两个文本。第3列表示类别(0或1,0表示两个文本不相似,1表示两个文本相似)。
### Class `hub.dataset.IFLYTEK`
IFLYTEK是一个中文长文本分类数据集,该数据集共有1.7万多条关于app应用描述的长文本标注数据,包含和日常生活相关的各类应用主题,共119个类别:"打车":0,"地图导航":1,"免费WIFI":2,"租车":3,….,"女性":115,"经营":116,"收款":117,"其他":118(分别用0-118表示)。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.IFLYTEK()
```
数据集样例:
```text
70_!_随意发SendAnywherePro是一款文件分享工具,你可以快速的将分享手机中的照片、视频、联系人、应用、文件、文件夹等任何文件分享给其他人,可以在手机之前发送或接收,也可以通过官网www.sendweb.com不许要注册账号,只需输入一次key即可接收。
```
每个字段以“\_!\_”键分隔,第1列表示类别ID。第2列表示文本数据。
### Class `hub.dataset.THUCNEWS`
THUCNEWS是一个中文长文本分类数据集,该数据集共有4万多条中文新闻长文本标注数据,共14个类别,包括"体育", "娱乐", "家居", "彩票", "房产", "教育", "时尚", "时政", "星座", "游戏", "社会", "科技", "股票", "财经"。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.THUCNEWS()
```
数据集样例:
```text
0_!_体育_!_97498.txt_!_林书豪拒绝中国篮协邀请 将随中华台北征战亚锦赛  信息时报讯 (记者 冯爱军) 中国篮协比中华台北篮协抢先一步了。据台湾媒体报道,刚刚成功签...倘若顺利,最快明年东亚区资格赛与亚锦赛就有机会看到林书豪穿上中华台北队球衣。”
```
每个字段以“\_!\_”键分隔,第1列表示类别ID,第2列表示类别,第3列表示文本数据。
### Class `hub.dataset.Couplet`
Couplet是一个开源对联数据集,来源于https://github.com/v-zich/couplet-clean-dataset。该数据集包含74万条对联数据,已利用敏感词词库过滤、删除了低俗或敏感内容。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.Couplet()
```
数据集样例:
```text
亲情似日堪融雪 孝意如春可著花
```
上下联中每个字以不可见字符“\002”分隔,上下联之间以tab键分隔。
### Class `hub.dataset.DogCatDataset`
DOGCAT是由Kaggle提供的数据集,用于图像二分类,其目标是判断一张图片是猫或是狗。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.DogCatDataset()
```
数据集样例:
```text
dog/4122.jpg 1
dog/6337.jpg 1
cat/3853.jpg 0
cat/5831.jpg 0
```
每个字段以空格键分隔。第一列表示图片所在路径,第二列表示图片类别,1表示属于,0表示不属于。
### Class `hub.dataset.Food101`
FOOD101 是由Kaggle提供的数据集,含有101种类别,其目标是判断一张图片属于101种类别中的哪一种类别。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.Food101()
```
关于该数据集详细信息参见[Kaggle Food101](https://www.kaggle.com/dansbecker/food-101)
### Class `hub.dataset.Indoor67`
INDOOR数据集是由麻省理工学院发布,其包含67种室内场景,其目标是识别一张室内图片的场景类别。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.Indoor67()
```
关于该数据集详细信息参见[Indoor67](http://web.mit.edu/torralba/www/indoor.html)
### Class `hub.dataset.Flowers`
Flowers数据集是是公开花卉数据集,数据集有5种类型,包括"roses","tulips","daisy","sunflowers","dandelion"。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.Flowers()
```
数据集样例:
```text
dandelion/7148085703_b9e8bcd6ca_n.jpg 4
roses/5206847130_ee4bf0e4de_n.jpg 0
tulips/8454707381_453b4862eb_m.jpg 1
```
每个字段以空格键分隔。第一列表示图片所在路径,第二列表示图片类别ID。
### Class `hub.dataset.StanfordDogs`
StanfordDogS数据集是斯坦福大学发布,其包含120个种类的狗,用于做图像分类。
**示例**
```python
import paddlehub as hub
dataset = hub.dataset.StanfordDogs()
```
关于该数据集详细信息参考[StanfordDogs](http://vision.stanford.edu/aditya86/ImageNetDogs/main.html)
# Class `hub.datasets.Canvas`
```python
hub.datasets.Canvas(
transforms: Callable,
mode: str = 'train')
```
Dataset for colorization. It contains 1193 and 400 pictures for Monet and Vango paintings style, respectively. We collected data from https://people.eecs.berkeley.edu/~taesung_park/CycleGAN/datasets/.
**Args**
* transforms(callmethod) : The method of preprocess images.
* mode(str): The mode for preparing dataset.
# Class `hub.datasets.Flowers`
```python
hub.datasets.Flowers(
transforms: Callable,
mode: str = 'train')
```
Dataset for image classification. It contains 5 categories(roses, tulips, daisy, sunflowers, dandelion) and a total of 3667 pictures, of which 2914 are used for training, 382 are used for verification, and 371 are used for testing.
**Args**
* transforms(callmethod) : The method of preprocess images.
* mode(str): The mode for preparing dataset.
# Class `hub.datasets.MiniCOCO`
```python
hub.datasets.MiniCOCO(
transforms: Callable,
mode: str = 'train')
```
Dataset for Style transfer. The dataset contains 2001 images for training set and 200 images for testing set.They are derived form COCO2014. Meanwhile, it contains 21 different style pictures in file "21styles".
**Args**
* transforms(callmethod) : The method of preprocess images.
* mode(str): The mode for preparing dataset.
预置数据集
==================
PaddleHub预置了多种任务的预置数据集,用户可以通过预置数据集进行快速体验。
.. toctree::
:maxdepth: 1
:titlesonly:
hub.datasets.Canvas<datasets/canvas>
hub.datasets.Flowers<datasets/flowers>
hub.datasets.MiniCOCO<datasets/minicoco>
\ No newline at end of file
# Class `hub.finetune.Trainer`
```python
hub.finetune.Trainer(
model: paddle.nn.Layer,
optimizer: paddle.optimizer.Optimizer,
use_vdl: bool = True,
checkpoint_dir: str = None,
compare_metrics: Callable = None)
```
Model trainer
**Args**
* model(paddle.nn.Layer) : Model to train or evaluate.
* optimizer(paddle.optimizer.Optimizer) : Optimizer for loss.
* use_vdl(bool) : Whether to use visualdl to record training data.
* checkpoint_dir(str) : Directory where the checkpoint is saved, and the trainer will restore the state and model parameters from the checkpoint.
* compare_metrics(callable) : The method of comparing the model metrics. If not specified, the main metric return by `validation_step` will be used for comparison by default, the larger the value, the better the effect. This method will affect the saving of the best model. If the default behavior does not meet your requirements, please pass in a custom method.
----
```python
def train(
train_dataset: paddle.io.Dataset,
epochs: int = 1,
batch_size: int = 1,
num_workers: int = 0,
eval_dataset: paddle.io.Dataset = None,
log_interval: int = 10,
save_interval: int = 10)
```
Train a model with specific config.
**Args**
* train_dataset(paddle.io.Dataset) : Dataset to train the model
* epochs(int) : Number of training loops, default is 1.
* batch_size(int) : Batch size of per step, default is 1.
* num_workers(int) : Number of subprocess to load data, default is 0.
* eval_dataset(paddle.io.Dataset) : The validation dataset, deafult is None. If set, the Trainer will execute evaluate function every `save_interval` epochs.
* log_interval(int) : Log the train infomation every `log_interval` steps.
* save_interval(int) : Save the checkpoint every `save_interval` epochs.
----
```python
def evaluate(
eval_dataset: paddle.io.Dataset,
batch_size: int = 1,
num_workers: int = 0):
```
Run evaluation and returns metrics.
**Args**
* eval_dataset(paddle.io.Dataset) : The validation dataset
* batch_size(int) : Batch size of per step, default is 1.
* num_workers(int) : Number of subprocess to load data, default is 0.
# Class `hub.Module`
```python
hub.Module(
name: str = None,
directory: str = None,
version: str = None,
source: str = None,
update: bool = False,
branch: str = None,
**kwargs):)
```
In PaddleHub, Module represents an executable module, which usually a pre-trained model that can be used for end-to-end prediction, such as a face detection model or a lexical analysis model, or a pre-trained model that requires finetuning, such as BERT/ERNIE. When loading a Module with a specified name, if the Module does not exist locally, PaddleHub will automatically request the server or the specified Git source to download the resource.
**Args**
* name(str): Module name.
* directory(str|optional): Directory of the module to be loaded, only takes effect when the `name` is not specified.
* version(str|optional): The version limit of the module, only takes effect when the `name` is specified. When the local Module does not meet the specified version conditions, PaddleHub will re-request the server to download the appropriate Module. Default to None, This means that the local Module will be used. If the Module does not exist, PaddleHub will download the latest version available from the server according to the usage environment.
* source(str|optional): Url of a git repository. If this parameter is specified, PaddleHub will no longer download the specified Module from the default server, but will look for it in the specified repository. Default to None.
* update(bool|optional): Whether to update the locally cached git repository, only takes effect when the `source` is specified. Default to False.
* branch(str|optional): The branch of the specified git repository. Default to None.
参考
==================
以下介绍了PaddleHub 数据集(dataset)、优化策略(strategy)、运行配置(config)、迁移任务(task)等API介绍。
以下介绍了PaddleHub 数据集(datasets)、训练器(finetune.Trainer)、预训练模型(Module)、数据增强模块(vision.transforms)等API介绍。
.. toctree::
:maxdepth: 1
hub.dataset<dataset>
hub.strategy<strategy>
hub.config<config>
hub.task<task_index>
\ No newline at end of file
hub.datasets<datasets_index>
hub.finetune.Trainer<finetune>
hub.Module<module>
hub.vision.transforms<vision>
\ No newline at end of file
## hub.strategy
在PaddleHub中,Strategy类封装了一系列适用于迁移学习的Fine-tune策略。Strategy包含了对预训练参数使用什么学习率变化策略,使用哪种类型的优化器,使用什么类型的正则化等。
### Class `hub.finetune.strategy.AdamWeightDecayStrategy`
```python
hub.AdamWeightDecayStrategy(
learning_rate=1e-4,
lr_scheduler="linear_decay",
warmup_proportion=0.0,
weight_decay=0.01,
optimizer_name="adam")
```
基于Adam优化器的学习率衰减策略
**参数**
* learning_rate: 全局学习率,默认为1e-4
* lr_scheduler: 学习率调度方法,默认为"linear_decay"
* warmup_proportion: warmup所占比重
* weight_decay: 学习率衰减率
* optimizer_name: 优化器名称,默认为adam
**返回**
`AdamWeightDecayStrategy`
**示例**
```python
...
strategy = hub.AdamWeightDecayStrategy()
config = hub.RunConfig(
use_cuda=True,
num_epoch=10,
batch_size=32,
checkpoint_dir="hub_finetune_ckpt",
strategy=strategy)
```
### Class `hub.finetune.strategy.DefaultFinetuneStrategy`
```python
hub.DefaultFinetuneStrategy(
learning_rate=1e-4,
optimizer_name="adam",
regularization_coeff=1e-3)
```
默认的Finetune策略,该策略会对预训练参数增加L2正则作为惩罚因子
**参数**
* learning_rate: 全局学习率。默认为1e-4
* optimizer_name: 优化器名称。默认adam
* regularization_coeff: 正则化的λ参数。默认为1e-3
**返回**
`DefaultFinetuneStrategy`
**示例**
```python
...
strategy = hub.DefaultFinetuneStrategy()
config = hub.RunConfig(
use_cuda=True,
num_epoch=10,
batch_size=32,
checkpoint_dir="hub_finetune_ckpt",
strategy=strategy)
```
### Class `hub.finetune.strategy.L2SPFinetuneStrategy`
```python
hub.L2SPFinetuneStrategy(
learning_rate=1e-4,
optimizer_name="adam",
regularization_coeff=1e-3)
```
使用L2SP正则作为惩罚因子的Finetune策略
**参数**
* learning_rate: 全局学习率。默认为1e-4
* optimizer_name: 优化器名称。默认为adam
* regularization_coeff: 正则化的λ参数。默认为1e-3
**返回**
`L2SPFinetuneStrategy`
**示例**
```python
...
strategy = hub.L2SPFinetuneStrategy()
config = hub.RunConfig(
use_cuda=True,
num_epoch=10,
batch_size=32,
checkpoint_dir="hub_finetune_ckpt",
strategy=strategy)
```
### Class `hub.finetune.strategy.ULMFiTStrategy`
```python
hub.ULMFiTStrategy(
learning_rate=1e-4,
optimizer_name="adam",
cut_fraction=0.1,
ratio=32,
dis_blocks=3,
factor=2.6,
frz_blocks=3)
```
该策略实现了[ULMFiT](https://arxiv.org/abs/1801.06146)论文中提出的三种策略:Slanted triangular learning rates, Discriminative fine-tuning, Gradual unfreezing。
- Slanted triangular learning rates是一种学习率先上升再下降的策略,如下图所示:
<div align=center><img src="https://github.com/PaddlePaddle/PaddleHub/wiki/images/slanted.png" width="50%" height="50%"></div>
- Discriminative fine-tuning是一种学习率逐层递减的策略,通过该策略可以减缓底层的更新速度。
- Gradual unfreezing是一种逐层解冻的策略,通过该策略可以优先更新上层,再慢慢解冻下层参与更新。
**参数**
* learning_rate: 全局学习率。默认为1e-4。
* optimizer_name: 优化器名称。默认为adam。
* cut_fraction: 设置Slanted triangular learning rates学习率上升的步数在整个训练总步数中的比例,对应论文中Slanted triangular learning rates中的cut_frac。默认为0.1,如果设置为0,则不采用Slanted triangular learning rates。
* ratio: 设置Slanted triangular learning rates下降的最小学习率与上升的最大学习率的比例关系,默认为32,表示最小学习率是最大学习率的1/32。
* dis_blocks: 设置 Discriminative fine-tuning中的块数。由于预训练模型中没有记录op的层数,Paddlehub通过op的前后关系推测op所在的层次,这会导致诸如LSTM这类计算单元的op会被当作是不同层的op。为了不使层次划分太细,我们将层次进行了分块,用块的概念代替原论文中层的概念,通过设置dis_blocks即可设置块的个数。默认为3,如果设置为0,则不采用Discriminative fine-tuning。
* factor: 设置Discriminative fine-tuning的衰减率。默认为2.6,表示下一层的学习率是上一层的1/2.6。
* frz_blocks: 设置Gradual unfreezing中的块数。块的概念同“dis_blocks”中介绍的概念。
**返回**
`ULMFiTStrategy`
**示例**
```python
...
strategy = hub.ULMFiTStrategy()
config = hub.RunConfig(
use_cuda=True,
num_epoch=10,
batch_size=32,
checkpoint_dir="hub_finetune_ckpt",
strategy=strategy)
```
### Class `hub.finetune.strategy.CombinedStrategy`
```python
hub.CombinedStrategy(
optimizer_name="adam",
learning_rate=1e-4,
scheduler=None,
regularization=None,
clip=None)
```
Paddlehub中的基类策略,上文的所有策略都基于该策略,通过该策略可以设置所有策略参数。
**参数**
* optimizer_name: 优化器名称,默认为adam。
* learning_rate: 全局学习率,默认为1e-4。
* scheduler: 学习率调度方法,默认为None,此时不改变任何默认学习率调度方法参数,不采取任何学习率调度方法,即:
```python
scheduler = {
"warmup": 0.0,
"linear_decay": {
"start_point": 1.0,
"end_learning_rate": 0.0,
},
"noam_decay": False,
"discriminative": {
"blocks": 0,
"factor": 2.6
},
"gradual_unfreeze": 0,
"slanted_triangle": {
"cut_fraction": 0.0,
"ratio": 32
}
}
```
* regularization: 正则方法,默认为None,此时不改变任何默认正则方法参数,不采取任何正则方法,即:
```python
regularization = {
"L2": 0.0,
"L2SP": 0.0,
"weight_decay": 0.0,
}
```
* clip: 梯度裁剪方法,默认为None,此时不改变任何默认正则方法参数,不采取任何梯度裁剪方法,即:
```python
clip = {
"GlobalNorm": 0.0,
"Norm": 0.0
}
```
**返回**
`CombinedStrategy`
**示例**
```python
...
# Parameters not specified will remain default
scheduler = {
"discriminative": {
"blocks": 3,
"factor": 2.6
}
}
# Parameters not specified will remain default
regularization = {"L2": 1e-3}
# Parameters not specified will remain default
clip = {"GlobalNorm": 1.0}
strategy = hub.CombinedStrategy(
scheduler = scheduler,
regularization = regularization,
clip = clip
)
config = hub.RunConfig(
use_cuda=True,
num_epoch=10,
batch_size=32,
checkpoint_dir="hub_finetune_ckpt",
strategy=strategy)
```
# Class `hub.BaseTask`
基础的Task类,封装了finetune、eval、finetune_and_eval、predict等基础接口以及事件的回调机制。该类无法直接使用,需要继承实现特定接口
```python
hub.BaseTask(
feed_list,
data_reader,
main_program=None,
startup_program=None,
config=None,
metrics_choice="default"):
```
**参数**
* feed_list (list): 待feed变量的名字列表
* data_reader: 提供数据的Reader
* main_program (fluid.Program): 存储了模型计算图的Program,如果未提供,则使用fluid.default_main_program()
* startup_program (fluid.Program): 存储了模型参数初始化op的Program,如果未提供,则使用fluid.default_startup_program()
* config ([RunConfig](../config.md)): 运行配置
* metric_choices : 任务评估指标,默认为"acc"。metrics_choices支持训练过程中同时评估多个指标,作为最佳模型的判断依据,例如["matthews", "acc"],"matthews"将作为主指标,为最佳模型的判断依据;
## 基本概念
### phase / 执行状态
Task可以有不同的执行状态(训练/测试/预测),在不同状态下所获取到的属性会有区别,例如,当处于训练状态时,通过task获取到的feed_list除了输入特征外,还包括输入label,而处于预测状态时,所获取到的feed_list只包括输入特征
Task通过phase属性来区分不同的状态,对应的关系如下:
|phase|状态|
|-|-|
|train|训练|
|val, dev, test|评估|
|predict, inference|预测|
### env / 执行环境
Task中的每个执行状态,都有一个对应的执行环境env([RunEnv])用于保存该状态下的属性。当phase发生变化时,env也会发生变化,从而保证用户在不同状态下可以取到正确的属性。
## Func `phase_guard`
配合使用python的“with”语句来改变task的phase状态,在with块中,task的phase为所指定的新phase,退出with块后,恢复上一个phase
**参数**
* phase: 所要切换的phase状态,必须是[有效的phase状态](#phase--执行状态)
**示例**
```python
import paddlehub as hub
...
# 打印该task进行过多少个step的训练
with task.phase_guard("train"):
print(task.current_step)
```
## Func `enter_phase`
改变task的phase状态
**参数**
* phase: 所要切换的phase状态,必须是[有效的phase状态](#phase--执行状态)
**示例**
```python
import paddlehub as hub
...
# 打印该task进行过多少个step的训练
task.enter_phase("train")
print(task.current_step)
```
## Func `exit_phase`
退出task的当前phase状态,回到上一步的状态
**参数**
* phase: 所要切换的phase状态
**示例**
```python
import paddlehub as hub
...
task.enter_phase("train")
task.exit_phase()
```
## Func `save_checkpoint`
保存当前的checkpoint到config指定的目录
**示例**
```python
import paddlehub as hub
...
with task.phase_guard("train"):
task.save_checkpoint()
```
## Func `load_checkpoint`
从config指定的checkpoint目录中加载checkpoint数据
**示例**
```python
import paddlehub as hub
...
with task.phase_guard("train"):
task.load_checkpoint()
```
## Func `save_parameters`
保存参数到指定的目录
**参数**
* dirname: 保存参数的目录
**示例**
```python
import paddlehub as hub
...
with task.phase_guard("train"):
task.save_parameters("./params")
```
## Func `load_parameters`
从指定的目录中加载参数
**参数**
* dirname: 待加载参数所在目录
**示例**
```python
import paddlehub as hub
...
with task.phase_guard("train"):
task.load_parameters("./params")
```
## Func `finetune`
根据config配置进行finetune
**示例**
```python
import paddlehub as hub
...
task.finetune()
```
## Func `finetune_and_eval`
根据config配置进行finetune,并且定期进行eval
**示例**
```python
import paddlehub as hub
...
task.finetune_and_eval()
```
## Func `eval`
根据config配置进行eval
**示例**
```python
import paddlehub as hub
...
task.eval(load_best_model = False)
```
## Func `predict`
根据config配置进行predict
**示例**
```python
import paddlehub as hub
...
task.predict()
```
## Property `is_train_phase`
判断是否处于训练阶段
## Property `is_test_phase`
判断是否处于评估阶段
## Property `is_predict_phase`
判断是否处于预测阶段
## Property `phase`
当前的phase
## Property `env`
当前环境[RunEnv]()对象
## Property `py_reader`
当前env中的PyReader对象
## Property `current_step`
当前env所执行过的step数
## Property `current_epoch`
当前env所执行过的epoch数量
## Property `main_program`
当前env对应的主Program,包含训练/评估/预测所需的计算图
## Property `startup_program`
当前env对应的初始化Program,包含初始化op
## Property `reader`
当前env下对应的数据Reader
## Property `loss`
当前env下对应的loss Variable,只在test和train phase有效
## Property `labels`
当前env下对应的label Variable,只在test和train phase有效
## Property `outputs`
当前env下对应的outputs Variable
## Property `metrics`
当前env下对应的metrics Variable,只在test和train phase有效
## Property `feed_list`
当前env下对应的feed list
## Property `fetch_list`
当前env下对应的fetch_list
# Class `hub.ImageClassifierTask`
通用的分类任务Task,继承自[BaseTask](base_task.md),该Task基于输入的特征,添加一个或多个全连接层来创建一个分类任务用于Fine-tune,度量指标为准确率,损失函数为交叉熵Loss。
```python
hub.ImageClassifierTask(
feature,
num_classes,
feed_list,
data_reader,
startup_program=None,
config=None,
hidden_units=None,
metrics_choices="default"):
```
**参数**
* feature (fluid.Variable): 输入的特征矩阵。
* num_classes (int): 分类任务的类别数量
* feed_list (list): 待feed变量的名字列表
* data_reader: 提供数据的Reader
* startup_program (fluid.Program): 存储了模型参数初始化op的Program,如果未提供,则使用fluid.default_startup_program()
* config ([RunConfig]()): 运行配置
* hidden_units (list): ImageClassifierTask最终的全连接层输出维度为label_size,是每个label的概率值。在这个全连接层之前可以设置额外的全连接层,并指定它们的输出维度,例如hidden_units=[4,2]表示先经过一层输出维度为4的全连接层,再输入一层输出维度为2的全连接层,最后再输入输出维度为label_size的全连接层。
* metrics_choices("default" or list ⊂ ["acc", "f1", "matthews"]): 任务训练过程中需要计算的评估指标,默认为“default”,此时等效于["acc"]。metrics_choices支持训练过程中同时评估多个指标,其中指定的第一个指标将被作为主指标用于判断当前得分是否为最佳分值,例如["matthews", "acc"],"matthews"将作为主指标,参与最佳模型的判断中;“acc”只计算并输出,不参与最佳模型的判断。
**返回**
`ImageClassifierTask`
**示例**
[图像分类](https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.5/demo/image_classification/img_classifier.py)
# Class `hub.MultiLabelClassifierTask`
多标签分类Task,继承自[BaseTask](base_task.md),该Task基于输入的特征,添加一个或多个全连接层来创建一个多标签分类任务用于finetune,度量指标为多个标签的平均AUC,损失函数为多个标签的平均交叉熵。
```python
hub.MultiLabelClassifierTask(
feature,
num_classes,
feed_list,
data_reader,
startup_program=None,
config=None,
hidden_units=None,
metrics_choices="default"):
```
**参数**
* feature (fluid.Variable): 输入的特征矩阵。
* num_classes (int): 多标签任务的标签数量
* feed_list (list): 待feed变量的名字列表
* data_reader: 提供数据的Reader
* startup_program (fluid.Program): 存储了模型参数初始化op的Program,如果未提供,则使用fluid.default_startup_program()
* config ([RunConfig](../config.md)): 运行配置
* hidden_units (list): MultiLabelClassifierTask最终的全连接层输出维度为[num_classes, 2],是属于各个标签的概率值。在这个全连接层之前可以设置额外的全连接层,并指定它们的输出维度,例如hidden_units=[4,2]表示先经过一层输出维度为4的全连接层,再输入一层输出维度为2的全连接层,最后再拼接上输出维度为[num_classes, 2]的全连接层。
* metrics_choices("default" or list ⊂ ["auc"]): 任务训练过程中需要计算的评估指标,默认为“default”,此时等效于["auc"]。
**返回**
`MultiLabelClassifierTask`
**示例**
[多标签分类](https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.4/demo/multi_label_classification/multi_label_classifier.py)
# Class `hub.ReadingComprehensionTask`
阅读理解任务Task,继承自[BaseTask](base_task.md),该Task基于输入的特征,添加一个全连接层来创建一个阅读理解任务用于Fine-tune,损失函数为交叉熵Loss。
```python
hub.ReadingComprehensionTask(
feature,
feed_list,
data_reader,
startup_program=None,
config=None):
```
**参数**
* feature (fluid.Variable): 输入的特征矩阵。
* feed_list (list): 待feed变量的名字列表
* data_reader: 提供数据的Reader
* startup_program (fluid.Program): 存储了模型参数初始化op的Program,如果未提供,则使用fluid.default_startup_program()
* config ([RunConfig](../config.md)): 运行配置
**返回**
`ReadingComprehensionTask`
**示例**
[阅读理解](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.4/demo/reading_comprehension)
# Class `hub.RegressionTask`
文本回归任务Task,继承自[BaseTask](base_task.md),该Task基于输入的特征,添加一个Dropout层,以及一个或多个全连接层来创建一个文本回归任务用于finetune,度量指标为准确率,损失函数为均方差损失函数。
```python
hub.RegressionTask(
feature,
feed_list,
data_reader,
startup_program=None,
config=None,
hidden_units=None,
metrics_choices="default"):
```
**参数**
* feature (fluid.Variable): 输入的特征矩阵。
* feed_list (list): 待feed变量的名字列表。
* data_reader: 提供数据的Reader。
* startup_program (fluid.Program): 存储了模型参数初始化op的Program,如果未提供,则使用fluid.default_startup_program()。
* config ([RunConfig](../config.md)): 运行配置。
* hidden_units (list): RegressionTask最终的全连接层输出维度为1,是一个回归值。在这个全连接层之前可以设置额外的全连接层,并指定它们的输出维度,例如hidden_units=[4,2]表示先经过一层输出维度为4的全连接层,再输入一层输出维度为2的全连接层,最后再输入输出维度为1的全连接层。
* metrics_choices("default" or list ⊂ ["spearman"]): 任务训练过程中需要计算的评估指标,默认为“default”,此时等效于["spearman"]。metrics_choices支持训练过程中同时评估多个指标,其中指定的第一个指标将被作为主指标用于判断当前得分是否为最佳分值,例如["spearman", "acc"],"spearman"将作为主指标,参与最佳模型的判断中;“acc”只计算并输出,不参与最佳模型的判断。
**返回**
`RegressionTask`
**示例**
[文本回归](https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.4/demo/regression/regression.py)
# Class `hub.task.RunEnv`
PaddleHub的Task通过phase来切换不同的状态(训练/评估/预测等),每个phase都有对应的一个RunEnv对象用于保存对应状态下的重要属性。对于不需要自定义Task的用户来说,本文档并不是必须的
## Property `current_step`
该环境所执行过的step数
## Property `current_epoch`
该环境所执行过的epoch数量
## Property `main_program`
该环境对应的主Program,包含训练/评估/预测所需的计算图
## Property `startup_program`
该环境对应的初始化Program,包含初始化操作的计算图
## Property `py_reader`
该环境中的PyReader对象
## Property `reader`
该环境下对应的数据Reader
## Property `loss`
该环境下对应的loss Variable
## Property `label`
该环境下对应的label Variable
## Property `outputs`
该环境下对应的outputs Variable
## Property `metrics`
该环境下对应的metrics Variable,只在test和train phase有效
## Property `is_inititalized `
该环境是否已经完成初始化
# Class `hub.task.RunState`
PaddleHub的Task在进行训练/评估/预测时,会将运行过程中的状态和输出保存到RunState对象中。用户可以从RunState对象中获取所需数据
## Property `run_time_begin`
运行的开始时间
## Property `run_step`
运行的step数
## Property `run_examples`
运行的样本数量
## Property `run_results`
运行的结果列表,数据和task中的fetch_list一一对应
## Property `run_time_used`
运行所用时间
## Property `run_speed`
运行速度
# Class `hub.SequenceLabelTask`
序列标注Task,继承自[BaseTask](base_task.md),该Task基于输入的特征,添加一个全连接层或者一个全连接层和CRF层来创建一个序列标注任务用于Fine-tune,度量指标为F1,损失函数为交叉熵Loss。
```python
hub.SequenceLabelTask(
feature,
max_seq_len,
num_classes,
feed_list,
data_reader,
startup_program=None,
config=None,
metrics_choices="default",
add_crf=False):
```
**参数**
* feature (fluid.Variable): 输入的特征矩阵
* num_classes (int): 分类任务的类别数量
* feed_list (list): 待feed变量的名字列表
* data_reader: 提供数据的Reader
* startup_program (fluid.Program): 存储了模型参数初始化op的Program,如果未提供,则使用fluid.default_startup_program()
* config ([RunConfig](../config.md)): 运行配置
* metrics_choices("default" or list ⊂ ["precision","recall","f1"]): 任务训练过程中需要计算的评估指标,默认为“default”,此时等效于["f1", "precision", "recall"]。metrics_choices支持训练过程中同时评估多个指标,其中指定的第一个指标将被作为主指标用于判断当前得分是否为最佳分值,例如["f1", "precision"],"f1"将作为主指标,参与最佳模型的判断中;"precision"只计算并输出,不参与最佳模型的判断
* add_crf (bool): 是否选择crf作为decoder,默认为false,如果add_crf=True,则网络加入crf层作为decoder
**返回**
`SequenceLabelTask`
**示例**
[序列标注](https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.4/demo/sequence_labeling/sequence_label.py)
# hub.task
在PaddleHub中,Task代表了一个Fine-tune的任务。任务中包含了执行该任务相关的Program、数据Reader、运行配置等内容。
## 基本概念
在了解Task之前,首先需要认识[RunEnv](runenv.md)[RunState](runstate.md)
Task的基本方法和属性参见[BaseTask](base_task.md)
## 预置Task
PaddleHub预置了常见任务的Task,每种Task都有自己特有的应用场景以及提供了对应的度量指标,用于适应用户的不同需求。预置的任务类型如下:
* 图像分类任务
[ImageClassifierTask](image_classify_task.md)
* 文本分类任务
[TextClassifierTask](text_classify_task.md)
* 序列标注任务
[SequenceLabelTask](sequence_label_task.md)
* 多标签分类任务
[MultiLabelClassifierTask](multi_lable_classify_task.md)
* 回归任务
[RegressionTask](regression_task.md)
* 阅读理解任务
[ReadingComprehensionTask](reading_comprehension_task.md)
## 自定义Task
如果这些Task不支持您的特定需求,您也可以通过继承BasicTask来实现自己的任务,具体实现细节参见[自定义Task](../../tutorial/how_to_define_task.md)以及[修改Task中的模型网络](../../tutorial/define_task_example.md)
## 修改Task内置方法
如果Task内置方法不满足您的需求,您可以通过Task支持的Hook机制修改方法实现,详细信息参见[修改Task内置方法](../../tutorial/hook.md)
# Class `hub.TextClassifierTask`
文本分类任务Task,继承自[BaseTask](base_task.md),该Task基于输入的特征,添加一个Dropout层,以及一个或多个全连接层来创建一个文本分类任务用于finetune,度量指标为准确率,损失函数为交叉熵Loss。
```python
hub.TextClassifierTask(
num_classes,
feed_list,
data_reader,
feature=None,
token_feature=None,
startup_program=None,
config=None,
hidden_units=None,
network=None,
metrics_choices="default"):
```
**参数**
* num_classes (int): 分类任务的类别数量
* feed_list (list): 待feed变量的名字列表
* data_reader: 提供数据的Reader,可选为ClassifyReader和LACClassifyReader。
* feature(fluid.Variable): 输入的sentence-level特征矩阵,shape应为[-1, emb_size]。默认为None。
* token_feature(fluid.Variable): 输入的token-level特征矩阵,shape应为[-1, seq_len, emb_size]。默认为None。feature和token_feature须指定其中一个。
* network(str): 文本分类任务PaddleHub预置网络,支持BOW,Bi-LSTM,CNN,DPCNN,GRU,LSTM。如果指定network,则应使用token_feature作为输入特征。其中DPCNN网络实现为[ACL2017-Deep Pyramid Convolutional Neural Networks for Text Categorization](https://www.aclweb.org/anthology/P17-1052.pdf)
* startup_program (fluid.Program): 存储了模型参数初始化op的Program,如果未提供,则使用fluid.default_startup_program()
* config ([RunConfig](../config.md)): 运行配置,如设置batch_size,epoch,learning_rate等。
* hidden_units (list): TextClassifierTask最终的全连接层输出维度为label_size,是每个label的概率值。在这个全连接层之前可以设置额外的全连接层,并指定它们的输出维度,例如hidden_units=[4,2]表示先经过一层输出维度为4的全连接层,再输入一层输出维度为2的全连接层,最后再输入输出维度为label_size的全连接层。
* metrics_choices("default" or list ⊂ ["acc", "f1", "matthews"]): 任务训练过程中需要计算的评估指标,默认为“default”,此时等效于["acc"]。metrics_choices支持训练过程中同时评估多个指标,其中指定的第一个指标将被作为主指标用于判断当前得分是否为最佳分值,例如["matthews", "acc"],"matthews"将作为主指标,参与最佳模型的判断中;“acc”只计算并输出,不参与最佳模型的判断。
**返回**
`TextClassifierTask`
**示例**
[文本分类](../../../demo/text_classification/text_cls.py)
迁移任务
==================
在PaddleHub中,Task代表了一个Fine-tune的任务。任务中包含了执行该任务相关的Program、数据Reader、运行配置等内容。
在了解Task之前,首先需要认识RunEnv和RunState。
Task的基本方法和属性参见BaseTask。
PaddleHub预置了图像分类、文本分类、序列标注、多标签分类、阅读理解、回归等迁移任务,每种任务都有自己特有的应用场景以及提供了对应的度量指标,用于适应用户的不同需求。
.. toctree::
:maxdepth: 1
:titlesonly:
hub.task.RunEnv<task/runenv>
hub.task.RunState<task/runstate>
hub.task.BaseTask<task/base_task>
hub.ImageClassifierTask<task/image_classify_task>
hub.TextClassifierTask<task/text_classify_task>
hub.SequenceLabelTask<task/sequence_label_task>
hub.MultiLabelClassifierTask<task/multi_lable_classify_task>
hub.ReadingComprehensionTask<task/reading_comprehension_task>
hub.RegressionTask<task/regression_task>
\ No newline at end of file
# 更新历史
## `v2.0.0a`
* TODO
## `v1.8.1`
*[图像分割](https://www.paddlepaddle.org.cn/hublist?filter=en_category&value=ImageSegmentation)』新增轻量级人像分割模型Humanseg,支持移动端实时分割
* 增强文本匹配任务性能,使用[EMNLP2019-Sentence-BERT](https://arxiv.org/abs/1908.10084)作为文本匹配任务网络,可同时大幅提升准确率和预测速度。配套教程:[pointwise文本语义匹配](https://aistudio.baidu.com/aistudio/projectdetail/705526)[pairwise文本语义匹配](https://aistudio.baidu.com/aistudio/projectdetail/709472)
* 修复文本分类选择F1作为评价指标,运行错误
## `v1.8.0`
* 预训练模型丰富,一键完成更多
*[文本生成](https://www.paddlepaddle.org.cn/hublist?filter=en_category&value=TextGeneration)』新增基于ERNIE-tiny和ERNIE-gen的对联和写诗生成模型,支持一键自动写诗和对对联。
*[词法分析](https://www.paddlepaddle.org.cn/hublist?filter=en_category&value=LexicalAnalysis)』新增jieba的paddle模式切词模型,可一键完成中文分词、关键词抽取等功能。
*[语义表示](https://www.paddlepaddle.org.cn/hublist?filter=en_category&value=SemanticModel)』新增基于网页、小说、新闻三类大规模文本数据的LDA主题模型及其语义相似度计算接口。
* Fine-tune API升级,提升灵活性并支持更多任务
* 新增Tokenizer API,支持更加灵活的切词、切字模式和自定义切词工具拓展。
* 新增[文本生成](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.8/demo/text_generation)任务,支持Seq2Seq任务的Fine-tuning。
* 新增文本匹配任务,支持[Pointwise](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.8/demo/pointwise_text_matching)[Pairwise](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.8/demo/pairwise_text_matching)两种文本匹配训练模式,更便捷完成语义匹配任务。
## `v1.7.0`
* 丰富预训练模型,提升应用性
......
部署预训练模型
==================
本文介绍了如何生成可用于服务化部署的模型、如何实现服务化部署以及如何获取ERNIE/BERT Embedding服务的方法。
详细信息,参考以下教程:
.. toctree::
:maxdepth: 1
Fine-tune模型转化为PaddleHub Module<finetuned_model_to_module.md>
服务化部署<serving>
文本Embedding服务<bert_service>
# PaddleHub 超参优化(AutoDL Finetuner)
## 一、简介
目前深度学习模型参数可分为两类:*模型参数 (Model Parameters)**超参数 (Hyper Parameters)*,前者是模型通过大量的样本数据进行训练学习得到的参数数据;后者则需要通过人工经验或者不断尝试找到最佳设置(如学习率、dropout_rate、batch_size等),以提高模型训练的效果。如果想得到一个效果好的深度学习神经网络模型,超参的设置非常关键。因为模型参数空间大,目前超参调整都是通过手动,依赖人工经验或者不断尝试,且不同模型、样本数据和场景下不尽相同,所以需要大量尝试,时间成本和资源成本非常浪费。PaddleHub AutoDL Finetuner可以实现自动调整超参数。
PaddleHub AutoDL Finetuner提供两种超参优化算法:
* **HAZero**: 核心思想是通过对正态分布中协方差矩阵的调整来处理变量之间的依赖关系和scaling。算法基本可以分成以下三步:
1. 采样产生新解;
2. 计算目标函数值;
3. 更新正态分布参数;
调整参数的基本思路为,调整参数使得产生更优解的概率逐渐增大。优化过程如下图:
<p align="center">
<img src="https://raw.githubusercontent.com/PaddlePaddle/PaddleHub/release/v1.3/docs/imgs/bayesian_optimization.gif" hspace='10'/> <br />
</p>
*图片来源于https://www.kaggle.com/clair14/tutorial-bayesian-optimization*
* PSHE2: 采用哈密尔顿动力系统搜索参数空间中“势能”最低的点。而最优超参数组合就是势能低点。现在想求得最优解就是要找到更新超参数组合,即如何更新超参数,才能让算法更快更好的收敛到最优解。PSHE2算法根据超参数本身历史的最优,在一定随机扰动的情况下决定下一步的更新方向。
<p align="center">
<img src="https://raw.githubusercontent.com/PaddlePaddle/PaddleHub/release/v1.3/docs/imgs/thermodynamics.gif" hspace='10'/> <br />
</p>
PaddleHub AutoDL Finetuner为了评估搜索的超参对于任务的效果,提供两种超参评估策略:
* **Full-Trail**: 给定一组超参,利用这组超参从头开始Fine-tune一个新模型,之后在验证集评估这个模型;
* **Population-Based**: 给定一组超参,若这组超参是第一轮尝试的超参组合,则从头开始Fine-tune一个新模型;否则基于前几轮已保存的较好模型,在当前的超参数组合下继续Fine-tune并评估;
## 二、准备工作
使用PaddleHub AutoDL Finetuner需要准备两个指定格式的文件:待优化的超参数信息yaml文件hparam.yaml和需要Fine-tune的python脚本train.py。
### 1. hparam.yaml
hparam给出待搜索的超参名字、类型(int或者float)、搜索范围等信息,通过这些信息构建了一个超参空间,PaddleHub将在这个空间内进行超参数的搜索,将搜索到的超参传入train.py获得评估效果,根据评估效果自动调整超参搜索方向,直到满足搜索次数。
**NOTE:**
* yaml文件的最外层级的key必须是param_list;
```
param_list:
- name : hparam1
init_value : 0.001
type : float
lower_than : 0.05
greater_than : 0.00005
...
```
* 超参名字可以任意指定,PaddleHub会将搜索到的值以指定名称传递给train.py使用;
* 优化超参策略选择HAZero时,需要提供两个以上的待优化超参;
### 2. train.py
train.py用于接受PaddleHub搜索到的超参进行一次优化过程,将优化后的效果返回。
<p align="center">
<img src="https://raw.githubusercontent.com/PaddlePaddle/PaddleHub/release/v1.3/docs/imgs/demo.png" hspace='10'/> <br />
</p>
**NOTE**:
* train.py的选项参数须包含待优化超参数,需要将超参以argparser的方式写在其中,待搜索超参数选项名字和yaml文件中的超参数名字保持一致。
* train.py须包含选项参数saved_params_dir,优化后的参数将会保存到该路径下。
* 超参评估策略选择PopulationBased时,train.py须包含选项参数model_path,自动从model_path指定的路径恢复模型
* train.py须反馈模型的评价效果(建议使用验证集或者测试集上的评价效果),通过调用`report_final_result`接口反馈,如
```python
hub.report_final_result(eval_avg_score["acc"])
```
* 输出的评价效果取值范围应为`(-∞, 1]`,取值越高,表示效果越好。
### 示例
[PaddleHub AutoDL Finetuner超参优化--NLP情感分类任务](../../demo/autofinetune_text_classification)
[PaddleHub AutoDL Finetuner超参优化--CV图像分类任务](../../demo/autofinetune_image_classification)
## 三、启动方式
**确认安装PaddleHub版本在1.3.0以上, 同时PaddleHub AutoDL Finetuner功能要求至少有一张GPU显卡可用。**
通过以下命令方式:
```shell
$ OUTPUT=result/
$ hub autofinetune train.py --param_file=hparam.yaml --gpu=0,1 --popsize=5 --round=10
--output_dir=${OUTPUT} --evaluator=fulltrail --tuning_strategy=pshe2
```
其中,选项
* `--param_file`: 必填,待优化的超参数信息yaml文件,即上述**hparam.yaml**
* `--gpu`: 必填,设置运行程序的可用GPU卡号,中间以逗号隔开,不能有空格;
* `--popsize`: 可选,设置程序运行每轮产生的超参组合数,默认为5;
* `--round`: 可选,设置程序运行的轮数,默认为10;
* `--output_dir`: 可选,设置程序运行输出结果存放目录,不指定该选项参数时,在当前运行路径下生成存放程序运行输出信息的文件夹;
* `--evaluator`: 可选,设置自动优化超参的评价效果方式,可选fulltrail和populationbased, 默认为populationbased;
* `--tuning_strategy`: 可选,设置自动优化超参算法,可选hazero和pshe2,默认为pshe2;
**NOTE:**
* 进行超参搜索时,一共会进行n轮(--round指定),每轮产生m组超参(--popsize指定)进行搜索。上一轮的优化结果决定下一轮超参数调整方向;
* 当指定GPU数量不足以同时跑一轮时,AutoDL Finetuner功能自动实现排队为了提高GPU利用率,建议卡数为刚好可以被popsize整除。如popsize=6,gpu=0,1,2,3,则每搜索一轮,AutoDL Finetuner自动起四个进程训练,所以第5/6组超参组合需要排队一次,在搜索第5/6两组超参时,会存在两张卡出现空闲等待的情况,如果设置为3张可用的卡,则可以避免这种情况的出现;
## 四、目录结构
进行自动超参搜索时,PaddleHub会生成以下目录
```
./output_dir/
├── log_file.txt
├── best_model
├── visualization
├── round0
├── round1
├── ...
└── roundn
├── log-0.info
├── log-1.info
├── ...
├── log-m.info
├── model-0
├── model-1
├── ...
└── model-m
```
其中output_dir为启动autofinetune命令时指定的根目录,目录下:
* log_file.txt记录每一轮搜索所有的超参以及整个过程中所搜索到的最优超参;
* best_model保存整个搜索训练过程中得到的最优的模型参数;
* visualization记录可视化过程的日志文件;
* round0 ~ roundn记录每一轮的数据,在每个round目录下,还存在以下文件;
* log-0.info ~ log-m.info记录每个搜索方向的日志;
* model-0 ~ model-m记录对应搜索的参数;
## 五、可视化
AutoDL Finetuner API在优化超参过程中会自动对关键训练指标进行打点,启动程序后执行下面命令。
```shell
$ visualdl --logdir ${OUTPUT}/visualization --host ${HOST_IP} --port ${PORT_NUM}
```
其中${OUTPUT}为AutoDL Finetuner输出目录,${HOST_IP}为本机IP地址,${PORT_NUM}为可用端口号,如本机IP地址为192.168.0.1,端口号8040,
用浏览器打开192.168.0.1:8040,即可看到搜索过程中各超参以及指标的变化情况。
## 六、args参数传递
PaddleHub AutoDL Finetuner 支持将train.py中的args其余不需要搜索的参数通过autofinetune remainder方式传入。这个不需要搜索的选项参数名称应该和通过hub autofinetune的传入选项参数名称保持一致。如[PaddleHub AutoDL Finetuner超参优化--NLP情感分类任务](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo/autofinetune_text_classification)示例中的max_seq_len选项,可以参照以下方式传入。
```shell
$ OUTPUT=result/
$ hub autofinetune train.py --param_file=hparam.yaml --gpu=0,1 --popsize=5 --round=10
--output_dir=${OUTPUT} --evaluator=fulltrail --tuning_strategy=pshe2 max_seq_len 128
```
## 七、其他
1. 如在使用AutoDL Finetuner功能时,输出信息中包含如下字样:
**WARNING:Program which was ran with hyperparameters as ... was crashed!**
首先根据终端上的输出信息,确定这个输出信息是在第几个round(如round 3),之后查看${OUTPUT}/round3/下的日志文件信息log.info, 查看具体出错原因。
2. PaddleHub AutoDL Finetuner功能使用过程中建议使用的GPU卡仅供PaddleHub使用,无其他任务使用。
......@@ -6,7 +6,7 @@ PaddleHub支持修改预训练模型存放路径:
* 如已设置`${HUB_HOME}`环境变量,则预训练模型、配置等文件都存放在`${HUB_HOME}`指示的路径下
* 如未设置`${HUB_HOME}`环境变量,则存放在`$HOME`指示的路径下
目前命令行支持以下12个命令:
目前命令行支持以下11个命令:
## `hub install`
......@@ -22,14 +22,7 @@ PaddleHub支持修改预训练模型存放路径:
## `hub download`
用于下载百度提供的Module
`选项`
* `--output_path`:用于指定存放下载文件的目录,默认为当前目录
* `--uncompress`:是否对下载的压缩包进行解压,填写true或者false,默认false(不解压)
* `--type`:指定下载的资源类型,当指定Model时,download只会下载Model的资源。默认为All,此时会优先搜索Module资源,如果没有相关的Module资源,则搜索Model
用于下载PaddleHub提供的Module
## `hub search`
......@@ -58,26 +51,6 @@ PaddleHub支持修改预训练模型存放路径:
PaddleHub在使用过程中会产生一些缓存数据,这部分数据默认存放在${HUB_HOME}/.paddlehub/cache目录下,用户可以通过clear命令来清空缓存
## `hub autofinetune`
用于自动调整Fine-tune任务的超参数,具体使用详情参考[PaddleHub AutoDL Finetuner使用教程](./autofinetune.md)
`选项`
* `--param_file`: 需要搜索的超参数信息yaml文件
* `--gpu`: 设置运行程序的可用GPU卡号,中间以逗号隔开,不能有空格
* `--popsize`: 设置程序运行每轮产生的超参组合数,默认为5
* `--round`: 设置程序运行的轮数,默认是10
* `--output_dir`: 设置程序运行输出结果存放目录,可选,不指定该选项参数时,在当前运行路径下生成存放程序运行输出信息的文件夹
* `--evaluator`: 设置自动搜索超参的评价效果方式,可选fulltrail和populationbased, 默认为populationbased
* `--strategy`: 设置自动搜索超参算法,可选hazero和pshe2,默认为hazero
## `hub config`
用于查看和设置paddlehub相关设置,包括对server地址、日志级别的设置:
......@@ -88,7 +61,9 @@ PaddleHub在使用过程中会产生一些缓存数据,这部分数据默认
* `hub config server==[address]`: 设置当前paddlehub-server地址为[address],paddlehub客户端从此地址获取模型信息
* `hub config log==[level]`: 设置当前日志级别为[level], 可选值为critical, error, warning, info, debug, nolog, 从左到右优先级从高到低,nolog表示不显示日志信息
* `hub config log.level==[level]`: 设置当前日志级别为[level], 可选值为CRITICAL, ERROR, WARNING, EVAL, TRAIN, INFO, DEBUG, 从左到右优先级从高到低
* `hub config log.enable==True|False`: 设置当日志是否可用
## `hub serving`
......@@ -96,7 +71,7 @@ PaddleHub在使用过程中会产生一些缓存数据,这部分数据默认
**NOTE:**
在PaddleHub中,Module表示一个`可执行的神经网络模型`,一个Module可以支持直接命令行预测,也可以配合PaddleHub Finetune API,通过少量代码实现迁移学习。不是所有的Module都支持命令行预测 (例如BERT/ERNIE Transformer类模型,一般需要搭配任务进行finetune),也不是所有的Module都可用于finetune(例如LAC词法分析模型,我们不建议用户用于finetune)。
在PaddleHub中,Module表示一个`可执行的预训练模型`,一个Module可以支持直接命令行预测,也可以配合PaddleHub Finetune API,通过少量代码实现迁移学习。不是所有的Module都支持命令行预测 (例如BERT/ERNIE Transformer类模型,一般需要搭配任务进行finetune),也不是所有的Module都可用于finetune(例如LAC词法分析模型,我们不建议用户用于finetune)。
PaddleHub尽量简化了用户在使用命令行预测时的理解成本,一般来讲,我们将预测分为NLP和CV两大类
......
# 如何修改Task中的模型网络
在应用中,用户需要更换迁移网络结构以调整模型在数据集上的性能。根据[如何自定义Task](./how_to_define_task.md),本教程展示如何修改Task中的默认网络。
以序列标注任务为例,本教程展示如何修改默认网络结构。SequenceLabelTask提供了两种网络选择,一种是FC网络,一种是FC+CRF网络。
此时如果想在这基础之上,添加LSTM网络,组成BiLSTM+CRF的一种序列标注任务常用网络结构。
此时,需要定义一个Task,继承自SequenceLabelTask,并改写其中build_net()方法。
下方代码示例写了一个BiLSTM+CRF的网络。代码如下:
```python
class SequenceLabelTask_BiLSTMCRF(SequenceLabelTask):
def _build_net(self):
"""
自定义序列标注迁移网络结构BiLSTM+CRF
"""
self.seq_len = fluid.layers.data(
name="seq_len", shape=[1], dtype='int64', lod_level=0)
if version_compare(paddle.__version__, "1.6"):
self.seq_len_used = fluid.layers.squeeze(self.seq_len, axes=[1])
else:
self.seq_len_used = self.seq_len
if self.add_crf:
# 迁移网络为BiLSTM+CRF
# 去padding
unpad_feature = fluid.layers.sequence_unpad(
self.feature, length=self.seq_len_used)
# bilstm层
hid_dim = 128
fc0 = fluid.layers.fc(input=unpad_feature, size=hid_dim * 4)
rfc0 = fluid.layers.fc(input=unpad_feature, size=hid_dim * 4)
lstm_h, c = fluid.layers.dynamic_lstm(
input=fc0, size=hid_dim * 4, is_reverse=False)
rlstm_h, c = fluid.layers.dynamic_lstm(
input=rfc0, size=hid_dim * 4, is_reverse=True)
# 拼接lstm
lstm_concat = fluid.layers.concat(input=[lstm_h, rlstm_h], axis=1)
self.emission = fluid.layers.fc(
size=self.num_classes,
input=lstm_concat,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.Uniform(low=-0.1, high=0.1),
regularizer=fluid.regularizer.L2DecayRegularizer(
regularization_coeff=1e-4)))
size = self.emission.shape[1]
fluid.layers.create_parameter(
shape=[size + 2, size], dtype=self.emission.dtype, name='crfw')
# CRF层
self.ret_infers = fluid.layers.crf_decoding(
input=self.emission, param_attr=fluid.ParamAttr(name='crfw'))
ret_infers = fluid.layers.assign(self.ret_infers)
# 返回预测值,list类型
return [ret_infers]
else:
# 迁移网络为FC
self.logits = fluid.layers.fc(
input=self.feature,
size=self.num_classes,
num_flatten_dims=2,
param_attr=fluid.ParamAttr(
name="cls_seq_label_out_w",
initializer=fluid.initializer.TruncatedNormal(scale=0.02)),
bias_attr=fluid.ParamAttr(
name="cls_seq_label_out_b",
initializer=fluid.initializer.Constant(0.)))
self.ret_infers = fluid.layers.reshape(
x=fluid.layers.argmax(self.logits, axis=2), shape=[-1, 1])
logits = self.logits
logits = fluid.layers.flatten(logits, axis=2)
logits = fluid.layers.softmax(logits)
self.num_labels = logits.shape[1]
# 返回预测值,list类型
return [logits]
```
以上代码通过继承PaddleHub已经内置的Task,改写其中_build_net方法即可实现自定义迁移网络结构。
# Fine-tune保存的模型如何转化为一个PaddleHub Module
## 模型基本信息
本示例以模型ERNIE Tiny在数据集ChnSentiCorp上完成情感分类Fine-tune任务后保存的模型转化为一个PaddleHub Module,Module的基本信息如下:
```yaml
name: ernie_tiny_finetuned
version: 1.0.0
summary: ERNIE tiny which was fine-tuned on the chnsenticorp dataset.
author: anonymous
author_email:
type: nlp/semantic_model
```
**本示例代码可以参考[finetuned_model_to_module](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo/text_classification/finetuned_model_to_module)**
Module存在一个接口predict,用于接收带预测,并给出文本的情感倾向(正面/负面),支持python接口调用和命令行调用。
```python
import paddlehub as hub
ernie_tiny_finetuned = hub.Module(name="ernie_tiny_finetuned")
ernie_tiny_finetuned.predcit(data=[["这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般"], ["交通方便;环境很好;服务态度很好 房间较小"],
["19天硬盘就罢工了~~~算上运来的一周都没用上15天~~~可就是不能换了~~~唉~~~~你说这算什么事呀~~~"]])
```
## Module创建
### step 1. 创建必要的目录与文件
创建一个finetuned_model_to_module的目录,并在finetuned_model_to_module目录下分别创建__init__.py、module.py,其中
|文件名|用途|
|-|-|
|\_\_init\_\_.py|空文件|
|module.py|主模块,提供Module的实现代码|
|ckpt文件|利用PaddleHub Fine-tune得到的ckpt文件夹,其中必须包含best_model文件|
```cmd
➜ tree finetuned_model_to_module
finetuned_model_to_module/
├── __init__.py
├── ckpt_chnsenticorp
│   ├── ***
│   ├── best_model
│   │   ├── ***
└── module.py
```
### step 2. 编写Module处理代码
module.py文件为Module的入口代码所在,我们需要在其中实现预测逻辑。
#### step 2_1. 引入必要的头文件
```python
import os
import numpy as np
from paddlehub.common.logger import logger
from paddlehub.module.module import moduleinfo, serving
import paddlehub as hub
```
#### step 2_2. 定义ERNIE_Tiny_Finetuned类
module.py中需要有一个继承了hub.Module的类存在,该类负责实现预测逻辑,并使用moduleinfo填写基本信息。当使用hub.Module(name="ernie_tiny_finetuned")加载Module时,PaddleHub会自动创建ERNIE_Tiny_Finetuned的对象并返回。
```python
@moduleinfo(
name="ernie_tiny_finetuned",
version="1.0.0",
summary="ERNIE tiny which was fine-tuned on the chnsenticorp dataset.",
author="anonymous",
author_email="",
type="nlp/semantic_model")
class ERNIETinyFinetuned(hub.Module):
...
```
#### step 2_3. 执行必要的初始化
```python
def _initialize(self,
ckpt_dir="ckpt_chnsenticorp",
num_class=2,
max_seq_len=128,
use_gpu=False,
batch_size=1):
self.ckpt_dir = os.path.join(self.directory, ckpt_dir)
self.num_class = num_class
self.MAX_SEQ_LEN = max_seq_len
self.params_path = os.path.join(self.ckpt_dir, 'best_model')
if not os.path.exists(self.params_path):
logger.error(
"%s doesn't contain the best_model file which saves the best parameters as fietuning."
)
exit()
# Load Paddlehub ERNIE Tiny pretrained model
self.module = hub.Module(name="ernie_tiny")
inputs, outputs, program = self.module.context(
trainable=True, max_seq_len=max_seq_len)
self.vocab_path = self.module.get_vocab_path()
# Download dataset and use accuracy as metrics
# Choose dataset: GLUE/XNLI/ChinesesGLUE/NLPCC-DBQA/LCQMC
# metric should be acc, f1 or matthews
metrics_choices = ["acc"]
# For ernie_tiny, it use sub-word to tokenize chinese sentence
# If not ernie tiny, sp_model_path and word_dict_path should be set None
reader = hub.reader.ClassifyReader(
vocab_path=self.module.get_vocab_path(),
max_seq_len=max_seq_len,
sp_model_path=self.module.get_spm_path(),
word_dict_path=self.module.get_word_dict_path())
# Construct transfer learning network
# Use "pooled_output" for classification tasks on an entire sentence.
# Use "sequence_output" for token-level output.
pooled_output = outputs["pooled_output"]
# Setup feed list for data feeder
# Must feed all the tensor of module need
feed_list = [
inputs["input_ids"].name,
inputs["position_ids"].name,
inputs["segment_ids"].name,
inputs["input_mask"].name,
]
# Setup runing config for PaddleHub Finetune API
config = hub.RunConfig(
use_data_parallel=False,
use_cuda=use_gpu,
batch_size=batch_size,
checkpoint_dir=self.ckpt_dir,
strategy=hub.AdamWeightDecayStrategy())
# Define a classfication finetune task by PaddleHub's API
self.cls_task = hub.TextClassifierTask(
data_reader=reader,
feature=pooled_output,
feed_list=feed_list,
num_classes=self.num_class,
config=config,
metrics_choices=metrics_choices)
```
初始化过程即为Fine-tune时创建Task的过程。
**NOTE:**
1. 执行类的初始化不能使用默认的__init__接口,而是应该重载实现_initialize接口。对象默认内置了directory属性,可以直接获取到Module所在路径。
2. 使用Fine-tune保存的模型预测时,无需加载数据集Dataset,即Reader中的dataset参数可为None。
#### step 3_4. 完善预测逻辑
```python
def predict(self, data, return_result=False, accelerate_mode=True):
"""
Get prediction results
"""
run_states = self.cls_task.predict(
data=data,
return_result=return_result,
accelerate_mode=accelerate_mode)
results = [run_state.run_results for run_state in run_states]
prediction = []
for batch_result in results:
# get predict index
batch_result = np.argmax(batch_result, axis=2)[0]
batch_result = batch_result.tolist()
prediction += batch_result
return prediction
```
#### step 3_5. 支持serving调用
如果希望Module可以支持PaddleHub Serving部署预测服务,则需要将预测接口predcit加上serving修饰(`@serving`),接口负责解析传入数据并进行预测,将结果返回。
如果不需要提供PaddleHub Serving部署预测服务,则可以不需要加上serving修饰。
```python
@serving
def predict(self, data, return_result=False, accelerate_mode=True):
"""
Get prediction results
"""
run_states = self.cls_task.predict(
data=data,
return_result=return_result,
accelerate_mode=accelerate_mode)
results = [run_state.run_results for run_state in run_states]
prediction = []
for batch_result in results:
# get predict index
batch_result = np.argmax(batch_result[0], axis=1)
batch_result = batch_result.tolist()
prediction += batch_result
return prediction
```
### 完整代码
* [module.py](https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.7/demo/text_classification/finetuned_model_to_module/module.py)
* [__init__.py](https://github.com/PaddlePaddle/PaddleHub/blob/release/v1.7/demo/text_classification/finetuned_model_to_module/__init__.py)
**NOTE:** `__init__.py`是空文件
## 测试步骤
完成Module编写后,我们可以通过以下方式测试该Module
### 调用方法1
将Module安装到本机中,再通过Hub.Module(name=...)加载
```shell
hub install finetuned_model_to_module
```
安装成功会显示**Successfully installed ernie_tiny_finetuned**
```python
import paddlehub as hub
import numpy as np
ernie_tiny = hub.Module(name="ernie_tiny_finetuned")
# Data to be prdicted
data = [["这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般"], ["交通方便;环境很好;服务态度很好 房间较小"],
["19天硬盘就罢工了~~~算上运来的一周都没用上15天~~~可就是不能换了~~~唉~~~~你说这算什么事呀~~~"]]
predictions = ernie_tiny.predict(data=data)
for index, text in enumerate(data):
print("%s\tpredict=%s" % (data[index][0], predictions[index]))
```
### 调用方法2
直接通过Hub.Module(directory=...)加载
```python
import paddlehub as hub
import numpy as np
ernie_tiny_finetuned = hub.Module(directory="finetuned_model_to_module/")
# Data to be prdicted
data = [["这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般"], ["交通方便;环境很好;服务态度很好 房间较小"],
["19天硬盘就罢工了~~~算上运来的一周都没用上15天~~~可就是不能换了~~~唉~~~~你说这算什么事呀~~~"]]
predictions = ernie_tiny.predict(data=data)
for index, text in enumerate(data):
print("%s\tpredict=%s" % (data[index][0], predictions[index]))
```
### 调用方法3
将finetuned_model_to_module作为路径加到环境变量中,直接加载ERNIETinyFinetuned对象
```shell
export PYTHONPATH=finetuned_model_to_module:$PYTHONPATH
```
```python
from finetuned_model_to_module.module import ERNIETinyFinetuned
import numpy as np
# Data to be prdicted
data = [["这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般"], ["交通方便;环境很好;服务态度很好 房间较小"],
["19天硬盘就罢工了~~~算上运来的一周都没用上15天~~~可就是不能换了~~~唉~~~~你说这算什么事呀~~~"]]
predictions = ERNIETinyFinetuned.predict(data=data)
for index, text in enumerate(data):
print("%s\tpredict=%s" % (data[index][0], predictions[index]))
```
### PaddleHub Serving调用方法
**第一步:启动预测服务**
```shell
hub serving start -m ernie_tiny_finetuned
```
**第二步:发送请求,获取预测结果**
通过如下脚本既可以发送请求:
```python
# coding: utf8
import requests
import json
# 待预测文本
texts = [["这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般"], ["交通方便;环境很好;服务态度很好 房间较小"],
["19天硬盘就罢工了~~~算上运来的一周都没用上15天~~~可就是不能换了~~~唉~~~~你说这算什么事呀~~~"]]
# key为'data', 对应着预测接口predict的参数data
data = {'data': texts}
# 指定模型为ernie_tiny_finetuned并发送post请求,且请求的headers为application/json方式
url = "http://127.0.0.1:8866/predict/ernie_tiny_finetuned"
headers = {"Content-Type": "application/json"}
r = requests.post(url=url, headers=headers, data=json.dumps(data))
# 打印预测结果
print(json.dumps(r.json(), indent=4, ensure_ascii=False))
```
关与PaddleHub Serving更多信息参见[Hub Serving教程](./serving.md)以及[Demo](https://github.com/PaddlePaddle/PaddleHub/tree/release/v1.7/demo/serving)
# 如何修改Task内置方法?
了解如何修改Task内置方法,我们首先了解下Task中的事件。
Task定义了[组网事件](./how_to_define_task.md)[运行事件](./how_to_define_task.md)。其中运行事件的工作流程如下图。
![](../imgs/task_event_workflow.png)
**NOTE:**
* 图中提到的运行设置config参见[RunConfig说明](../reference/config.md)
* "finetune_start_event","finetune_end_event","predict_start_event","predict_end_event",
"eval_start_event","eval_end_event"等事件是用于打印相应阶段的日志信息。"save_ckpt_interval_event"事件用于保存当前训练的模型参数。"log_interval_event"事件用于计算模型评价指标以及可视化这些指标。
如果您需要对图中提到的事件的具体实现进行修改,可以通过Task提供的事件回调hook机制进行改写。
如你想要改变任务评价指标,如下示例中将PaddleHub默认的accuracy评价指标改为F1评价指标。同时还想用自定义的可视化工具可视化模型训练过程,如下示例将可视化工具改写为tb-paddle。则你需要改写评估方法log_interval_event。这时候你可以用Hook实现。具体使用方法如下:
```python
import numpy as np
def calculate_f1_np(preds, labels):
# 计算F1分数
# preds:预测label
# labels: 真实labels
# 返回F1分数
preds = np.array(preds)
labels = np.array(labels)
tp = np.sum((labels == 1) & (preds == 1))
tn = np.sum((labels == 0) & (preds == 0))
fp = np.sum((labels == 0) & (preds == 1))
fn = np.sum((labels == 1) & (preds == 0))
p = tp / (tp + fp) if (tp + fp) else 0
r = tp / (tp + fn) if (tp + fn) else 0
f1 = (2 * p * r) / (p + r) if p + r else 0
return f1
# 自定义评估方法实现
def calculate_metrics(self, run_states):
# run_states: list类型,每个元素是一个RunState对象,指明了该step的运行状态
# 返回评估得分,平均损失值和平局运行速度
loss_sum = acc_sum = run_examples = 0
run_step = run_time_used = 0
all_labels = np.array([])
all_infers = np.array([])
for run_state in run_states:
run_examples += run_state.run_examples
run_step += run_state.run_step
loss_sum += np.mean(
run_state.run_results[-1]) * run_state.run_examples
acc_sum += np.mean(
run_state.run_results[2]) * run_state.run_examples
np_labels = run_state.run_results[0]
np_infers = run_state.run_results[1]
all_labels = np.hstack((all_labels, np_labels.reshape([-1])))
all_infers = np.hstack((all_infers, np_infers.reshape([-1])))
run_time_used = time.time() - run_states[0].run_time_begin
avg_loss = loss_sum / run_examples
run_speed = run_step / run_time_used
scores = OrderedDict()
f1 = calculate_f1_np(all_infers, all_labels)
scores["f1"] = f1
return scores, avg_loss, run_speed
# 利用自定义可视化工具tb-paddle记录训练过程中的损失值,评估指标等
from tb_paddle import SummaryWriter
tb_writer = SummaryWriter("PATH/TO/LOG")
def record_value(evaluation_scores, loss, s)
tb_writer.add_scalar(
tag="Loss_{}".format(self.phase),
scalar_value=loss,
global_step=self._envs['train'].current_step)
log_scores = ""
for metric in evaluation_scores:
self.tb_writer.add_scalar(
tag="{}_{}".format(metric, self.phase),
scalar_value=scores[metric],
global_step=self._envs['train'].current_step)
log_scores += "%s=%.5f " % (metric, scores[metric])
print("step %d / %d: loss=%.5f %s[step/sec: %.2f]" %
(self.current_step, self.max_train_steps, avg_loss,
log_scores, run_speed))
# 改写_log_interval_event实现
def new_log_interval_event(self, run_states):
# 改写的事件方法,参数列表务必与PaddleHub内置的相应方法保持一致
print("This is the new log_interval_event!")
scores, avg_loss, run_speed = calculate_metrics(run_states)
record_value(scores, avg_loss, run_speed)
# 利用Hook改写PaddleHub内置_log_interval_event实现,需要2步(假设task已经创建好)
# 1.删除PaddleHub内置_log_interval_event实现
# hook_type:你想要改写的事件hook类型
# name:hook名字,“default”表示PaddleHub内置_log_interval_event实现
task.delete_hook(hook_type="log_interval_event", name="default")
# 2.增加自定义_log_interval_event实现(new_log_interval_event)
# hook_type:你想要改写的事件hook类型
# name: hook名字
# func:自定义改写的方法
task.add_hook(hook_type="log_interval_event", name="new_log_interval_event", func=new_log_interval_event)
# 输出hook信息
task.hook_info()
```
**NOTE:**
* 关于上述提到的run_states参见[RunEnv说明](../reference/task/runenv.md)
* tb-paddle详细信息参见[官方文档](https://github.com/ShenYuhan/tb-paddle)
* 改写的事件方法,参数列表务必与PaddleHub内置的相应方法保持一致。
* 只支持改写/删除以下事件hook类型:
"build_env_start_event","build_env_end_event","finetune_start_event","finetune_end_event",
"predict_start_event","predict_end_event","eval_start_event","eval_end_event",
"log_interval_event","save_ckpt_interval_event","eval_interval_event","run_step_event"。
* 如果想要改写组网事件,Hook不支持。改写组网事件参见[自定义Task](./how_to_define_task.md)
* 如何创建Task,参见[PaddleHub迁移学习示例](../../demo)
# 自定义Task
本节内容讲述如何实现自定义Task。在了解本节内容之前,您需要先了解以下内容:
* 任务基类[BasicTask](../reference/task/base_task.md)
* 运行状态[RunState](../reference/task/runstate.md)
* 运行环境[RunEnv](../reference/task/runenv.md)
当自定义一个Task时,我们并不需要重新实现eval、finetune等通用接口。一般来讲,新的Task与其他Task的区别在于
* 网络结构
* 评估指标
这两者的差异可以通过重载BasicTask的组网事件和运行事件来实现
## 组网事件
BasicTask定义了一系列的组网事件,当需要构建对应的Fluid Program时,相应的事件会被调用。通过重载实现对应的组网函数,用户可以实现自定义网络
### `_build_net`
进行前向网络组网的函数,用户需要自定义实现该函数,函数需要返回对应预测结果的Variable list
```python
# 代码示例
def _build_net(self):
cls_feats = self.feature
if self.hidden_units is not None:
for n_hidden in self.hidden_units:
cls_feats = fluid.layers.fc(
input=cls_feats, size=n_hidden, act="relu")
logits = fluid.layers.fc(
input=cls_feats,
size=self.num_classes,
param_attr=fluid.ParamAttr(
name="cls_out_w",
initializer=fluid.initializer.TruncatedNormal(scale=0.02)),
bias_attr=fluid.ParamAttr(
name="cls_out_b", initializer=fluid.initializer.Constant(0.)),
act="softmax")
return [logits]
```
### `_add_label`
添加label的函数,用户需要自定义实现该函数,函数需要返回对应输入label的Variable list
```python
# 代码示例
def _add_label(self):
return [fluid.layers.data(name="label", dtype="int64", shape=[1])]
```
### `_add_metrics`
添加度量指标的函数,用户需要自定义实现该函数,函数需要返回对应度量指标的Variable list
```python
# 代码示例
def _add_metrics(self):
return [fluid.layers.accuracy(input=self.outputs[0], label=self.label)]
```
## 运行事件
BasicTask定义了一系列的运行时回调事件,在特定的时机时触发对应的事件,在自定的Task中,通过重载实现对应的回调函数,用户可以实现所需的功能
### `_build_env_start_event`
当需要进行一个新的运行环境构建时,该事件被触发。通过重载实现该函数,用户可以在一个环境开始构建前进行对应操作,例如写日志
```python
# 代码示例
def _build_env_start_event(self):
logger.info("Start to build env {}".format(self.phase))
```
### `_build_env_end_event`
当一个新的运行环境构建完成时,该事件被触发。通过继承实现该函数,用户可以在一个环境构建结束后进行对应操作,例如写日志
```python
# 代码示例
def _build_env_end_event(self):
logger.info("End of build env {}".format(self.phase))
```
### `_finetune_start_event`
当开始一次finetune时,该事件被触发。通过继承实现该函数,用户可以在开始一次finetune操作前进行对应操作,例如写日志
```python
# 代码示例
def _finetune_start_event(self):
logger.info("PaddleHub finetune start")
```
### `_finetune_end_event`
当结束一次finetune时,该事件被触发。通过继承实现该函数,用户可以在结束一次finetune操作后进行对应操作,例如写日志
```python
# 代码示例
def _finetune_end_event(self):
logger.info("PaddleHub finetune finished.")
```
### `_eval_start_event`
当开始一次evaluate时,该事件被触发。通过继承实现该函数,用户可以在开始一次evaluate操作前进行对应操作,例如写日志
```python
# 代码示例
def _eval_start_event(self):
logger.info("Evaluation on {} dataset start".format(self.phase))
```
### `_eval_end_event`
当结束一次evaluate时,该事件被触发。通过继承实现该函数,用户可以在完成一次evaluate操作后进行对应操作,例如计算运行速度、评估指标等
```python
# 代码示例
def _eval_end_event(self, run_states):
run_step = 0
for run_state in run_states:
run_step += run_state.run_step
run_time_used = time.time() - run_states[0].run_time_begin
run_speed = run_step / run_time_used
logger.info("[%s dataset evaluation result] [step/sec: %.2f]" %
(self.phase, run_speed))
```
* `run_states`: 一个list对象,list中的每一个元素都是RunState对象,该list包含了整个评估过程的状态数据。
### `_predict_start_event`
当开始一次predict时,该事件被触发。通过继承实现该函数,用户可以在开始一次predict操作前进行对应操作,例如写日志
```python
# 代码示例
def _predict_start_event(self):
logger.info("PaddleHub predict start")
```
### `_predict_end_event`
当结束一次predict时,该事件被触发。通过继承实现该函数,用户可以在结束一次predict操作后进行对应操作,例如写日志
```python
# 代码示例
def _predict_end_event(self):
logger.info("PaddleHub predict finished.")
```
### `_log_interval_event`
调用*finetune* 或者 *finetune_and_eval*接口时,每当命中用户设置的日志打印周期时([RunConfig.log_interval](../reference/config.md))。通过继承实现该函数,用户可以在finetune过程中定期打印所需数据,例如计算运行速度、loss、准确率等
```python
# 代码示例
def _log_interval_event(self, run_states):
avg_loss, avg_acc, run_speed = self._calculate_metrics(run_states)
self.env.loss_scalar.add_record(self.current_step, avg_loss)
self.env.acc_scalar.add_record(self.current_step, avg_acc)
logger.info("step %d: loss=%.5f acc=%.5f [step/sec: %.2f]" %
(self.current_step, avg_loss, avg_acc, run_speed))
```
* `run_states`: 一个list对象,list中的每一个元素都是RunState对象,该list包含了整个从上一次该事件被触发到本次被触发的状态数据
### `_save_ckpt_interval_event`
调用*finetune* 或者 *finetune_and_eval*接口时,每当命中用户设置的保存周期时([RunConfig.save_ckpt_interval](../reference/config.md)),该事件被触发。通过继承实现该函数,用户可以在定期保存checkpoint
```python
# 代码示例
def _save_ckpt_interval_event(self):
self.save_checkpoint(self.current_epoch, self.current_step)
```
### `_eval_interval_event`
调用*finetune_and_eval*接口时,每当命中用户设置的评估周期时([RunConfig.eval_interval](../reference/config.md)),该事件被触发。通过继承实现该函数,用户可以实现自定义的评估指标计算
```python
# 代码示例
def _eval_interval_event(self):
self.eval(phase="dev")
```
### `_run_step_event`
调用*eval**predict**finetune_and_eval**finetune*等接口时,每执行一次计算,该事件被触发。通过继承实现该函数,用户可以实现所需操作
```python
# 代码示例
def _run_step_event(self, run_state):
...
```
* `run_state`: 一个RunState对象,指明了该step的运行状态
此差异已折叠。
# 自定义数据
训练一个新任务时,如果从零开始训练时,这将是一个耗时的过程,并且效果可能达不到理想的效果,此时您可以利用PaddleHub提供的预训练模型进行具体任务的Fine-tune。您只需要对自定义数据进行相应的预处理,随后输入预训练模型中,即可得到相应的结果。
训练一个新任务时,如果从零开始训练时,这将是一个耗时的过程,并且效果可能达不到理想的效果,此时您可以利用PaddleHub提供的预训练模型进行具体任务的Fine-tune。您只需要对自定义数据进行相应的预处理,随后输入预训练模型中,即可得到相应的结果。请参考如下内容设置数据集的结构。
## 一、NLP类任务如何自定义数据
## 一、图像分类数据集
本文以预训练模型ERNIE对文本分类任务进行Fine-tune为例,说明如何利用PaddleHub适配自定义数据完成Fine-tune。
## 二、图像着色数据集
### 数据准备
```
├─data: 数据目录
  ├─train.tsv 训练集
  ├─dev.tsv 验证集
  ├─test.tsv 测试集
  └─……
```
相应的数据格式为第一列是文本内容text_a,第二列为文本类别label。列与列之间以Tab键分隔。数据集文件第一行为`text_a label`(中间以Tab键分隔)。
如果您有两个输入文本text_a、text_b,则第一列为第一个输入文本text_a, 第二列应为第二个输入文本text_b,第三列文本类别label。列与列之间以Tab键分隔。数据集第一行为`text_a text_b label`(中间以Tab键分隔)。
```text
text_a label
15.4寸笔记本的键盘确实爽,基本跟台式机差不多了,蛮喜欢数字小键盘,输数字特方便,样子也很美观,做工也相当不错 1
房间太小。其他的都一般。。。。。。。。。 0
1.接电源没有几分钟,电源适配器热的不行. 2.摄像头用不起来. 3.机盖的钢琴漆,手不能摸,一摸一个印. 4.硬盘分区不好办. 0
```
### 自定义数据加载
加载文本类自定义数据集,用户仅需要继承基类BaseNLPDatast,修改数据集存放地址以及类别即可。具体使用如下:
**NOTE:**
* 数据集文件编码格式建议为utf8格式。
* 如果相应的数据集文件没有上述的列说明,如train.tsv文件没有第一行的`text_a label`,则train_file_with_header=False。
* 如果您还有预测数据(没有文本类别),可以将预测数据存放在predict.tsv文件,文件格式和train.tsv类似。去掉label一列即可。
* 分类任务中,数据集的label必须从0开始计数
```python
from paddlehub.dataset.base_nlp_dataset import BaseNLPDataset
class DemoDataset(BaseNLPDataset):
"""DemoDataset"""
def __init__(self):
# 数据集存放位置
self.dataset_dir = "path/to/dataset"
super(DemoDataset, self).__init__(
base_path=self.dataset_dir,
train_file="train.tsv",
dev_file="dev.tsv",
test_file="test.tsv",
# 如果还有预测数据(不需要文本类别label),可以放在predict.tsv
predict_file="predict.tsv",
train_file_with_header=True,
dev_file_with_header=True,
test_file_with_header=True,
predict_file_with_header=True,
# 数据集类别集合
label_list=["0", "1"])
dataset = DemoDataset()
```
之后,您就可以通过DemoDataset()获取自定义数据集了。进而配合ClassifyReader以及预训练模型如ERNIE完成文本分类任务。
## 二、CV类任务如何自定义数据
利用PaddleHub迁移CV类任务使用自定义数据时,用户需要自己切分数据集,将数据集且分为训练集、验证集和测试集。
### 数据准备
需要三个文本文件来记录对应的图片路径和标签,此外还需要一个标签文件用于记录标签的名称。
```
├─data: 数据目录
  ├─train_list.txt:训练集数据列表
  ├─test_list.txt:测试集数据列表
  ├─validate_list.txt:验证集数据列表
├─label_list.txt:标签列表
  └─……
```
训练/验证/测试集的数据列表文件的格式如下
```
图片1路径 图片1标签
图片2路径 图片2标签
...
```
label_list.txt的格式如下
```
分类1名称
分类2名称
...
```
示例:
[DogCat数据集](../reference/dataset.md)为示例,train_list.txt/test_list.txt/validate_list.txt内容如下示例
```
cat/3270.jpg 0
cat/646.jpg 0
dog/12488.jpg 1
```
label_list.txt内容如下:
```
cat
dog
```
### 自定义数据加载
加载图像类自定义数据集,用户仅需要继承基类BaseCVDatast,修改数据集存放地址即可。具体使用如下:
**NOTE:**
* 数据集文件编码格式建议为utf8格式。
* dataset_dir为数据集实际路径,需要填写全路径,以下示例以`/test/data`为例。
* 训练/验证/测试集的数据列表文件中的图片路径需要相对于dataset_dir的相对路径,例如图片的实际位置为`/test/data/dog/dog1.jpg`。base_path为`/test/data`,则文件中填写的路径应该为`dog/dog1.jpg`
* 如果您还有预测数据(没有文本类别),可以将预测数据存放在predict_list.txt文件,文件格式和train_list.txt类似。去掉label一列即可
* 如果您的数据集类别较少,可以不用定义label_list.txt,可以选择定义label_list=["数据集所有类别"]。
* 分类任务中,数据集的label必须从0开始计数
```python
from paddlehub.dataset.base_cv_dataset import BaseCVDataset
class DemoDataset(BaseCVDataset):
def __init__(self):
# 数据集存放位置
self.dataset_dir = "/test/data"
super(DemoDataset, self).__init__(
base_path=self.dataset_dir,
train_list_file="train_list.txt",
validate_list_file="validate_list.txt",
test_list_file="test_list.txt",
predict_file="predict_list.txt",
label_list_file="label_list.txt",
# label_list=["数据集所有类别"])
dataset = DemoDataset()
```
## 三、风格迁移数据集
......@@ -35,9 +35,9 @@ import numpy as np
import scipy
from scipy.spatial import distance
from paddlehub.reader.tokenization import load_vocab
import paddle.fluid as fluid
import paddle
import paddlehub as hub
from paddlehub.text.utils import load_vocab
raw_data = [
["驾驶违章一次扣12分用两个驾驶证处理可以吗", "一次性扣12分的违章,能用不满十二分的驾驶证扣分吗"],
......@@ -79,9 +79,10 @@ vocab = load_vocab(module.get_vocab_path())
word_ids = inputs["word_ids"]
embedding = outputs["word_embs"]
place = fluid.CPUPlace()
exe = fluid.Executor(place)
feeder = fluid.DataFeeder(feed_list=[word_ids], place=place)
paddle.enable_static()
place = paddle.CPUPlace()
exe = paddle.static.Executor(place)
feeder = paddle.fluid.DataFeeder(feed_list=[word_ids], place=place)
for item in processed_data:
text_a = convert_tokens_to_ids(vocab, item[0])
......
# PaddleHub 迁移学习与ULMFiT微调策略
## 一、简介
迁移学习(Transfer Learning)顾名思义就是将模型在其它领域学到的知识迁移至目标领域的学习过程中,帮助模型取得更好的学习效果。通过迁移学习,模型能够在短时间内取得更好的学习效果。
迁移学习通常由预训练阶段、微调阶段两部分组成。预训练阶段通常在大规模数据集中进行,例如CV任务中的ImageNet包含千万张标注图片,NLP任务中的English Wikipedia包含25亿个单词,这样训练得到的预训练模型能够很好地学习到不同领域中的通用知识。但预训练阶段使用的数据集往往与我们想要完成的任务的数据集存在差异,例如如果你只是想简单地判断一副图像是否是玫瑰花,ImageNet就没有提供相关的标注,因此为了更好的学习目标领域的知识,通常还需要对预训练模型参数进行微调。
PaddleHub中集成了ERNIE、BERT、LAC、ELMo等[NLP预训练模型](https://www.paddlepaddle.org.cn/hub),ResNet、GoogLeNet、MobileNet等[CV预训练模型](https://www.paddlepaddle.org.cn/hub);以及Adam + Weight Decay、L2SP、ULMFiT等微调策略。本文主要介绍ULMFiT微调策略在PaddleHub中的使用。
## 二、 ULMFiT
[ULMFiT](https://arxiv.org/pdf/1801.06146.pdf)提出了三种微调策略:slanted triangular learning rates、discriminative fine-tuning以及gradual unfreezing。
1. slanted triangular learning rates
slanted triangular learning rates(STLR)是一种学习率先上升再下降的微调策略,如下图所示:
![image-20190917170542047](https://user-images.githubusercontent.com/11913168/65138331-61316c80-da3d-11e9-9acb-c29385785e24.png)
其计算公式如下:
![image-20190917170707549](https://user-images.githubusercontent.com/11913168/65138349-6bec0180-da3d-11e9-821d-98bc7f2d6f1e.png)
其中T表示训练的迭代次数,PaddleHub会自动计算训练总step数;cut_frac是学习率上升在整个训练过程占用的比例;cut表示学习率转折处的step;t表示当前的step;p表示当前step学习率的缩放比例;ratio表示LR最低下降至最大学习率η<sub>max</sub>的几分之一;η<sub>t</sub>表示当前step的学习率。论文中,作者采用的超参设置为:cut_frac=0.1, ratio=32, η<sub>max</sub>=0.01。本次策略实验过程中,保持ratio=32, η<sub>max</sub>=0.01不变,仅调整cut_frac。
2. Discriminative fine-tuning
Discriminative fine-tuning 是一种学习率逐层递减的策略,通过该策略可以减缓底层的更新速度。其计算公式为:
<div align=center>η<sup>l-1</sup><sup>l</sup>/factor</div>
其中η<sup>l</sup>表示第l层的学习率;η<sup>l-1</sup>表示第l-1层的学习率;factor表示逐层衰减率,论文中作者根据经验设置为2.6。这个策略能够让模型微调过程中不断减缓底层的更新速度,尽可能的保留预训练模型中习得的底层通用知识。PaddleHub通过op的拓扑关系自动计算模型的层次,因此针对这一策略,PaddleHub提供了一个额外的超参:dis_blocks,用于设置划分的层数,默认为3,如果设置为0,则不采用Discriminative fine-tuning。
3. Gradual unfreezing
Gradual unfreezing是一种逐层解冻的策略,通过该策略可以优先更新上层,再慢慢解冻下层参与更新。PaddleHub在Gradual unfreezing策略中引入了一个额外的超参:frz_blocks,其作用与默认值与第2点提到的dis_blocks一致。在微调过程中,每经过一个epoch,模型解冻一个block,所有未被冻结的block都会参与到模型的参数更新中。
本文接下来将对ULMFiT策略在NLP以及CV任务中的使用进行实验说明,由于slanted triangular learning rates与warmup + linear decay在原理上相似,本文也将对比slanted triangular learning rates与warmup + linear decay的实验效果。
## 三、 在NLP迁移学习中使用ULMFiT策略
1. 数据集与预训练模型的选择
本次实验选取两个数据集,一个为中文数据集Chnsenticorp,另一个为英文数据集CoLA,两个数据集的训练集数据规模相似,前者包含9601个句子,后者包含8551个句子。针对中文数据集Chnsenticorp与英文数据集CoLA,本次实验分别使用ELMo与“bert_uncased_L-12_H-768_A-12”作为其预训练模型。
2. Baseline与实验设置
Baseline不采用任何策略,学习率在微调过程中保持恒定。Chnsenticorp与CoLA任务均只使用1张显卡,Batch size均设置为32,总共迭代3个epoch。Chnsenticorp设置学习率为1e-4,由于采用ELMo预训练模型,无需设置句子最大长度;CoLA设置学习率为5e-5,句子最大长度设置为128。实验效果如下表所示:
| - | Chnsenticorp | CoLA |
| :------------ | :----------- | :---------------- |
| Module | ELMo | Bert |
| Batch size | 32 | 32 |
| Num epoch | 3 | 3 |
| Learning rate | 1e-4 | 5e-5 |
| Max length | - | 128 |
| Dev | acc = 0.8766 | matthews = 0.5680 |
其中Chnsenticorp采用准确率(accuracy)得分,CoLA采用马修斯相关系数(matthews correlation coefficient)得分。
在后续调优过程中,如无特别说明,实验设置(例如Batch size、Num epoch等)均与Baseline一致。
3. slanted triangular learning rates(STLR)策略实验与分析
理论上,STLR与warmup + linear decay相似,因此本次实验同时对warmup + linear decay策略进行了实验。实验中STLR的超参仅调整cut_fraction,其它超参与论文设置一致;warm up proportion为学习率上升在总步数中的比重,linear decay则在warmup结束的时刻开始,linear decay的终止学习率设置了2组,1组为0,另一组与STLR的终止学习率一致,为learning rate/32。实验结果如下表所示:
| slanted triangular cut_fraction | 0(Baseline) | 0 | 0 | 0 | 0 | 0.1 | 0.2 |
| :---------------------------------- | :------------ | :----- | :----- | :--------- | :----- | :------ | :------ |
| warm up proportion | 0 | 0.1 | 0.2 | 0.1 | 0.2 | 0 | 0 |
| linear decay end | - Unused | 0 | 0 | lr/32 | lr/32 | - | - |
| Chnsenticorp | 0.8766 | 0.8725 | 0.8758 | **0.8825** | 0.8733 | 0.8791 | 0.8791 |
| CoLA | 0.5680 | 0.5780 | 0.5786 | **0.5887** | 0.5826 | 0.5880 | 0.5827 |
从实验结果可以看到,STLR实验效果上与warmup + linear decay (end learning rate = lr/32)接近,并且在两个任务中模型的性能都得到了提升。建议用户在尝试slanted triangular或warmup+linear decay策略时尝试更多的超参设置,在使用warmup+linear decay策略时考虑设置linear decay end。
4. Discriminative fine-tuning策略实验与分析
本小节对Discriminative fine-tuning策略进行实验分析。固定训练总epoch=3,实验结果如下表所示:
| dis_blocks | -<br />(Baseline) | 3 | 5 |
| ----------------- | ------------------- | ---------- | ------ |
| epoch | 3 | 3 | 3 |
| Chnsenticorp | **0.8766** | 0.8641 | 0.6766 |
| CoLA | 0.5680 | **0.5996** | 0.5749 |
由于Discriminative fine-tuning策略会降低模型底层的更新速度,影响模型的拟合能力。实验结果表明,dis_blocks设置过大会导致模型性能明显下降。为了提升模型拟合能力,本小节继续增大epoch大小至5、8。
对于Chnsenticorp,实验结果如下表所示:
| dis_blocks | -<br />(Baseline) | - | 5 | - | 5 |
| ----------------- | ------------------- | ---------- | ------ | ---------- | ---------- |
| epoch | 3 | 5 | 5 | 8 | 8 |
| Chnsenticorp | 0.8766 | 0.8775 | 0.8566 | 0.8775 | **0.8792** |
可以看到当dis_blocks=5时,epoch=8时,模型性能超越Baseline。
在CoLA任务中,dis_block=3,epoch=3时的模型得分已经超越了Baseline,因为可以进一步增大dis_blocks,观察其实验效果,结果如下表所示:
| dis_blocks | -<br />(Baseline) | 3 | - | 7 | - | 7 |
| ---------- | ------------------- | ---------- | ------ | ------ | ------ | ------ |
| epoch | 3 | 3 | 5 | 5 | 8 | 8 |
| CoLA | 0.5680 | **0.5996** | 0.5680 | 0.5605 | 0.5720 | 0.5788 |
实验结果表明,dis_blocks过大同样会导致性能下降的问题,当dis_blocks=7时,模型在epoch=5性能低于Baseline (epoch=3),直至epoch=8才略微超过Baseline (epoch=8),但仍显著低于dis_blocks=3,epoch=3的模型表现。建议用户采用discriminative fine-tuning时,应当设置较小的dis_blocks,如果设置过大的dis_blocks,则需提升训练的epoch。
5. Gradual unfreezing策略实验与分析
本小节对Gradual unfreezing策略进行实验分析,frz_blocks设置为3,第一个epoch只更新最顶层的block,此后每一个epoch解冻一个block参与更新,实验结果如下表所示:
| gradual unfreezing | -(baseline) | 3 |
| :----------------- | :------------ | :----- |
| Chnsenticorp | 0.8766 | **0.8850** |
| CoLA | 0.5680 | **0.5704** |
实验结果表明通过延后更新预训练模型中的底层参数,该策略不论是对Chnsenticorp数据集还是对CoLA数据集均有效。
## 四、在CV迁移学习中使用ULMFiT策略
1. 数据集与预训练模型的选择
本小节采用resnet50作为预训练模型。基于数据规模、任务数据集与预训练数据集的相似度,本次实验选择了以下四个数据集:
- **indoor67**(相似度小,规模小):该数据集包含1.5万个样例,标签包含concert_hall, locker_room等67个室内物体,这些标签未出现在预训练数据集ImageNet中。理论上,相似度小规模小的数据集在微调时既不能更新得太快导致过拟合,也不能太小导致欠拟合,是最难调整的一类数据集。
- **food101**(相似度小,规模大):该数据集包含10万个样例,标签包含Apple pie, Baby back ribs等101个食品,这些标签同样几乎没有出现在ImageNet中。理论上,相似度小规模大的数据集可以较快更新,是模型充分拟合。
- **dogcat**(相似度大,规模大):该数据集包含2.2万个样例,标签只有dog和cat两类,单类数据规模较大,且均出现在ImageNet中。理论上,相似度大规模大的数据集不论采用怎样的策略均能获得非常良好的模型性能,通过细致地调整策略可以略微提升模型性能。
- **dogcat 1/10**(相似度大,规模小):该数据集由dogcat数据集中随机抽取1/10个样例组成,包含0.22万个样例,”dog”/”cat”两类标签。理论上,相似度大规模小的数据集由于与预训练数据集相似度大,模型在微调过程中可以保留更多的预训练参数。
2. Baseline与实验设置
Baseline未采用任何策略,学习率在微调过程中保持恒定。所有任务均使用两张显卡,Batch size设置为40,训练迭代一个epoch,学习率均设置为1e-4,评估指标为准确率(accuracy)。实验效果如下表所示:
| - | **indoor67** | **food101** | **dogcat** | **dogcat 1/10** |
| :--------------- | :------------- | :------------- | -------------- | --------------- |
| Batch size | 40 | 40 | 40 | 40 |
| Num epoch | 1 | 1 | 1 | 1 |
| Learning rate | 1e-4 | 1e-4 | 1e-4 | 1e-4 |
| Dev | 0.6907 | 0.7272 | 0.9893 | 1.0 |
| Test | 0.6741 | 0.7338 | 0.9830 | 0.9719 |
在后续调优过程中,如无特别说明,实验设置(例如Batch size、Num epoch等)均与Baseline一致。
3. slanted triangular learning rates(STLR)策略实验与分析
本小节采用STLR微调策略进行实验,实验结果如下表所示,其中cut_fraction=0为Baseline,不采用任何策略:
| cut_fraction | indoor67<br />相似度小规模小 | food101<br />相似度小规模大 | dogcat <br />相似度大规模大 | dogcat 1/10<br />相似度大规模小 |
| :----------- | :-------------------------------- | :----------------------------------- | :------------------------------- | :-------------------------------- |
| 0 (baseline) | dev: 0.6907<br />test:0.6741 | dev: 0.7272<br />test:0.7338 | dev:0.9893<br />test:0.9830 | dev:**1.0**<br />test:0.9719 |
| 0.01 | dev: 0.7148<br /> test:0.7053 | dev:**0.7637**<br /> test:**0.7656** | dev: **0.9946**<br />test:0.9924 | dev: *0.4481* <br />test:*0.5346* |
| 0.05 | dev: **0.7226**<br /> test:0.7130 | dev:0.7605<br /> test:0.7612 | dev: 0.9901<br />test:0.9919 | dev: **1.0**<br />test:0.9844 |
| 0.1 | dev: 0.7128<br /> test:**0.7155** | dev: 0.7606<br /> test:0.7582 | dev: 0.9924<br />test:**0.9928** | dev: 0.9958<br />test:0.9688 |
| 0.2 | dev: 0.6361<br /> test:0.6151 | dev: 0.7581<br /> test:0.7575 | dev: 0.9941<br />test:0.9897 | dev: 0.9916<br /> test:**0.9916** |
从实验结果可以看到,采用该策略后,模型在各个数据集中的性能都获得了提升,尤其在相似度小规模大的数据集中,模型在验证集上的结果从0.7272提升至0.7637。
值得注意的是dogcat 1/10在cut_fraction=0.01时会出现异常结果,这是由于dogcat 1/10的训练集大小为1803,在总batch size=80的时候,总迭代步数为22,当设置cut_fraction=0.01时,由第二章STLR计算公式可得,cut=0,这会导致后续计算p时会出现除数为0的问题,导致实验结果异常。因此对于小规模数据集,建议设置较小的batch size。
4. Discriminative fine-tuning策略实验与分析
本小节对Discriminative fine-tuning策略进行实验分析。理论上,预训练得到的模型的底层学到的是图像当中的通用特征,那么对于相似度大的数据集,可以保留更多的预训练参数;而对于相似度小的数据集,则应保留更少的预训练参数,让模型在任务数据集中得到更多训练。本实验通过设置不同的dis_blocks来控制底层的学习率衰减次数,dis_blocks越大则底层的学习率衰减越多,预训练参数保留得越多。实验结果如下表所示:
| dis_blocks | indoor67<br />相似度小规模小 | food101<br />相似度小规模大 | dogcat <br />相似度大规模大 | dogcat 1/10<br />相似度大规模小 |
| :----------- | :---------------------------------- | :---------------------------------- | :-------------------------------- | :-------------------------------- |
| 0 (baseline) | dev: 0.6907<br />test:0.6741 | dev: 0.7272<br />test:0.7338 | dev:0.9893<br />test:0.9830 | dev:**1.0**<br />test:0.9719 |
| 3 | dev:**0.7842**<br />test:**0.7575** | dev:**0.7581**<br />test:**0.7527** | dev:**0.9933**<br /> test:0.9897 | dev:0.9958<br /> test:**0.9802** |
| 5 | dev: 0.7092<br />test:0.6961 | dev:0.7336<br /> test:0.7390 | dev: 0.9928<br /> test:**0.9910** | dev: 0.9958<br /> test:**0.9802** |
观察实验结果,可以发现该策略在四类数据集中均有良好的效果。在相似度小规模小的数据集中,当dis_blocks设置为3时,实验效果提升明显,但设置为5的时候,test成绩反而不如Baseline,对于相似度小规模小的数据集,调优过程应当注意寻找合适的超参数设置。对于相似度大规模大的数据集无论是否采用该策略均有优良的表现,采用该策略可以略微提升模型性能。
5. Gradual unfreezing策略实验与分析
本小节验证Gradual unfreezing策略的实验效果。理论上,该策略与Discriminative fine-tuning策略相似,对于相似度大的数据集可以更慢的解冻底层,而相似度小的数据集可以早点解冻底层使它们拟合任务数据集。本次实验设置了不同的frz_blocks控制底层的解冻速度,每个epoch模型解冻一个block。实验结果如下表所示:
| frz_blocks | epoch | indoor67<br />相似度小规模小 | food101<br />相似度小规模大 | dogcat <br />相似度大规模大 | dogcat 1/10<br />相似度大规模小 |
| :--------- | ----- | :---------------------------------- | :------------------------------- | :------------------------------- | :-------------------------------- |
| 0 | 1 | dev: 0.6907<br />test:0.6741 | dev: **0.7272**<br />test:0.7338 | dev:0.9893<br />test:0.9830 | dev:**1.0**<br />test:0.9719 |
| 0 | 3 | dev:0.7697<br /> test:0.7574 | dev: 0.7427<br /> test:0.7407 | dev:0.9919<br /> test:**0.9910** | dev:**1.0**<br />test:0.9719 |
| 3 | 1 | dev:0.7210<br /> test:0.7018 | dev: 0.7251<br />test:0.7270 | dev:**0.9924**<br /> test:0.9857 | dev:**1.0**<br />test:0.9719 |
| 3 | 3 | dev: 0.7763<br /> test:0.7627 | dev:0.7346<br /> test:0.7356 | dev: 0.9849<br /> test:0.9887 | dev: **1.0**<br /> test: 0.9719 |
| 5 | 1 | dev: 0.7236<br /> test:0.6961 | dev: 0.7168<br /> test:0.7204 | dev: 0.9892<br /> test:0.9861 | dev: **1.0**<br />test:**0.9802** |
| 5 | 3 | dev:**0.7802**<br />test:**0.7689** | dev:**0.7461<br />** test:0.7389 | dev:**0.9924**<br /> test:0.9892 | dev:**1.0**<br /> test:**0.9802** |
从表中结果可得,frz_blocks=5的实验组在epoch=3时超越了frz_blocks=3的实验结果,设置较大的frz_blocks会降低模型的拟合能力,但提升epoch,使模型得到充分的训练后,模型能够取得更好的效果。建议用户采用Gradual unfreezing策略时设置足够大的epoch。
## 五、总结
本文描述了在NLP、CV任务中使用ULMFiT策略微调PaddleHub预训练模型的过程,尝试了warm up + linear decay, slanted triangular learning rate, Discriminative fine-tuning, Gradual unfreezing四种微调策略。
slanted triangular learning rate和warm up + linear decay在原理上和实验结果上都是相似的,Discriminative fine-tuning和Gradual unfreezing微调策略在使用中,应当注意它们会降低模型的拟合能力,可以适当提高训练的轮数。
PaddleHub 1.2已发布AutoDL Finetuner,可以自动搜索超参设置,详情请参考[PaddleHub AutoDL Finetuner](./autofinetune.md)。如有任何疑问欢迎您在issues中向我们提出!
## 六、参考文献
1. Howard J, Ruder S. Universal Language Model Fine-tuning for Text Classification[C]//Proceedings of the 56th Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers). 2018: 328-339.
2. website: [Transfer learning from pre-trained models](https://towardsdatascience.com/transfer-learning-from-pre-trained-models-f2393f124751)
教程
迁移学习
==================
以下是关于PaddleHub的使用教程,介绍了命令行使用、如何自定义数据完成Finetune、如何自定义迁移任务、如何服务化部署预训练模型、如何获取ERNIE/BERT Embedding、如何用word2vec完成语义相似度计算、ULMFit优化策略介绍、如何使用超参优化AutoDL Finetuner、如何用Hook机制改写Task内置方法
本文将介绍介绍了如何自定义数据、如何完成Finetune以及如何使用超参优化AutoDL Finetuner
详细信息,参考以下教程:
......@@ -9,13 +9,8 @@
.. toctree::
:maxdepth: 1
命令行工具<cmdintro>
自定义数据<how_to_load_data>
Fine-tune模型转化为PaddleHub Module<finetuned_model_to_module.md>
自定义任务<how_to_define_task>
服务化部署<serving>
文本Embedding服务<bert_service>
语义相似度计算<sentence_sim>
ULMFit优化策略<strategy_exp>
如何迁移学习<how_to_finetune>
超参优化<autofinetune>
Hook机制<hook>
......@@ -15,8 +15,8 @@ from senta_test.processor import load_vocab
author_email="",
type="nlp/sentiment_analysis",
)
class SentaTest(hub.Module):
def _initialize(self):
class SentaTest:
def __init__(self):
# add arg parser
self.parser = argparse.ArgumentParser(
description="Run the senta_test module.", prog='hub run senta_test', usage='%(prog)s', add_help=True)
......
......@@ -32,6 +32,7 @@ def register(name: str, description: str = '') -> Any:
name(str) : The name of the command, separated by '.' (e.g, hub.serving)
description(str) : The description of the specified command showd in the help command, if not description given, this command would not be shown in help command. Default is None.
'''
def _warpper(command):
items = name.split('.')
......
......@@ -19,6 +19,7 @@ from typing import List
class BaseProcessor(object):
'''
'''
def __init__(self, module):
...
......
......@@ -153,7 +153,7 @@ class ImageColorizeModule(RunModule, ImageServing):
'''
self.eval()
lab2rgb = T.LAB2RGB()
if isinstance(images, str):
images = cv2.imread(images).astype('float32')
......
......@@ -15,6 +15,7 @@
import os
import shutil
import sys
from collections import OrderedDict
from typing import List
......@@ -38,6 +39,7 @@ class HubModuleNotFoundError(Exception):
msg = '{}'.format(self.name)
if self.version:
msg += '-{}'.format(self.version)
if self.source:
msg += ' from {}'.format(self.source)
......@@ -168,6 +170,7 @@ class LocalModuleManager(object):
source (str|optional): source containing module code, use with name paramete
'''
if name:
lock = filelock.FileLock(os.path.join(TMP_HOME, name))
with lock:
hub_module_cls = self.search(name, source, branch)
......@@ -235,6 +238,7 @@ class LocalModuleManager(object):
'''List all installed HubModule.'''
for subdir in os.listdir(self.home):
fulldir = os.path.join(self.home, subdir)
try:
self._local_modules[subdir] = HubModule.load(fulldir)
except:
......@@ -284,20 +288,16 @@ class LocalModuleManager(object):
if item['name'] == name and item['version'].match(version):
# uninstall local module
if self.search(name):
local_module = self.search(name)
if local_module and local_module.source == source and local_module.branch == branch:
self._local_modules[name] = local_module
return self._local_modules[name]
if os.path.exists(self._get_normalized_path(name)):
self.uninstall(name)
installed_path = self._get_normalized_path(name)
if not os.path.exists(installed_path):
os.makedirs(installed_path)
module_file = os.path.join(installed_path, 'module.py')
# Generate a module.py file to reference objects from git repository
with open(module_file, 'w') as file:
file.write('import sys\n\n')
file.write('sys.path.insert(0, \'{}\')\n'.format(item['path']))
file.write('from hubconf import {}\n'.format(item['class']))
file.write('sys.path.pop(0)\n')
shutil.copytree(item['path'], installed_path)
source_info_file = os.path.join(installed_path, '_source_info.yaml')
with open(source_info_file, 'w') as file:
......@@ -305,10 +305,6 @@ class LocalModuleManager(object):
file.write('branch: {}'.format(branch))
self._local_modules[name] = HubModule.load(installed_path)
module_file = sys.modules[self._local_modules[name].__module__].__file__
requirements_file = os.path.join(os.path.dirname(module_file), 'requirements.txt')
if os.path.exists(requirements_file):
shutil.copy(requirements_file, installed_path)
# Install python package requirements
self._install_module_requirements(self._local_modules[name])
......
......@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import ast
import inspect
import importlib
import os
......@@ -79,6 +80,20 @@ class GitSource(object):
sys.path.insert(0, self.path)
try:
with open(os.path.join(self.path, 'hubconf.py'), 'r') as file:
pycode = file.read()
ast_module = ast.parse(pycode)
for _body in ast_module.body:
if not isinstance(_body, (ast.Import, ast.ImportFrom)):
continue
if not _body.module.endswith('module'):
continue
subpath = '.'.join(_body.module.split('.')[:-2])
subpath = os.path.join(self.path, subpath)
sys.path.insert(0, subpath)
py_module = importlib.import_module('hubconf')
for _item, _cls in inspect.getmembers(py_module, inspect.isclass):
_item = py_module.__dict__[_item]
......@@ -111,10 +126,12 @@ class GitSource(object):
'''
module = self.hub_modules.get(name, None)
if module and module.version.match(version):
path = sys.modules[module.__module__].__file__
path = os.path.dirname(path)
return [{
'version': module.version,
'name': module.name,
'path': self.path,
'path': path,
'class': module.__name__,
'source': self.url
}]
......
......@@ -579,4 +579,3 @@ class CenterCrop:
crop_top = int((img_height - self.crop_size) / 2.)
crop_left = int((img_width - self.crop_size) / 2.)
return img[crop_left:crop_left + self.crop_size, crop_top:crop_top + self.crop_size, :]
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册