瀏覽代碼

Merge branch 'develop' of https://github.com/PaddlePaddle/PaddleX into develop_qh

FlyingQianMM 5 年之前
父節點
當前提交
0f394b0758

+ 5 - 4
README.md

@@ -11,13 +11,13 @@ PaddleX是基于飞桨核心框架、开发套件和工具组件的深度学习
 
 ## 特点
 
-- **全流程打通** 
+- **全流程打通**
   - **数据准备**:支持[EasyData智能数据服务平台](https://ai.baidu.com/easydata/)数据协议,通过平台便捷完成智能标注,低质数据清洗工作, 同时兼容主流标注工具协议, 助力开发者更快完成数据准备工作。
   - **模型训练**:集成[PaddleClas](https://github.com/PaddlePaddle/PaddleClas), [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection), [PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg)视觉开发套件,丰富的高质量预训练模型,更快实现工业级模型效果。
   - **模型调优**:内置模型可解释性模块、[VisualDL](https://github.com/PaddlePaddle/VisualDL)可视化分析组件, 提供丰富的信息更好地理解模型,优化模型。
   - **多端安全部署**:内置[PaddleSlim](https://github.com/PaddlePaddle/PaddleSlim)模型压缩工具和**模型加密部署模块**,结合Paddle Inference或[Paddle Lite](https://github.com/PaddlePaddle/Paddle-Lite)便捷完成高性能的多端安全部署。
 
-- **融合产业实践** 
+- **融合产业实践**
   - 精选飞桨产业实践的成熟模型结构,开放案例实践教程,加速开发者产业落地。
 
 - **易用易集成**
@@ -47,13 +47,14 @@ PaddleX提供两种开发模式,满足不同场景和用户需求:
 ```
 pip install paddlex -i https://mirror.baidu.com/pypi/simple
 ```
+安装的相关问题参考[PaddleX安装](https://paddlex.readthedocs.io/zh_CN/latest/install.html)
 
 ### PaddleX-GUI安装
 
 进入PaddleX官网[下载使用](https://www.paddlepaddle.org.cn/paddle/paddlex),申请下载绿色安装包,开箱即用。
 Paddle-GUI的使用教程可参考[PaddleX-GUI模式使用教程](https://paddlex.readthedocs.io/zh_CN/latest/paddlex_gui/index.html)
 
-## 使用文档 
+## 使用文档
 
 推荐访问[PaddleX在线使用文档](https://paddlex.readthedocs.io/zh_CN/latest/index.html),快速查阅读使用教程和API文档说明。
 
@@ -83,7 +84,7 @@ Paddle-GUI的使用教程可参考[PaddleX-GUI模式使用教程](https://paddle
 
   **`v1.0.0`**
   * 初始版本发布。
-  
+
 ## 贡献代码
 
 我们非常欢迎您为PaddleX贡献代码或者提供使用建议。如果您可以修复某个issue或者增加一个新功能,欢迎给我们提交Pull Requests.

+ 13 - 10
docs/FAQ.md

@@ -1,22 +1,25 @@
 # 常见问题
 
-## 1. 训练过程因显存不够出错
+## 1. 训练参数如何调整
+> 参考[参数调整文档](appendix/parameters.md)
+
+## 2. 训练过程因显存不够出错
 
 > 通过使用在终端`nvidia-smi`命令,查看GPU是否被其它任务占用,尝试清除其它任务;  
 > 调低训练时的`batch_size`参数,从而降低显存的要求,注意需等比例调低`learning_rate`等参数;
 > 选用更小的模型或backbone。
 
-## 2. 是否有更小的模型,适用于更低配置的设备上运行
+## 3. 是否有更小的模型,适用于更低配置的设备上运行
 > 可以使用模型裁剪,参考文档[模型裁剪使用教程](slim/prune.md),通过调整裁剪参数,可以控制模型裁剪后的大小,在实际实验中,如VOC检测数据,使用yolov3-mobilenet,原模型大小为XXM,裁剪后为XX M,精度基本保持不变
 
-## 3. 如何配置训练时GPU的卡数
+## 4. 如何配置训练时GPU的卡数
 > 通过在终端export环境变量,或在Python代码中设置,可参考文档[CPU/多卡GPU训练](gpu_configure.md)
 
-## 4. 想将之前训练的模型参数上继续训练
+## 5. 想将之前训练的模型参数上继续训练
 > 在训练调用`train`接口时,将`pretrain_weights`设为之前的模型保存路径即可
 
 
-## 5. PaddleX保存的模型分为正常训练过程中产生、裁剪训练产生、导出为部署模型和量化保存这么多种,有什么差别,怎么区分
+## 6. PaddleX保存的模型分为正常训练过程中产生、裁剪训练产生、导出为部署模型和量化保存这么多种,有什么差别,怎么区分
 
 **不同模型的功能差异**
 
@@ -40,20 +43,20 @@
 >> 通过模型目录下model.yml文件中`status`字段来区别不同的模型类型, 'Normal'、'Prune'、'Infer'、'Quant'分别表示正常模型训练保存、裁剪训练保存、导出的部署模型、量化保存模型
 
 
-## 6. 模型训练需要太久时间,或者训练速度太慢,怎么提速
+## 7. 模型训练需要太久时间,或者训练速度太慢,怎么提速
 > 1.模型训练速度与用户选定的模型大小,和设定的`batch_size`相关,模型大小可直接参考[模型库](model_zoo.md)中的指标,一般而言,模型越大,训练速度就越慢;  
 
 > 2.在模型速度之外,模型训练完成所需的时间又与用户设定的`num_epochs`迭代轮数相关,用户可以通过观察模型在验证集上的指标来决定是否提示结束掉训练进程(训练时设定`save_interval_epochs`参数,训练过程会每间隔`save_interval_epochs`轮数在验证集上计算指标,并保存模型);  
 
-## 7. 如何设定迭代的轮数
+## 8. 如何设定迭代的轮数
 > 1. 用户自行训练时,如不确定迭代的轮数,可以将轮数设高一些,同时注意设置`save_interval_epochs`,这样模型迭代每间隔相应轮数就会在验证集上进行评估和保存,可以根据不同轮数模型在验证集上的评估指标,判断模型是否已经收敛,若模型已收敛,可以自行结束训练进程
 >
-## 8. 只有CPU,没有GPU,如何提升训练速度
+## 9. 只有CPU,没有GPU,如何提升训练速度
 > 当没有GPU时,可以根据自己的CPU配置,选择是否使用多CPU进行训练,具体配置方式可以参考文档[多卡CPU/GPU训练](gpu_configure.md)
 >
-## 9. 电脑不能联网,训练时因为下载预训练模型失败,如何解决
+## 10. 电脑不能联网,训练时因为下载预训练模型失败,如何解决
 > 可以预先通过其它方式准备好预训练模型,然后训练时自定义`pretrain_weights`即可,可参考文档[无联网模型训练](how_to_offline_run.md)
 
-## 10. 每次训练新的模型,都需要重新下载预训练模型,怎样可以下载一次就搞定
+## 11. 每次训练新的模型,都需要重新下载预训练模型,怎样可以下载一次就搞定
 > 1.可以按照9的方式来解决这个问题  
 > 2.每次训练前都设定`paddlex.pretrain_dir`路径,如设定`paddlex.pretrain_dir='/usrname/paddlex`,如此下载完的预训练模型会存放至`/usrname/paddlex`目录下,而已经下载在该目录的模型也不会再次重复下载

+ 1 - 7
docs/appendix/index.rst

@@ -8,13 +8,7 @@
 
    model_zoo.md
    metrics.md
+   parameters.md
    how_to_convert_dataset.md
    datasets.md
 
-
-* PaddleX版本: v0.1.7
-* 项目官网: http://www.paddlepaddle.org.cn/paddle/paddlex  
-* 项目GitHub: https://github.com/PaddlePaddle/PaddleX/tree/develop  
-* 官方QQ用户群: 1045148026  
-* GitHub Issue反馈: http://www.github.com/PaddlePaddle/PaddleX/issues
-

+ 25 - 0
docs/appendix/parameters.md

@@ -0,0 +1,25 @@
+# 训练参数调整
+
+PaddleX所有训练接口中,内置的参数均为根据单GPU卡相应batch_size下的较优参数,用户在自己的数据上训练模型,涉及到参数调整时,如无太多参数调优经验,则可参考如下方式
+
+## 1.Epoch数的调整
+Epoch数是模型训练过程,迭代的轮数,用户可以设置较大的数值,根据模型迭代过程在验证集上的指标表现,来判断模型是否收敛,进而提前终止训练。此外也可以使用`train`接口中的`early_stop`策略,模型在训练过程会自动判断模型是否收敛自动中止。
+
+## 2.Batch Size的调整
+Batch Size指模型在训练过程中,一次性处理的样本数量, 如若使用多卡训练, batch_size会均分到各张卡上(因此需要让batch size整除卡数)。这个参数跟机器的显存/内存高度相关,`batch_size`越高,所消耗的显存/内存就越高。PaddleX在各个`train`接口中均配置了默认的batch size,如若用户调整batch size,则也注意需要对应调整其它参数,如下表所示展示YOLOv3在训练时的参数配置
+
+|       参数       |     默认值    |      调整比例       |      示例     |
+|:---------------- | :------------ | :------------------ | :------------ |
+| train_batch_size |      8        |   调整为 8*alpha    |      16       |
+| learning_rate    |    1.0/8000   |   调整为 alpha/8000 |    2.0/8000   |
+| warmup_steps     |    1000       |   调整为 1000/alpha<br>(该参数也可以自行根据数据情况调整) |     500       |
+| lr_decay_epochs  | [213, 240]    |   不变              |   [213, 240]  |
+
+
+更多训练接口可以参考
+- [分类模型-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/classification.html#train)
+- [目标检测检测FasterRCNN-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/detection.html#id2)
+- [目标检测YOLOv3-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/detection.html#train)
+- [实例分割MaskRCNN-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/instance_segmentation.html#train)
+- [语义分割DeepLabv3p-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#train)
+- [语义分割UNet](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#id2)

+ 1 - 1
paddlex/__init__.py

@@ -53,4 +53,4 @@ log_level = 2
 
 from . import interpret
 
-__version__ = '0.2.0.github'
+__version__ = '1.0.1.github'

+ 7 - 1
paddlex/interpret/core/interpretation_algorithms.py

@@ -242,7 +242,13 @@ class NormLIME(object):
         self.label_names = label_names
 
     def predict_cluster_labels(self, feature_map, segments):
-        return self.kmeans_model.predict(get_feature_for_kmeans(feature_map, segments))
+        X = get_feature_for_kmeans(feature_map, segments)
+        try:
+            cluster_labels = self.kmeans_model.predict(X)
+        except AttributeError:
+            from sklearn.metrics import pairwise_distances_argmin_min
+            cluster_labels, _ = pairwise_distances_argmin_min(X, self.kmeans_model.cluster_centers_)
+        return cluster_labels
 
     def predict_using_normlime_weights(self, pred_labels, predicted_cluster_labels):
         # global weights

+ 9 - 8
paddlex/interpret/core/lime_base.py

@@ -30,17 +30,10 @@ The code in this file (lime_base.py) is modified from https://github.com/marcotc
 
 import numpy as np
 import scipy as sp
-import sklearn
-import sklearn.preprocessing
-from skimage.color import gray2rgb
-from sklearn.linear_model import Ridge, lars_path
-from sklearn.utils import check_random_state
 
 import tqdm
 import copy
 from functools import partial
-from skimage.segmentation import quickshift
-from skimage.measure import regionprops
 
 
 class LimeBase(object):
@@ -59,6 +52,7 @@ class LimeBase(object):
                 generate random numbers. If None, the random state will be
                 initialized using the internal numpy seed.
         """
+        from sklearn.utils import check_random_state
         self.kernel_fn = kernel_fn
         self.verbose = verbose
         self.random_state = check_random_state(random_state)
@@ -75,6 +69,7 @@ class LimeBase(object):
             (alphas, coefs), both are arrays corresponding to the
             regularization parameter and coefficients, respectively
         """
+        from sklearn.linear_model import lars_path
         x_vector = weighted_data
         alphas, _, coefs = lars_path(x_vector,
                                      weighted_labels,
@@ -106,6 +101,7 @@ class LimeBase(object):
     def feature_selection(self, data, labels, weights, num_features, method):
         """Selects features for the model. see interpret_instance_with_data to
            understand the parameters."""
+        from sklearn.linear_model import Ridge
         if method == 'none':
             return np.array(range(data.shape[1]))
         elif method == 'forward_selection':
@@ -213,7 +209,7 @@ class LimeBase(object):
             score is the R^2 value of the returned interpretation
             local_pred is the prediction of the interpretation model on the original instance
         """
-
+        from sklearn.linear_model import Ridge
         weights = self.kernel_fn(distances)
         labels_column = neighborhood_labels[:, label]
         used_features = self.feature_selection(neighborhood_data,
@@ -376,6 +372,7 @@ class LimeImageInterpreter(object):
                 generate random numbers. If None, the random state will be
                 initialized using the internal numpy seed.
         """
+        from sklearn.utils import check_random_state
         kernel_width = float(kernel_width)
 
         if kernel is None:
@@ -422,6 +419,10 @@ class LimeImageInterpreter(object):
             An ImageIinterpretation object (see lime_image.py) with the corresponding
             interpretations.
         """
+        import sklearn
+        from skimage.measure import regionprops
+        from skimage.segmentation import quickshift
+        from skimage.color import gray2rgb
         if len(image.shape) == 2:
             image = gray2rgb(image)
 

+ 10 - 6
paddlex/interpret/core/normlime_base.py

@@ -17,6 +17,7 @@ import numpy as np
 import glob
 
 from paddlex.interpret.as_data_reader.readers import read_image
+import paddlex.utils.logging as logging
 from . import lime_base
 from ._session_preparation import compute_features_for_kmeans, h_pre_models_kmeans
 
@@ -113,11 +114,11 @@ def precompute_lime_weights(list_data_, predict_fn, num_samples, batch_size, sav
             save_path = os.path.join(save_dir, save_path)
 
         if os.path.exists(save_path):
-            print(f'{save_path} exists, not computing this one.')
+            logging.info(save_path + ' exists, not computing this one.', use_color=True)
             continue
 
-        print('processing', each_data_ if isinstance(each_data_, str) else data_index,
-              f', {data_index}/{len(list_data_)}')
+        logging.info('processing'+each_data_ if isinstance(each_data_, str) else data_index + \
+              f'+{data_index}/{len(list_data_)}', use_color=True)
 
         image_show = read_image(each_data_)
         result = predict_fn(image_show)
@@ -149,9 +150,12 @@ def precompute_lime_weights(list_data_, predict_fn, num_samples, batch_size, sav
         interpreter = algo.interpret_instance(image_show[0], predict_fn, pred_label, 0,
                                           num_samples=num_samples, batch_size=batch_size)
 
-        cluster_labels = kmeans_model.predict(
-            get_feature_for_kmeans(compute_features_for_kmeans(image_show).transpose((1, 2, 0)), interpreter.segments)
-        )
+        X = get_feature_for_kmeans(compute_features_for_kmeans(image_show).transpose((1, 2, 0)), interpreter.segments)
+        try:
+            cluster_labels = kmeans_model.predict(X)
+        except AttributeError:
+            from sklearn.metrics import pairwise_distances_argmin_min
+            cluster_labels, _ = pairwise_distances_argmin_min(X, kmeans_model.cluster_centers_)
         save_one_lime_predict_and_kmean_labels(
             interpreter.local_weights, pred_label,
             cluster_labels,

+ 2 - 2
setup.py

@@ -19,7 +19,7 @@ long_description = "PaddleX. A end-to-end deeplearning model development toolkit
 
 setuptools.setup(
     name="paddlex",
-    version='0.2.0',
+    version='1.0.1',
     author="paddlex",
     author_email="paddlex@baidu.com",
     description=long_description,
@@ -30,7 +30,7 @@ setuptools.setup(
     setup_requires=['cython', 'numpy'],
     install_requires=[
         "pycocotools;platform_system!='Windows'", 'pyyaml', 'colorama', 'tqdm',
-        'paddleslim==1.0.1', 'visualdl>=2.0.0a2'
+        'paddleslim==1.0.1', 'visualdl>=2.0.0b', 'paddlehub>=1.6.2'
     ],
     classifiers=[
         "Programming Language :: Python :: 3",