diff --git a/README.md b/README.md index b955732c41b962a4ba55066592180cb3646f049b..32746cd5b02e64e0b0ac76ef071eba320cf572d1 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ PaddleHub是基于PaddlePaddle开发的预训练模型管理工具,可以借 2. 通过hub download命令,快速地获取PaddlePaddle生态下的所有预训练模型; 3. 借助PaddleHub Finetune API,使用少量代码完成迁移学习; - 更多Demo可参考 [ERNIE文本分类](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/demo/text-classification) [图像分类迁移](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/demo/image-classification) - - 完整教程可参考 [文本分类迁移教程](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub%E6%96%87%E6%9C%AC%E5%88%86%E7%B1%BB%E8%BF%81%E7%A7%BB%E6%95%99%E7%A8%8B) [图像分类迁移教程](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub%E5%9B%BE%E5%83%8F%E5%88%86%E7%B1%BB%E8%BF%81%E7%A7%BB%E6%95%99%E7%A8%8B) + - 完整教程可参考 [文本分类迁移教程](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/turtorial/nlp_tl_turtorial.md) [图像分类迁移教程](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/turtorial/cv_tl_turtorial.md) ## 安装 @@ -43,7 +43,7 @@ $ hub run senta_bilstm --input_text "今天是个好日子" $ wget --no-check-certificate https://paddlehub.bj.bcebos.com/resources/test_img_bird.jpg $ hub run ssd_mobilenet_v1_pascal --input_path test_img_bird.jpg ``` -![SSD检测结果](https://raw.githubusercontent.com/PaddlePaddle/PaddleHub/develop/docs/imgs/test_img_bird_output.jpg) +![SSD检测结果](https://raw.githubusercontent.com/PaddlePaddle/PaddleHub/release/v0.5.0/docs/imgs/test_img_bird_output.jpg) 想了解更多PaddleHub已经发布的模型,请使用`hub search`命令查看所有已发布的模型。 @@ -52,10 +52,10 @@ $ hub search ``` ## 深入了解PaddleHub -* [PaddleHub Wiki](https://github.com/PaddlePaddle/PaddleHub/wiki) -* [命令行工具](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7) -* [Finetune API与迁移学习](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub%E4%B8%8E%E8%BF%81%E7%A7%BB%E5%AD%A6%E4%B9%A0) -* [API](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub-Finetune-API) +* [PaddleHub 介绍](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/home.md) +* [命令行工具](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/turtorial/cmd_tool.md) +* [Finetune API与迁移学习](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/turtorial/paddlehub_tl.md) +* [API](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/finetune_api.md) ## 答疑 diff --git a/docs/api/Dataset.md b/docs/api/Dataset.md new file mode 100644 index 0000000000000000000000000000000000000000..06c4e8e6dd7b2c9a3a610a55295cdc191a488cc0 --- /dev/null +++ b/docs/api/Dataset.md @@ -0,0 +1,103 @@ +PaddleHub提供以下数据集可供下载: + +### Class `hub.dataset.ChnSentiCorp` +ChnSentiCorp 是中文情感分析数据集,其目标是判断一段话的情感态度。 + +**示例** +> +> ```python +> import paddlehub as hub +> +>dataset = hub.dataset.ChnSentiCorp() +> ``` + +### Class `hub.dataset.LCQMC` +LCQMC 是哈尔滨工业大学在自然语言处理国际顶会 COLING2018 构建的问答匹配数据集,其目标是判断两个问题的语义是否相同。 + +**示例** +> +> ```python +> import paddlehub as hub +> +>dataset = hub.dataset.LCQMC() +> ``` + +### Class `hub.dataset.NLPCC_DPQA` +NLPCC_DPQA 是由国际自然语言处理和中文计算会议NLPCC于2016年举办的评测任务,其目标是选择能够回答问题的答案。 + +**示例** +> +> ```python +> import paddlehub as hub +> +>dataset = hub.dataset.NLPCC_DPQA() +> ``` + +### Class `hub.dataset.MSRA_NER` +MSRA-NER(SIGHAN 2006) 数据集由微软亚研院发布,其目标是命名实体识别,是指识别文本中具有特定意义的实体,主要包括人名、地名、机构名等。 + +**示例** +> +> ```python +> import paddlehub as hub +> +>dataset = hub.dataset.MSRA-NER() +> ``` + +### Class `hub.dataset.DogCatDataset` +DOGCAT 是由Kaggle提供的数据集,用于图像二分类,其目标是判断一张图片是猫或是狗。 + +**示例** +> +> ```python +> import paddlehub as hub +> +>dataset = hub.dataset.DogCatDataset() +> ``` + +### Class `hub.dataset.Food101Dataset` +FOOD101 是由Kaggle提供的数据集,含有101种类别,其目标是判断一张图片属于101种类别中的哪一种类别。 + +**示例** +> +> ```python +> import paddlehub as hub +> +>dataset = hub.dataset.Food101Dataset() +> ``` + +### Class `hub.dataset.Indoor67Dataset` +INDOOR数据集是由麻省理工学院发布,其包含67种室内场景,其目标是识别一张室内图片的场景类别。 + +**示例** +> +> ```python +> import paddlehub as hub +> +>dataset = hub.dataset.Indoor67Dataset() +> ``` + +### Class `hub.dataset.FlowersDataset` +FLOWERS数据集是是公开花卉数据集,一共有5种类型,用于做图像分类。 + +**示例** +> +> ```python +> import paddlehub as hub +> +>dataset = hub.dataset.FlowersDataset() +> ``` + +### Class `hub.dataset.StanfordDogsDataset` +STANFORD_DOGS数据集是斯坦福大学发布,其包含120个种类的狗,用于做图像分类。 + +**示例** +> +> ```python +> import paddlehub as hub +> +>dataset = hub.dataset.StanfordDogsDataset() +> ``` + + +若您想在自定义数据集上完成FineTune,请查看[PaddleHub适配自定义数据完成FineTune](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/turtorial/user_define_dataset.md) diff --git a/docs/api/Module.md b/docs/api/Module.md new file mode 100644 index 0000000000000000000000000000000000000000..ce127a36586e7ecc4e4ea3a738b948f9826097b5 --- /dev/null +++ b/docs/api/Module.md @@ -0,0 +1,56 @@ +# Module +---- +Module代表了一个`可执行`的模型。这里的可执行指的是,Module可以直接通过命令行`hub run ${MODULE_NAME}`执行预测,或者通过context接口获取上下文后进行finetune。在生成一个Module时,支持通过名称、url或者路径创建Module。 + +### Class `hub.module.Module` + +```python +hub.Module( + name=None, + module_dir=None, + signatures=None, + module_info=None, + assets=None, + processor=None, + extra_info=None): +``` + +**参数** +> * name: 模块名称 +> * module_dir: 模块路径 + +**返回** + +`Module` + +**示例** +```python +import paddlehub as hub +# 根据模型名字创建Module +hub.Module(name = "lac") +``` + +#### `context` +用于获取Module的上下文信息,得到输入、输出以及预训练的Paddle Program副本。 + +**参数** +> * for_test: 是否用于测试,如果是用于预测,则设置为True,如果用于finetune,则设置为False。默认情况下,该参数被设置为False +> * trainable: 获取的Program副本中的参数是否为可训练的,设置为True表示可训练。默认情况下,该参数被设置为False +> * regularizer: 获取的Program副本中的参数的正则化项。默认情况下,该参数被设置为None +> * learning_rate: 获取的Program副本中的参数的学习率。默认情况下,该参数被设置为1e-3 + +**示例** +```python +import paddlehub as hub +resnet = hub.Module(name = "resnet_v2_50_imagenet") +input_dict, output_dict, program = resnet.context(trainable=True) +with fluid.program_guard(program): + label = fluid.layers.data(name="label", dtype="int64", shape=[1]) + img = input_dict["image"] + feature_map = output_dict["feature_map"] + feed_list = [img.name, label.name] + fc = fluid.layers.fc(input = feature_map, size = 2) + feed_list = [img.name, label.name] + # 添加fc层后,进行训练 + ... +``` diff --git a/docs/api/Reader.md b/docs/api/Reader.md new file mode 100644 index 0000000000000000000000000000000000000000..e4da6d768bd6df0fa652e106777a583c9a9938a8 --- /dev/null +++ b/docs/api/Reader.md @@ -0,0 +1,182 @@ +# Reader + +PaddleHub的数据预处理模块Reader对常见的NLP和CV任务进行了抽象。 + +## NLPReader + +### hub.reader.ClassifyReader + +#### Class `ClassifyReader` +适用于Transformer预训练模型(ERNIE/BERT)的数据预处理器。 + +hub.reader.ClassifyReader( + dataset, + vocab_path, + max_seq_len, + do_lower_case, + random_seed +) + +**参数:** +* `dataset`: hub.dataset中的数据集 +* `vocab_path`: 模型词表路径 +* `max_seq_len`: 最大序列长度 +* `do_lower_case`: 是否讲所有字符中的大写字符转为小写字符 +* `random_seed`: 随机种子,默认为None + +**返回** + +`ClassifyReader` + +**示例** +```python +import paddlehub as hub + +dataset = hub.dataset.ChnSentiCorp() + +reader = hub.reader.ClassifyReader( + dataset=dataset, + vocab_path=module.get_vocab_path(), + max_seq_len=args.max_seq_len) + +``` + +------ + +### hub.reader.LACClassifyReader +#### Class `LACClassifyReader` +以LAC模块为切词器的预处理模块,适用于Senta、ELMo等需要以词粒度分词的任务。 + +```python +hub.reader.LACClassificationReader( + dataset, + vocab_path) +``` + +**参数:** +* `dataset`: hub.dataset中的数据集 +* `vocab_path`: 模型词表路径 + +**返回** + +`LACClassificationReader` + +**示例** +```python +import paddlehub as hub + +dataset = hub.dataset.ChnSentiCorp() + +reader = hub.reader.LACClassifyReader( + dataset=dataset, vocab_path=module.get_vocab_path()) + +``` + + +***NOTE***: 使用LACClassificationReader时,安装的lac module版本应该至少为1.0.1 + + +------ + +### hub.reader.SequenceLabelReader +#### Class `SequenceLabelReader` +适用于Transformer类模型(ERNIE/BERT)的序列标注预处理器。 + +hub.reader.SequenceLabelReader( + dataset, + vocab_path, + max_seq_len, + do_lower_case, + random_seed +) + +**参数:** +* `dataset`: hub.dataset中的数据集 +* `vocab_path`: 模型词表路径 +* `max_seq_len`: 最大序列长度 +* `do_lower_case`: 是否讲所有字符中的大写字符转为小写字符 +* `random_seed`: 随机种子,默认为None + +**返回** + +`ClassifyReader` + +**示例** +```python +import paddlehub as hub + +dataset = hub.dataset.ChnSentiCorp() + +reader = hub.reader.SequenceLabelReader( + dataset=dataset, + vocab_path=module.get_vocab_path(), + max_seq_len=args.max_seq_len) + +``` +## CVReader + +### hub.reader.cv_reader.ImageClassificationReader + +#### Class `ImageClassificationReader` +```python +hub.ImageClassificationReader( + image_width, + image_height, + dataset, + channel_order="RGB", + images_mean=None, + images_std=None, + data_augmentation=False) +``` + +适用于图像分类数据的预处理器。会修改输入图像的尺寸、进行标准化处理、图像增广处理等操作。 + +**参数** +> * image_width: 预期经过reader处理后的图像宽度 +> * image_height: 预期经过reader处理后的图像高度 +> * dataset: 数据集 +> * channel_order: 预期经过reader处理后的图像通道顺序。默认为RGB +> * images_mean: 进行标准化处理时所减均值。默认为None +> * images_std: 进行标准化处理时所除标准差。默认为None +> * data_augmentation: 是否使用图像增广,当开启这个选项时,会对输入数据进行随机变换,包括左右对换,上下倒置,旋转一定的角度,对比度调整等 + +**返回** + +`ImageClassificationReader` + +**示例** +```python +import paddlehub as hub + +dataset = hub.dataset.Flowers() + +data_reader = hub.reader.ImageClassificationReader( + image_width=module.get_expected_image_width(), + image_height=module.get_expected_image_height(), + images_mean=module.get_pretrained_images_mean(), + images_std=module.get_pretrained_images_std(), + dataset=dataset) +``` + +#### `data_generator` +为数据集或者指定的数据生成对应的batch reader。 + +**参数** +> * batch_size: 所返回的batch reader的batch大小 +> * phase: 生成什么类型的数据集,phase只能是{train/test/val/dev/predict}中的一个,其中train表示训练集,test表示测试集,val或dev表示验证集,predict表示预测数据。默认为"train" +> * shuffle: 是否打乱数据。默认为False +> * data: 待预测数据,当phase为"predict"时,需要提供将预测数据填入这个字段 + +**示例** +```python +... +data_reader = hub.reader.ImageClassificationReader( + image_width=module.get_expected_image_width(), + image_height=module.get_expected_image_height(), + images_mean=module.get_pretrained_images_mean(), + images_std=module.get_pretrained_images_std(), + dataset=dataset) +... +hub.finetune_and_eval( + task, feed_list=feed_list, data_reader=data_reader, config=config) +``` diff --git a/docs/api/RunConfig.md b/docs/api/RunConfig.md new file mode 100644 index 0000000000000000000000000000000000000000..bd5adf5e93eaae05e392467042b5726f92f00c2c --- /dev/null +++ b/docs/api/RunConfig.md @@ -0,0 +1,161 @@ +# RunConfig +---- +在PaddleHub中,RunConfig代表了在对[Task](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/Task.md)进行Finetune时的运行配置。包括运行的epoch次数、batch的大小、是否使用GPU训练等。 + +### Class `hub.finetune.config.RunConfig` + +```python +hub.RunConfig( + log_interval=10, + eval_interval=100, + save_ckpt_interval=None, + use_cuda=False, + checkpoint_dir=None, + num_epoch=10, + batch_size=None, + enable_memory_optim=True, + strategy=None)` +``` +**参数:** + +* `log_interval`: 打印训练日志的周期,默认为10。 +* `eval_interval`: 进行评估的周期,默认为100。 +* `save_ckpt_interval`: 保存checkpoint的周期,默认为None。 +* `use_cuda`: 是否使用GPU训练和评估,默认为False。 +* `checkpoint_dir`: checkpoint的保存目录,默认为None,此时会在工作目录下根据时间戳生成一个临时目录。 +* `num_epoch`: 运行的epoch次数,默认为10。 +* `batch_size`: batch大小,默认为None。 +* `enable_memory_optim`: 是否进行内存优化,默认为True。 +* `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() +``` + +#### `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() +``` diff --git a/docs/api/Strategy.md b/docs/api/Strategy.md new file mode 100644 index 0000000000000000000000000000000000000000..e66f2ff73fa758091915a656a770aa18c30c6bfc --- /dev/null +++ b/docs/api/Strategy.md @@ -0,0 +1,106 @@ +# Strategy +---- +在PaddleHub中,Strategy类封装了一系列适用于迁移学习的Fine-tuning策略。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: 优化器名称,默认为None,此时会使用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: 优化器名称。默认为None,此时会使用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: 优化器名称。默认为None,此时会使用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) +``` diff --git a/docs/api/Task.md b/docs/api/Task.md new file mode 100644 index 0000000000000000000000000000000000000000..066726a23baa59c64821ae38e60f5f40fb183a0f --- /dev/null +++ b/docs/api/Task.md @@ -0,0 +1,179 @@ +# Task +---- +在PaddleHub中,Task代表了一个fine-tune的任务。任务中包含了执行该任务相关的program以及和任务相关的一些度量指标(如分类准确率accuracy、precision、 recall、 F1-score等)、模型损失等。 + +### Class `hub.finetune.task.Task` +```python +hub.Task( + task_type, + graph_var_dict, + main_program, + startup_program, + inference_program=None) +``` + +**参数** +> * task_type: 任务类型,用于在finetune时进行判断如何执行任务 +> * graph_var_dict: 变量映射表,提供了任务的度量指标 +> * main_program: 存储了模型计算图的Program +> * module_dir: 存储了模型参数初始化op的Program + +**返回** + +`Task` + +**示例** + +```python +import paddlehub as hub +# 根据模型名字创建Module +resnet = hub.Module(name = "resnet_v2_50_imagenet") +input_dict, output_dict, program = resnet.context(trainable=True) +feature_map = output_dict["feature_map"] +task = hub.create_img_cls_task(feature=feature_map, num_classes=2) +``` + +#### `variable` +获取Task的相关变量,包括loss、label以及task相关的性能指标(如分类任务的指标为accuracy) + +**参数** +> * var_name: 变量名 +> + +**示例** +```python +import paddlehub as hub +... +task = hub.create_img_cls_task( + feature=feature_map, num_classes=2) +task.variable("loss") +``` + +#### `main_program` +获取Task对应的main_program + +**示例** +```python +import paddlehub as hub +... +task = hub.create_img_cls_task( + feature=feature_map, num_classes=2) +main_program = task.main_program() +``` + +#### `startup_program` +获取Task对应的startup_program + +**示例** +```python +import paddlehub as hub +... +task = hub.create_img_cls_task( + feature=feature_map, num_classes=2) +startup_program = task.startup_program() +``` + +#### `inference_program` +获取Task对应的inference_program + +**示例** +```python +import paddlehub as hub +... +task = hub.create_img_cls_task( + feature=feature_map, num_classes=2) +inference_program = task.inference_program() +``` + +#### `metric_variable_names` +获取Task对应的所有相关的变量,包括loss、度量指标等 + +**示例** +```python +import paddlehub as hub +... +task = hub.create_img_cls_task( + feature=feature_map, num_classes=2) +metric_variable_names = task.metric_variable_names() +``` + + +### `hub.create_img_cls_task` + +基于输入的特征,添加一个或多个全连接层来创建一个[图像分类](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/demo/image-classification)任务用于finetune + +### 参数 +> * feature: 输入的特征 +> * labels: 标签Variable +> * num_classes: 最后一层全连接层的神经元个数 +> * hidden_units: 隐藏单元的设置,预期值为一个python list,list中的每个元素说明了一个隐藏层的神经元个数 + +### 返回 + +`hub.finetune.task.Task` + +### 示例 + +```python +import paddlehub as hub + +module = hub.Module(name="resnet_v2_50_imagenet") +inputs, outputs, program = module.context(trainable=True) +feature_map = outputs['feature_map'] +cls_task = hub.create_img_cls_task( + feature=feature_map, num_classes=2, hidden_units = [20, 10]) +``` + +### hub.create_seq_label_task + +基于输入的特征,添加一个全连接层来创建一个[序列标注](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/demo/sequence-labeling)任务用于finetune + +### 参数 +> * feature: 输入的特征 +> * seq_len: 序列长度Variable +> * num_classes: 全连接层的神经元个数 + +### 返回 + +`hub.finetune.task.Task` + +### 示例 +```python +import paddlehub as hub + +max_seq_len = 20 +module = hub.Module(name="ernie") +inputs, outputs, program = module.context( + trainable=True, max_seq_len=max_seq_len) +sequence_output = outputs["sequence_output"] +seq_label_task = hub.create_seq_label_task( + feature=sequence_output, + seq_len=seq_len, + num_classes=dataset.num_labels) +``` + +### hub.create_text_cls_task + +基于输入的特征,添加一个或多个全连接层来创建一个[文本分类](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/demo/text-classification)任务用于finetune + +### 参数 +> * feature: 输入的特征 +> * num_classes: 最后一层全连接层的神经元个数 +> * hidden_units: 隐藏单元的设置,预期值为一个python list,list中的每个元素说明了一个隐藏层的神经元个数 + +### 返回 + +`hub.finetune.task.Task` + +### 示例 +```python +import paddlehub as hub + +max_seq_len = 20 +module = hub.Module(name="ernie") +inputs, outputs, program = module.context( + trainable=True, max_seq_len=max_seq_len) +pooled_output = outputs["pooled_output"] +cls_task = hub.create_text_cls_task( + feature=pooled_output, num_classes=2, hidden_units = [20, 10]) +``` diff --git a/docs/api/connect_program.md b/docs/api/connect_program.md new file mode 100644 index 0000000000000000000000000000000000000000..69973771034a49deddc49d5985a1bee964d9cacf --- /dev/null +++ b/docs/api/connect_program.md @@ -0,0 +1,55 @@ +# paddlehub.connect_program + +### hub.connect_program +```python +hub.connect_program( + pre_program, + next_program, + input_dict=None, + inplace=True): +``` +connect_program用于串行连接两个Program来生成一个新的Program,例如可用于支持**py_reader输入方式**的计算图连接等。py_reader本身会创建一个数据输入的计算图,而预训练模型本身也是一个计算图,connect_program接口用于将输入图与预训练模型图进行连接。 + +### 参数 +* `pre_program`: 待进行串接的Program,串接后位于首部 +* `next_program`: 待进行串接的Program,串接后位于尾部 +* `input_dict`: 一个由 {str, Variable} 键值对组成的dict,用于指定将pre_program和next_program中的哪些Variable进行连接,dict的key为pre_program中的变量名(str),dict的value为next_program中的变量实例(Variable) +* `inplace`: 是否直接在pre_program上进行串接操作。如果为True,则会在pre_program上进行串接操作。如果为False,则会生成一个新的Program用于串接。默认为True + +### 返回 + +`Program` + +### 示例 + +```python +import paddlehub as hub +import paddle.fluid as fluid + +module = hub.Module(name="mobilenet_v2_imagenet") +inputs, outputs, program = module.context(trainable=True) +image = inputs["image"] +feature_map = outputs["feature_map"] + +main_program = fluid.Program() + +with fluid.program_guard(main_program): + py_reader = fluid.layers.py_reader( + capacity=16, + shapes=[image.shape, [-1, 1]], + lod_levels=[0, 0], + dtypes=["float32", "int64"], + use_double_buffer=True) + + py_image, py_label = fluid.layers.read_file(py_reader) + + input_dict = { + image.name: py_image + } + + hub.connect_program( + pre_program=main_program, + next_program=program, + input_dict=input_dict, + inplace=True) +``` diff --git a/docs/api/finetune.md b/docs/api/finetune.md new file mode 100644 index 0000000000000000000000000000000000000000..8e22175d489b7a8e053da6400c0cfcc4273addac --- /dev/null +++ b/docs/api/finetune.md @@ -0,0 +1,45 @@ +# paddlehub.finetune + +### hub.finetune_and_eval +```python +hub.finetune_and_eval( + task, + data_reader, + feed_list, + config=None) +``` +对一个Task进行finetune,并且定期进行验证集评估。在finetune的过程中,接口会定期的保存checkpoint(模型和运行数据),当运行被中断时,通过RunConfig指定上一次运行的checkpoint目录,可以直接从上一次运行的最后一次评估中恢复状态继续运行。 + +### 参数 +* `task`: 需要执行的Task +* `data_reader`: 提供数据的reader +* `feed_list`: reader的feed列表 +* `config`: 运行配置 + +### 示例 +> ```python +> import paddlehub as hub +> import paddle.fluid as fluid +> +> resnet_module = hub.Module(name="resnet_v2_50_imagenet") +> input_dict, output_dict, program = resnet_module.context(trainable=True) +> dataset = hub.dataset.Flowers() +> data_reader = hub.reader.ImageClassificationReader( +> image_width=resnet_module.get_excepted_image_width(), +> image_height=resnet_module.get_excepted_image_height(), +> dataset=dataset) +> +> img = input_dict["image"] +> +> feature_map = output_dict["feature_map"] +> +> feed_list = [img.name, label.name] +> +> task = hub.create_img_cls_task( +> feature=feature_map, num_classes=dataset.num_labels) +> hub.finetune_and_eval( +> task=task, feed_list=feed_list, data_reader=data_reader) +> ``` + + +若您想在自定义数据集上完成相应任务,请查看[PaddleHub适配自定义数据完成FineTune](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/turtorial/user_define_dataset.md) diff --git a/docs/api/finetune_api.md b/docs/api/finetune_api.md new file mode 100644 index 0000000000000000000000000000000000000000..1b0004ff407fc808dbe1a9c469c6c7f5c430597c --- /dev/null +++ b/docs/api/finetune_api.md @@ -0,0 +1,11 @@ +# PaddleHub Fine-tune API 全景图 + +![Fine-tune API 全景图](https://raw.githubusercontent.com/PaddlePaddle/PaddleHub/release/v0.5.0/docs/imgs/finetune_api_figure.png) + +* Finetune [Finetune](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/finetune.md) +* 迁移任务 [Task](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/Task.md) +* 运行配置 [RunConfig](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/RunConfig.md) +* 优化策略 [Strategy](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/Strategy.md) +* 预训练模型 [Module](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/Module.md) +* 数据预处理 [Reader](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/Reader.md) +* 数据集 [Dataset](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/Dataset.md) diff --git a/docs/home.md b/docs/home.md new file mode 100644 index 0000000000000000000000000000000000000000..a2a671253aedab7acbc86207c31e0627e7d38870 --- /dev/null +++ b/docs/home.md @@ -0,0 +1,30 @@ +欢迎使用**PaddleHub**! + +PaddleHub是PaddlePaddle生态下的预训练模型的管理工具,旨在让PaddlePaddle生态下的开发者更便捷享受到大规模预训练模型的价值。通过PaddleHub,用户可以便捷地获取PaddlePaddle生态下的预训练模型,完成模型的管理和一键预测。此外,利用PaddleHub Fine-tune API,用户可以基于大规模预训练模型快速实现迁移学习,让预训练模型能更好服务于用户特定场景的应用。 + +![PaddleHub](https://raw.githubusercontent.com/PaddlePaddle/PaddleHub/release/v0.5.0/docs/imgs/paddlehub_figure.jpg) + +PaddleHub主要包括两个功能: +## 命令行工具: + +借鉴了Anaconda和PIP等软件包管理的理念,开发了PaddleHub命令行工具。可以方便快捷的完成模型的搜索、下载、安装、升级、预测等功能。 +更加详细的使用说明可以参考 +[PaddleHub命令行工具](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/cmd_tool.md)。 + +目前的预训练模型覆盖了图像分类、目标检测、词法分析、Transformer、情感分析五大类。 +未来会持续开放更多类型的深度学习模型,如语言模型、视频分类、图像生成等供开发者更便捷的使用PaddlePaddle生态下的预训练模型。 + + +## Fine-tune API: + +通过PaddleHub Fine-tune API,开发者可以更便捷地让预训练模型能更好服务于特定场景的应用。大规模预训练模型结合Fine-tuning,可以在更短的时间完成模型的训练,同时模型具备更好的泛化能力。 + +![PaddleHub-Finetune](https://raw.githubusercontent.com/PaddlePaddle/PaddleHub/release/v0.5.0/docs/imgs/paddlehub_finetune.jpg) + +更多关于Fine-tune API的详细信息和应用案例可以参考: + +* [PaddleHub Fine-tune API](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/finetune_api.md) + +* [PaddleHub文本分类迁移教程](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/turtorial/cv_tl_turtorial.md) + +* [PaddleHub图像分类迁移教程](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/turtorial/nlp_tl_turtorial.md) diff --git a/docs/turtorial/cmd_tool.md b/docs/turtorial/cmd_tool.md new file mode 100644 index 0000000000000000000000000000000000000000..d828dc8fbb246dbd0454bdaf7552dea80a567748 --- /dev/null +++ b/docs/turtorial/cmd_tool.md @@ -0,0 +1,112 @@ +# PaddleHub命令行工具 + +PaddleHub为Module/Model(关于Model和Module的区别,请查看下方的介绍)的管理和使用提供了命令行工具,目前命令行支持以下10个命令: + +## `install` + +用于将Module安装到本地,默认安装在`${HOME}/.paddlehub/module`目录下,当一个Module安装到本地后,用户可以通过其他命令操作该Module(例如,使用该Module进行预测),也可以使用PaddleHub提供的python API,将Module应用到自己的任务中,实现迁移学习 + +## `uninstall` + +用于卸载本地Module + +## `show` + +用于查看本地已安装Module的属性或者指定目录下确定的Model或者Module的属性,包括其名字、版本、描述、作者等信息 + +## `download` + +用于下载百度提供的Module/Model + +`选项` +> `--output_path`:用于指定存放下载文件的目录,默认为当前目录 +> +> `--uncompress`:是否对下载的压缩包进行解压,默认不解压 +> +> `--type`:指定下载的资源类型,当指定Model时,download只会下载Model的资源。默认为All,此时会优先搜索Module资源,如果没有相关的Module资源,则搜索Model +> +## `search` + +通过关键字在服务端检索匹配的Module/Model,当想要查找某个特定模型的Module/Model时,使用search命令可以快速得到结果,例如`hub search ssd`命令,会查找所有包含了ssd字样的Module/Model,命令支持正则表达式,例如`hub search ^s.*`搜索所有以s开头的资源。 + +`注意` +如果想要搜索全部的Module/Model,使用`hub search *`并不生效,这是因为shell会自行进行通配符展开,将*替换为当前目录下的文件名。为了进行全局搜索,用户可以直接键入`hub search` + +## `list` + +列出本地已经安装的Module + +## `run` + +用于执行Module的预测,需要注意的是,并不是所有的模型都支持预测(同样,也不是所有的模型都支持迁移学习),更多关于run命令的细节,请查看下方的`关于预测` + +## `help` + +显示帮助信息 + +## `version` + +显示PaddleHub版本信息 + +## `clear` + +PaddleHub在使用过程中会产生一些缓存数据,这部分数据默认存放在${HOME}/.paddlehub/cache目录下,用户可以通过clear命令来清空缓存 + +# 关于预测 +PaddleHub尽量简化了用户在使用命令行预测时的理解成本,一般来讲,我们将预测分为NLP和CV两大类 + +## NLP类的任务 +输入数据通过--input_text或者--input_file指定。以百度LAC模型(中文词法分析)为例,可以通过以下两个命令实现单行文本和多行文本的分析。 + +```shell +# 单文本预测 +$ hub run lac --input_text "今天是个好日子" +``` +```shell +# 多文本分析 +$ hub run lac --input_file test.txt +``` + +其中test.txt的样例格式如下,每行是一个需要词法分析句子 + +``` +今天是个好日子 +天气预报说今天要下雨 +下一班地铁马上就要到了 +……更多行…… +``` + +## CV类的任务 +输入数据通过`--input_path`或者`--input_file`指定。以SSD模型(单阶段目标检测)为例子,可以通过以下两个命令实现单张图片和多张图片的预测 + +```shell +# 单张照片预测 +$ hub run ssd_mobilenet_v1_pascal --input_path test.jpg +``` +```shell +# 多张照片预测 +$ hub run ssd_mobilenet_v1_pascal --input_file test.txt +``` +其中test.txt的格式为 +``` +cat.jpg +dog.jpg +person.jpg +……更多行…… +``` + +# 关于Model和Module + +在PaddleHub中,我们明确区分开Module/Model两个概念 + +## Model + +Model表示预训练好的参数和模型,当需要使用Model进行预测时,需要模型配套的代码,进行模型的加载,数据的预处理等操作后,才能进行预测。 + +PaddleHub为PaddlePaddle生态的预训练模型提供了统一的管理机制,用户可以使用`hub download`命令的获取到最新的Model,以便进行实验或者其他操作。 + +## Module + +Module是Model的超集,是一个`可执行模块`,一个Module可以支持直接命令行预测,也可以配合PaddleHub Finetune API,通过少量代码实现迁移学习。 +需要注意的是,不是所有的Module都支持命令行预测; (例如BERT/ERNIE Transformer类模型,一般需要搭配任务进行finetune) +也不是所有的Module都可用于finetune(例如LAC词法分析模型,我们不建议用户用于finetune)。 diff --git a/docs/turtorial/cv_tl_turtorial.md b/docs/turtorial/cv_tl_turtorial.md new file mode 100644 index 0000000000000000000000000000000000000000..22f77feace85950b1e70589e3114a3f62c63020a --- /dev/null +++ b/docs/turtorial/cv_tl_turtorial.md @@ -0,0 +1,289 @@ +# 如何使用PaddleHub进行图像分类迁移 + +Fine-tune是迁移学习中使用得最多的方式之一。 + +其主要思想是通过对预训练模型进行结构和参数的 **微调** 来实现模型迁移,从而达到模型适应新领域(Domain)数据的目的。 + +本文以Kaggle的猫狗分类数据集为例子,详细了介绍如何在PaddleHub中进行CV方向的finetune。 + +## 一、准备工作 + +在开始进行fine-tune前,我们需要完成以下工作准备: + +### 1. 安装PaddlePaddle + +PaddleHub是基于PaddlePaddle的预训练模型管理框架,使用PaddleHub前需要先安装PaddlePaddle,如果您本地已经安装了CPU或者GPU版本的PaddlePaddle,那么可以跳过以下安装步骤。 + +```shell +# 安装cpu版本的PaddlePaddle +$ pip install paddlepaddle +``` + +我们推荐您使用大于1.4.0版本的PaddlePaddle,如果您本地版本较低,使用如下命令进行升级 +```shell +$ pip install --upgrade paddlepaddle +``` + +在安装过程中如果遇到问题,您可以到[Paddle官方网站](http://www.paddlepaddle.org/)上查看解决方案 + +### 2. 安装PaddleHub + +通过以下命令来安装PaddleHub + +```shell +$ pip install paddlehub +``` + +如果在安装过程中遇到问题,您可以查看下[FAQ](https://github.com/PaddlePaddle/PaddleHub/wiki/PaddleHub-FAQ)来查找问题解决方案,如果无法解决,请在[Issue](https://github.com/PaddlePaddle/PaddleHub/issues)中反馈问题,我们会尽快分析解决 + +## 二、选择合适的模型 + +首先导入必要的python包 + +```python +# -*- coding: utf8 -*- +import paddlehub as hub +import paddle.fluid as fluid +``` + +接下来我们要在PaddleHub中选择合适的预训练模型来Finetune,由于猫狗分类是一个图像分类任务,因此我们使用经典的ResNet-50作为预训练模型。PaddleHub提供了丰富的图像分类预训练模型,包括了最新的神经网络架构搜索类的PNASNet,我们推荐您尝试不同的预训练模型来获得更好的性能。 + +```python +module_map = { + "resnet50": "resnet_v2_50_imagenet", + "resnet101": "resnet_v2_101_imagenet", + "resnet152": "resnet_v2_152_imagenet", + "mobilenet": "mobilenet_v2_imagenet", + "nasnet": "nasnet_imagenet", + "pnasnet": "pnasnet_imagenet" +} + +module_name = module_map["resnet50"] +module = hub.Module(name = module_name) +``` + +## 三、数据准备 + +接着需要加载图片数据集。为了快速体验,我们直接加载paddlehub提供的猫狗分类数据集,如果想要使用自定义的数据进行体验,请查看`自定义数据` + +```python +# 直接用PaddleHub提供的数据集 +dataset = hub.dataset.DogCat() +``` + +## 四、自定义数据 + +本节说明如何组装自定义的数据,如果想使用猫狗数据集进行体验,可以直接跳过本节。 + +使用自定义数据时,我们需要自己切分数据集,将数据集且分为训练集、验证集和测试集。 + +同时使用三个文本文件来记录对应的图片路径和标签,此外还需要一个标签文件用于记录标签的名称。 +``` +├─data: 数据目录 +  ├─train_list.txt:训练集数据列表 +  ├─test_list.txt:测试集数据列表 +  ├─validate_list.txt:验证集数据列表 + ├─label_list.txt:标签列表 +  └─…… +``` +训练/验证/测试集的数据列表文件的格式如下 +``` +图片1路径 图片1标签 +图片2路径 图片2标签 +... +``` +标签列表文件的格式如下 +``` +分类1名称 +分类2名称 +... +``` +使用如下的方式进行加载数据,生成数据集对象 + +`注意事项`: +1. num_labels要填写实际的分类数量,如猫狗分类该字段值为2,food101该字段值为101,下文以`2`为例子 +2. base_path为数据集实际路径,需要填写全路径,下文以`/test/data`为例子 +3. 训练/验证/测试集的数据列表文件中的图片路径需要相对于base_path的相对路径,例如图片的实际位置为`/test/data/dog/dog1.jpg`,base_path为`/test/data`,则文件中填写的路径应该为`dog/dog1.jpg` + +```python +# 使用本地数据集 +class MyDataSet(hub.dataset.base_cv_dataset.ImageClassificationDataset): + def __init__(self): + self.base_path = "/test/data" + self.train_list_file = "train_list.txt" + self.test_list_file = "test_list.txt" + self.validate_list_file = "validate_list.txt" + self.label_list_file = "label_list.txt" + self.label_list = None + self.num_labels = 2 + +dataset = MyDataSet() +``` + +## 五、生成Reader + +接着生成一个图像分类的reader,reader负责将dataset的数据进行预处理,接着以特定格式组织并输入给模型进行训练。 + +当我们生成一个图像分类的reader时,需要指定输入图片的大小 + +```python +data_reader = hub.reader.ImageClassificationReader( + image_width=module.get_expected_image_width(), + image_height=module.get_expected_image_height(), + images_mean=module.get_pretrained_images_mean(), + images_std=module.get_pretrained_images_std(), + dataset=dataset) +``` + +## 六、组建Finetune Task + +有了合适的预训练模型和准备要迁移的数据集后,我们开始组建一个Task。 + +由于猫狗分类是一个二分类的任务,而我们下载的分类module是在ImageNet数据集上训练的千分类模型,所以我们需要对模型进行简单的微调,把模型改造为一个二分类模型: + +1. 获取module的上下文环境,包括输入和输出的变量,以及Paddle Program; +2. 从输出变量中找到特征图提取层feature_map; +3. 在feature_map后面接入一个全连接层,生成Task; + +```python +input_dict, output_dict, program = module.context(trainable=True) + +img = input_dict["image"] +feature_map = output_dict["feature_map"] + +task = hub.create_img_cls_task( + feature=feature_map, num_classes=dataset.num_labels) + +feed_list = [img.name, task.variable("label").name] +``` + +## 七、选择运行时配置 + +在进行Finetune前,我们可以设置一些运行时的配置,例如如下代码中的配置,表示: + +> `use_cuda`:设置为False表示使用CPU进行训练。如果您本机支持GPU,且安装的是GPU版本的PaddlePaddle,我们建议您将这个选项设置为True; +> +> `epoch`:要求Finetune的任务只遍历1次训练集; +> +> `batch_size`:每次训练的时候,给模型输入的每批数据大小为32,模型训练时能够并行处理批数据,因此batch_size越大,训练的效率越高,但是同时带来了内存的负荷,过大的batch_size可能导致内存不足而无法训练,因此选择一个合适的batch_size是很重要的一步; +> +> `log_interval`:每隔10 step打印一次训练日志; +> +> `eval_interval`:每隔50 step在验证集上进行一次性能评估; +> +> `checkpoint_dir`:将训练的参数和数据保存到cv_finetune_turtorial_demo目录中; +> +> `strategy`:使用DefaultFinetuneStrategy策略进行finetune; + +更多运行配置,请查看[RunConfig](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/RunConfig.md) + +```python +config = hub.RunConfig( + use_cuda=False, + num_epoch=1, + checkpoint_dir="cv_finetune_turtorial_demo", + batch_size=32, + log_interval=10, + eval_interval=50, + strategy=hub.finetune.strategy.DefaultFinetuneStrategy()) +``` + +## 八、开始Finetune + +我们选择`finetune_and_eval`接口来进行模型训练,这个接口在finetune的过程中,会周期性的进行模型效果的评估,以便我们了解整个训练过程的性能变化。 + +```python +hub.finetune_and_eval( + task, feed_list=feed_list, data_reader=data_reader, config=config) +``` + +## 九、查看训练过程的效果 + +训练过程中的性能数据会被记录到本地,我们可以通过visualdl来可视化这些数据。 + +我们在shell中输入以下命令来启动visualdl,其中`${HOST_IP}`为本机IP,需要用户自行指定 +```shell +$ visualdl --logdir ./cv_finetune_turtorial_demo/vdllog --host ${HOST_IP} --port 8989 +``` + +启动服务后,我们使用浏览器访问`${HOST_IP}:8989`,可以看到训练以及预测的loss曲线和accuracy曲线 +![img](https://github.com/PaddlePaddle/PaddleHub/blob/release/v0.5.0/docs/imgs/cv_turtorial_vdl_log.jpg) + +## 十、使用模型进行预测 + +当Finetune完成后,我们使用模型来进行预测,整个预测流程大致可以分为以下几步: +1. 构建网络 +2. 生成预测数据的Reader +3. 切换到预测的Program +4. 加载预训练好的参数 +5. 运行Program进行预测 + +通过以下命令来获取测试的图片 +`注意`:以下示例仍然以猫狗分类为例子,其他数据集所用的测试图片请自行准备 +```shell +$ wget --no-check-certificate https://paddlehub.bj.bcebos.com/resources/test_img_cat.jpg +$ wget --no-check-certificate https://paddlehub.bj.bcebos.com/resources/test_img_dog.jpg +``` + +完整预测代码如下: +```python +import os +import numpy as np +import paddle.fluid as fluid +import paddlehub as hub + +# Step 1: build Program +module_map = { + "resnet50": "resnet_v2_50_imagenet", + "resnet101": "resnet_v2_101_imagenet", + "resnet152": "resnet_v2_152_imagenet", + "mobilenet": "mobilenet_v2_imagenet", + "nasnet": "nasnet_imagenet", + "pnasnet": "pnasnet_imagenet" +} + +module_name = module_map["resnet50"] +module = hub.Module(name = module_name) +input_dict, output_dict, program = module.context(trainable=False) +img = input_dict["image"] +feature_map = output_dict["feature_map"] + +dataset = hub.dataset.DogCat() +task = hub.create_img_cls_task( + feature=feature_map, num_classes=dataset.num_labels) +feed_list = [img.name] + +# Step 2: create data reader +data = [ + "test_img_dog.jpg", + "test_img_cat.jpg" +] + +data_reader = hub.reader.ImageClassificationReader( + image_width=module.get_expected_image_width(), + image_height=module.get_expected_image_height(), + images_mean=module.get_pretrained_images_mean(), + images_std=module.get_pretrained_images_std(), + dataset=None) + +predict_reader = data_reader.data_generator( + phase="predict", batch_size=1, data=data) + +label_dict = dataset.label_dict() + +# Step 3: switch to inference program +with fluid.program_guard(task.inference_program()): + # Step 4: load pretrained parameters + place = fluid.CPUPlace() + exe = fluid.Executor(place) + pretrained_model_dir = os.path.join("cv_finetune_turtorial_demo", "best_model") + fluid.io.load_persistables(exe, pretrained_model_dir) + feeder = fluid.DataFeeder(feed_list=feed_list, place=place) + # Step 5: predict + for index, batch in enumerate(predict_reader()): + result, = exe.run( + feed=feeder.feed(batch), fetch_list=[task.variable('probs')]) + predict_result = np.argsort(result[0])[::-1][0] + print("input %i is %s, and the predict result is %s" % + (index+1, data[index], label_dict[predict_result])) +``` diff --git a/docs/turtorial/nlp_tl_turtorial.md b/docs/turtorial/nlp_tl_turtorial.md new file mode 100644 index 0000000000000000000000000000000000000000..603c3d41e7585e272c1ea2ca2272416d78bc1e34 --- /dev/null +++ b/docs/turtorial/nlp_tl_turtorial.md @@ -0,0 +1,145 @@ +# 如何使用PaddleHub完成文本分类迁移 + +文本分类迁移是NLP迁移学习中最常见的一个任务之一。教程以情感分析任务为例子,介绍下如何使用PaddleHub+Fine-tune API快速完成文本分类迁移任务。 + +## 教程前置条件 + +* 已完成PaddlePaddle和PaddleHub的安装 +* 对BERT/ERNIE等Transformer类模型有基本的了解 + + +## ERNIE介绍 + +ERNIE是百度开放的基于Transformer知识增强的语义表示模型(**E**nhanced **R**epresentation from k**N**owledge **I**nt**E**gration)ERNIE预训练模型结合Fine-tuning,可以在中文情感分析任务上可以得到非常不错的效果。更多的介绍可以参考[ERNIE](https://github.com/PaddlePaddle/LARK/tree/develop/ERNIE) + +## 快速开始 + +### 准备环境 +```python +import paddle.fluid as fluid +import paddlehub as hub +``` +### 加载预训练模型 + +通过PaddleHub,只需要一行代码,即可以获取到PaddlePaddle生态下的预训练模型。 + +```python +module = hub.Module(name="ernie") + +inputs, outputs, program = module.context(trainable="True", max_seq_len=128) +``` + +* 通过`hub.Module(name="ernie")`PaddleHub会自动下载并加载ERNIE模型。 +* `module.context`接口中,`trainable=True`则预训练模型的参数可以被训练,`trainble=False`则讲预训练模型参数不可修改,仅作为特征提取器使用。 +* `max_seq_len`是ERNIE/BERT模型特有的参数,控制模型最大的序列识别长度,这一参数与任务相关,如果显存有限,切任务文本长度较短,可以适当调低这一参数。如果处理文本序列的unicode字符长度超过`max_seq_len`,则模型会对序列进行截断。通常来说,128是一个性能均衡的默认值。 + +#### ERNIE的输入输出结构 + +ERNIE模型与BERT在结构上类似,如下图所示: +![ERNIE结构图](https://raw.githubusercontent.com/PaddlePaddle/PaddleHub/release/v0.5.0/docs/imgs/ERNIE_input_output.png) + +ERNIE的在PaddleHub中的的输入有4个Tensor,分别是: +* `input_ids`: 文本序列后切词的ID; +* `position_ids`: 文本序列的位置ID; +* `segment_ids`: 文本序列的类型; +* `input_mask`: 序列的mask信息,主要用于对padding的标识; + +前三个输入与BERT模型的论文输入对应,第四个输入为padding所需的标识信息。更多细节信息可参考论文[BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding](https://arxiv.org/abs/1810.04805) + +ERNIE的输出的话有两类,分别是 + +* `pooled_output`: 句子粒度特征,对应的shape为`[batch_size, hidden_size]`,可用于句子分类或句对分类任务。 +* `sequence_output`: 词粒度的特征,对应的shape为`[batch_size, max_seq_len, hidden_size]`, 可用于序列标注任务。 + +通过以下代码即可获取到对应特征的Tensor,可用于后续的组网工作。 +```python +inputs, outputs, program = module.context(trainable="True", max_seq_len=128) + +pooled_output = outputs["pooled_output"] +sequence_output = outputs["sequence_output"] +``` + +### 准备数据及数据预处理 + +```python +ds = hub.dataset.ChnSentiCorp() +reader = hub.reader.ClassifyReader(dataset=ds, vocab_path=module.get_vocab_path(), max_seq_len=128) +``` + +通过`hub.dataset.ChnSentiCorp()`会自动获取数据集,可以通过以下代码查看训练集中的文本与标注: +```python +ds = hub.dataset.ChnSentiCorp() +for e in ds.get_train_examples(): + print(e.text_a, e.label) +``` + + +`ClassifyReader`是专门ERNIE/BERT模型的数据预处理器,会根据模型词典,进行字粒度的切词,其中英文以词粒度进行分割,而中文和其他字符采用unicode为单位的字粒度切词。因此与传统的中文分词器有所区别,详细代码可以参考 [tokenization.py](https://github.com/PaddlePaddle/PaddleHub/blob/release/v0.5.0/paddlehub/reader/tokenization.py) + +`ClassifyReader`的参数有以下三个: +* `dataset`: 传入PaddleHub Dataset; +* `vocab_path`: 传入ERNIE/BERT模型对应的词表文件路径; +* `max_seq_len`: ERNIE模型的最大序列长度,若序列长度不足,会通过padding方式补到`max_seq_len`, 若序列长度大于该值,则会以截断方式让序列长度为`max_seq_len`; + + +### 创建迁移学习任务 + +```python +task = hub.create_text_cls_task(feature=pooled_output, num_classes=ds.num_labels) +``` + +### 配置优化策略 + +适用于ERNIE/BERT这类Transformer模型的迁移优化策略为`AdamWeightDecayStrategy` +```python +strategy=hub.AdamWeightDecayStrategy( + learning_rate=1e-4, + lr_scheduler="linear_decay", + warmup_proportion=0.0, + weight_decay=0.01 +) +``` +* `learning_rate`: 最大学习率 +* `lr_scheduler`: 有`linear_decay`和`noam_decay`两种衰减策略可选, 如下图所示: +* `warmup_proprotion`: 训练预热的比例,若设置为0.1, 则会在前10%的训练step中学习率逐步提升到`learning_rate` +* `weight_decay`: 权重衰减,类似模型正则项策略,避免模型overfitting + +![学习率衰减策略](https://raw.githubusercontent.com/PaddlePaddle/PaddleHub/release/v0.5.0/docs/imgs/decay_strategy.png) + +### 设置运行配置 + +关于运行配置的详细信息可以查看[RunConfig](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/api/RunConfig.md) + +```python +config = hub.RunConfig( + use_cuda=True, + num_epoch=3, + batch_size=32, + strategy=strategy) +``` +请根据实际情况选择`use_cuda`和`batch_size`,若出现显存不足的情况,请调低`batch_size` + +### feed_list +```python +feed_list = [ + inputs["input_ids"].name, inputs["position_ids"].name, + inputs["segment_ids"].name, inputs["input_mask"].name, + task.variable("label").name +] +``` +`feed_list`的配置需要与ClassifyReader的Tensor输出顺序保持一致。请注意,此处的tensor name顺序不可以改变,因为`ClassifyReader`就是按照这一顺序返回ERNIE所需的输入tensor。 + +### 启动Fine-tuning + +当配置好迁移任务、数据预处理、`FeedList`和`RunConfig`后,就可以使用`finetune_and_eval`启动Fine-tuning任务了 + +```python +hub.finetune_and_eval( + task=cls_task, + data_reader=reader, + feed_list=feed_list, + config=config) +``` + +`finetune_and_eval`接口会自动完成验证集评估,并保存最优模型,并自动完成Visual DL可视化,如下图所示,在`/path/to/ckpt/vdllog`中会保存Visual DL的打点信息,如下图所示启动Visual DL后即可看到Fine-tuning的变化过程, 包括Loss变化,训练集和验证集的准确率情况等。 +![VisualDL可视化](https://raw.githubusercontent.com/PaddlePaddle/PaddleHub/release/v0.5.0/docs/imgs/finetune_vdl.png) diff --git a/docs/turtorial/paddlehub_tl.md b/docs/turtorial/paddlehub_tl.md new file mode 100644 index 0000000000000000000000000000000000000000..631f599315f26c11926ab9943c431c084bba671d --- /dev/null +++ b/docs/turtorial/paddlehub_tl.md @@ -0,0 +1,27 @@ +# PaddleHub Finetune API与迁移学习 + +## 简述 +迁移学习(Transfer Learning)是属于机器学习的一个子研究领域,该研究领域的目标在于利用数据、任务、或模型之间的相似性,将在旧领域学习过的知识,迁移应用于新领域中 + +基于以下几个原因,迁移学习吸引了很多研究者投身其中: + +* 一些研究领域只有少量标注数据,且数据标注成本较高,不足以训练一个足够鲁棒的神经网络 +* 大规模神经网络的训练依赖于大量的计算资源,这对于一般用户而言难以实现 +* 应对于普适化需求的模型,在特定应用上表现不尽如人意 + +目前在深度学习领域已经取得了较大的发展,本文让用户了解如何快速使用PaddleHub进行迁移学习。 更多关于Transfer Learning的知识,请参考: + +http://cs231n.github.io/transfer-learning/ + +https://papers.nips.cc/paper/5347-how-transferable-are-features-in-deep-neural-networks.pdf + +http://ftp.cs.wisc.edu/machine-learning/shavlik-group/torrey.handbook09.pdf + +## PaddleHub中的迁移学习 + +PaddleHub提供了基于PaddlePaddle框架实现的Finetune API, 重点针对大规模预训练模型的Fine-tuning任务做了高阶的抽象,帮助用户使用最少的代码快速、稳定地完成预训练模型的fine-tuning。 + +教程会涵盖CV领域的图像分类迁移,和NLP文本分类迁移两种任务。 + +* [CV教程](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/turtorial/cv_tl_turtorial.md) +* [NLP教程](https://github.com/PaddlePaddle/PaddleHub/tree/release/v0.5.0/docs/turtorial/nlp_tl_turtorial.md) diff --git a/docs/turtorial/user_define_dataset.md b/docs/turtorial/user_define_dataset.md new file mode 100644 index 0000000000000000000000000000000000000000..031a74da6cff19179d88928d87ab624204b951db --- /dev/null +++ b/docs/turtorial/user_define_dataset.md @@ -0,0 +1,92 @@ +训练一个新任务时,如果从零开始训练时,这将是一个耗时的过程,并且效果可能达不到理想的效果,此时您可以利用PaddleHub提供的预训练模型进行具体任务的FineTune。您只需要对自定义数据进行相应的预处理,随后输入预训练模型中,即可得到相应的结果。本文以预训练模型ERNIE对文本分类任务进行FineTune为例,说明如何利用PaddleHub适配自定义数据完成FineTune。 + +# 数据准备 + +> * train.tsv 训练集 +> * dev.tsv 验证集 +> * test.tsv 测试集 + +相应的数据格式为第一列是文本的编号(guid),第二列为文本内容,第三列为另一文本内容,第四列为标签,列与列之间以Tab键分隔。 +**NOTE:** 若是单文本分类任务,则第三列相应内容为空。 + +``` +9566 挺无聊的一本书。内容很贴近生活,可能是因为太贴近生活了,反而没什么可看的了。 None 0 +9529 内存数量配置偏低 内存插槽于掌托下,需拆卸安装,不方便 蓝牙模块采用软件控制 None 0 +9544 这本书看得我实在是没什么感觉。作者说的很抽象,我感觉挺空洞的,没什么意思。有点后悔买这本书。 None 0 +``` + +# 自定义数据预处理 +在源码paddlehub/dataset下自定义demodataset.py,便于数据预处理。 + +**示例** +```python +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from collections import namedtuple +import codecs +import os +import csv + +from paddlehub.dataset import InputExample, HubDataset + +class DemoDataset(HubDataset): + """DemoDataset""" + def __init__(self): + self.dataset_dir = "path/to/dataset" + + self._load_train_examples() + self._load_test_examples() + self._load_dev_examples() + + def _load_train_examples(self): + self.train_file = os.path.join(self.dataset_dir, "train.tsv") + self.train_examples = self._read_tsv(self.train_file) + + def _load_dev_examples(self): + self.dev_file = os.path.join(self.dataset_dir, "dev.tsv") + self.dev_examples = self._read_tsv(self.dev_file) + + def _load_test_examples(self): + self.test_file = os.path.join(self.dataset_dir, "test.tsv") + self.test_examples = self._read_tsv(self.test_file) + + def get_train_examples(self): + return self.train_examples + + def get_dev_examples(self): + return self.dev_examples + + def get_test_examples(self): + return self.test_examples + + def get_labels(self): + """define it according the real dataset""" + return ["0", "1"] + + @property + def num_labels(self): + """ + Return the number of labels in the dataset. + """ + return len(self.get_labels()) + + def _read_tsv(self, input_file, quotechar=None): + """Reads a tab separated value file.""" + with codecs.open(input_file, "r", encoding="UTF-8") as f: + reader = csv.reader(f, delimiter="\t", quotechar=quotechar) + examples = [] + seq_id = 0 + header = next(reader) # skip header + for line in reader: + example = InputExample( + guid=seq_id, label=line[0], text_a=line[1]) + seq_id += 1 + examples.append(example) + + return examples +``` +*** + +之后,您就可以通过hub.dataset.DemoDataset()获取自定义数据集了。进而配合ClassifyReader以及预训练模型如ERNIE完成文本分类任务。