diff --git a/README.md b/README.md index 59b3232..19be9c5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

- **基于飞桨框架开发的高性能遥感图像处理开发套件,端到端地完成从训练到部署的全流程遥感深度学习应用。** + **基于飞桨框架开发的高性能遥感影像处理开发套件,帮助您端到端地完成从数据预处理到模型部署的全流程遥感深度学习应用。** [![license](https://img.shields.io/badge/license-Apache%202-blue.svg)](LICENSE) @@ -19,19 +19,25 @@ ## 简介 -PaddleRS是遥感科研院所、相关高校共同基于飞桨开发的遥感处理平台,支持遥感图像分类,目标检测,图像分割,以及变化检测等常用遥感任务,帮助开发者更便捷地完成从训练到部署全流程遥感深度学习应用。 +PaddleRS是百度飞桨、遥感科研院所及相关高校共同开发的基于飞桨的遥感影像智能化处理套件,支持图像分割、目标检测、场景分类、变化检测以及图像复原等常见遥感任务。PaddleRS致力于帮助遥感领域科研从业者快速完成算法的研发、验证和调优,以及帮助投身于产业实践的开发者便捷地实现从数据预处理到模型部署的全流程遥感深度学习应用。
- +
## 特性 -* **特有的遥感数据处理模块**:针对遥感行业数据特点,提供了大尺幅数据切片与拼接,支持读取`tif`、`png`、 `jpeg`、 `bmp`、 `img`以及 `npy`等格式,支持地理信息保存和超分辨率。 +PaddleRS具有以下五大特色: -* **覆盖任务广**:支持目标检测、图像分割、变化检测、参数反演等多种任务 +* **丰富的视觉与遥感特色模型库**:集成飞桨四大视觉套件的成熟模型库,同时支持FarSeg、BIT、ChangeStar等众多遥感领域深度学习模型,覆盖图像分割、目标检测、场景分类、变化检测、图像复原等任务。 -* **高性能**:支持多进程异步I/O、多卡并行训练、评估等加速策略,结合飞桨核心框架的显存优化功能,可大幅度减少分割模型的训练开销,让开发者更低成本、更高效地完成图像遥感图像的开发和训练。 +* **对遥感领域专有任务的支持**:支持包括变化检测在内的遥感领域特色任务,提供完善的训练、部署教程以及丰富的实践案例。 + +* **针对遥感影像大幅面性质的优化**:支持大幅面影像滑窗推理,使用内存延迟载入技术提升性能;支持对大幅面影像地理坐标信息的读写。 + +* **顾及遥感特性与地学知识的数据预处理**:针对遥感数据特点,提供对包含任意数量波段的数据以及多时相数据的预处理功能,支持影像配准、辐射校正、波段选择等遥感数据预处理方法。 + +* **工业级训练与部署性能**:支持多进程异步I/O、多卡并行训练等加速策略,结合飞桨核心框架的显存优化功能,可大幅度减少模型的训练开销,帮助开发者以更低成本、更高效地完成遥感的开发和训练。 ## 产品矩阵 @@ -71,17 +77,17 @@ PaddleRS是遥感科研院所、相关高校共同基于飞桨开发的遥感处
  • Faster R-CNN
  • YOLOv3
  • - 超分/去噪
    + 图像复原
    变化检测
    @@ -119,9 +125,9 @@ PaddleRS是遥感科研院所、相关高校共同基于飞桨开发的遥感处 数据预处理
    @@ -150,31 +156,28 @@ PaddleRS是遥感科研院所、相关高校共同基于飞桨开发的遥感处 - ### 代码结构 -这部分将展示PaddleRS的文件结构全貌。文件树如下: +PaddleRS目录树中关键部分如下: ``` -├── deploy # 部署相关的文档和脚本 -├── docs # 整个项目文档及图片 +├── deploy # 部署相关文档与脚本 +├── docs # 项目文档 ├── paddlers -│ ├── rs_models # 遥感专用网络模型代码 -│ ├── datasets # 数据加载相关代码 -│ ├── models # 套件网络模型代码 -│ ├── tasks # 相关任务代码 -│ ├── tools # 相关脚本 -│ ├── transforms # 数据处理及增强相关代码 -│ └── utils # 各种实用程序文件 -├── tools # 用于处理遥感数据的脚本 +│ ├── rs_models # 遥感专用模型实现 +│ ├── datasets # 数据集接口实现 +│ ├── models # 视觉模型实现 +│ ├── tasks # 训练器实现 +│ └── transforms # 数据预处理/数据增强实现 +├── tools # 遥感影像处理工具集 └── tutorials - └── train # 训练教程 + └── train # 模型训练教程 ``` ## 技术交流 -* 如果你发现任何PaddleRS存在的问题或者是建议, 欢迎通过[GitHub Issues](https://github.com/PaddlePaddle/PaddleRS/issues)给我们提issues。 -* 欢迎加入PaddleRS 微信群 +* 如果您发现任何PaddleRS存在的问题或是对PaddleRS有建议, 欢迎通过[GitHub Issues](https://github.com/PaddlePaddle/PaddleRS/issues)向我们提出。 +* 欢迎加入PaddleRS微信群
    @@ -183,38 +186,40 @@ PaddleRS是遥感科研院所、相关高校共同基于飞桨开发的遥感处 * [快速上手PaddleRS](./tutorials/train/README.md) * 准备数据集 - * [遥感数据介绍](./docs/data/rs_data_cn.md) - * [遥感数据集](./docs/data/dataset_cn.md) - * [智能标注工具EISeg](https://github.com/PaddlePaddle/PaddleSeg/tree/release/2.4/EISeg) - * [遥感数据处理脚本](./docs/data/tools.md) + * [快速了解遥感与遥感数据](./docs/data/rs_data.md) + * [遥感数据集整理](./docs/data/dataset.md) + * [智能标注工具EISeg](https://github.com/PaddlePaddle/PaddleSeg/tree/release/2.6/EISeg) + * [遥感影像处理工具集](./docs/data/tools.md) +* 组件介绍 + * [数据预处理/数据增强](./docs/intro/transforms.md) + * [模型库](./docs/intro/model_zoo.md) * 模型训练 - * [数据增强](./docs/apis/transforms.md) - * [模型库](./docs/apis/model_zoo.md) - * [模型训练说明](./docs/apis/model_zoo.md) - * 模型验证 -* 推理部署 - * 模型导出 - * 推理预测 -* 应用案例 - * [变化检测示例](./docs/cases/csc_cd_cn.md) - * [超分模块示例](./docs/cases/sr_seg_cn.md) + * [模型训练API说明](./docs/apis/train.md) +* 模型部署 + * [模型导出](./deploy/export/README.md) + * [Python部署](./deploy/README.md) + * [模型推理API说明](./docs/apis/infer.md) +* 实践案例 + * [遥感影像变化检测案例](./docs/cases/csc_cd_cn.md) + * [遥感影像超分辨率重建案例](./docs/cases/sr_seg_cn.md) * 代码贡献 - * [PaddleRS代码注释规范](https://github.com/PaddlePaddle/PaddleRS/wiki/PaddleRS代码注释规范) - + * [贡献指南](./docs/CONTRIBUTING.md) + * [开发指南](./docs/dev/dev_guide.md) + * [代码注释规范](./docs/dev/docstring.md) ## 开源贡献 * 非常感谢国家对地观测科学数据中心、中国科学院空天信息创新研究院、北京航空航天大学、武汉大学、中国石油大学(华东)、中国地质大学、中国四维、航天宏图、中科星图、超图等单位对PaddleRS项目的贡献。注:排名不分先后。 -* 非常感谢[geoyee](https://github.com/geoyee)(陈奕州), [Bobholamovic](https://github.com/Bobholamovic)(林漫晖), [kongdebug](https://github.com/kongdebug)(孔远杭), [huilin16](https://github.com/huilin16)(赵慧琳)等开发者对PaddleRS项目的贡献。 -* PaddleRS欢迎来自开源社区的贡献。如果您想要为PaddleRS贡献源码/案例,请参考[贡献指南](docs/CONTRIBUTING.md)。 +* 非常感谢[geoyee](https://github.com/geoyee)(陈奕州), [kongdebug](https://github.com/kongdebug)(孔远杭), [huilin16](https://github.com/huilin16)(赵慧琳)等开发者对PaddleRS项目的贡献。 +* PaddleRS欢迎来自开源社区的贡献。如果您想要为PaddleRS贡献源码/案例,请参考[贡献指南](./docs/CONTRIBUTING.md)。 ## 许可证书 -本项目的发布受Apache 2.0 license许可认证。 +本项目的发布受[Apache 2.0 license](./LICENSE)许可认证。 ## 学术引用 -如果我们的项目在学术上帮助到你,请考虑以下引用: +如果我们的项目在学术上帮助到您,请考虑以下引用: ```latex @misc{paddlers2022, diff --git a/deploy/README.md b/deploy/README.md index 5047c26..328239d 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -2,30 +2,68 @@ PaddleRS已经集成了基于Python的高性能预测(prediction)接口。在安装PaddleRS后,可参照如下代码示例执行预测。 -## 部署模型导出 +## 1 部署模型导出 -在服务端部署模型时需要首先将训练过程中保存的模型导出为部署格式,具体的导出步骤请参考文档[部署模型导出](/deploy/export/README.md)。 +在服务端部署模型时需要首先将训练过程中保存的模型导出为部署格式,具体的导出步骤请参考文档[部署模型导出](deploy/export/README.md)。 -## 预测接口调用 +## 2 预测接口调用 -* **基本使用** +使用预测接口的基本流程为:首先构建`Predictor`对象,然后调用`Predictor`的`predict()`方法执行预测。需要说明的是,`Predictor`对象的`predict()`方法返回的结果与对应的训练器(在`paddlers/tasks/`目录的文件中定义)的`predict()`方法返回结果具有相同的格式。 -以下是一个调用PaddleRS Python预测接口的实例。首先构建`Predictor`对象,然后调用`Predictor`的`predict()`方法执行预测。 +### 2.1 基本使用 + +以变化检测任务为例,说明预测接口的基本使用方法: ```python -import paddlers as pdrs -# 将导出模型所在目录传入Predictor的构造方法中 -predictor = pdrs.deploy.Predictor('./inference_model') -# img_file参数指定输入图像路径 -result = predictor.predict(img_file='test.jpg') +from paddlers.deploy import Predictor + +# 第一步:构建Predictor。该类接受的构造参数如下: +# model_dir: 模型路径(必须是导出的部署或量化模型)。 +# use_gpu: 是否使用GPU,默认为False。 +# gpu_id: 使用GPU的ID,默认为0。 +# cpu_thread_num:使用CPU进行预测时的线程数,默认为1。 +# use_mkl: 是否使用MKL-DNN计算库,CPU情况下使用,默认为False。 +# mkl_thread_num: MKL-DNN计算线程数,默认为4。 +# use_trt: 是否使用TensorRT,默认为False。 +# use_glog: 是否启用glog日志, 默认为False。 +# memory_optimize: 是否启动内存优化,默认为True。 +# max_trt_batch_size: 在使用TensorRT时配置的最大batch size,默认为1。 +# trt_precision_mode:在使用TensorRT时采用的精度,可选值['float32', 'float16']。默认为'float32'。 +# +# 下面的语句构建的Predictor对象依赖static_models/目录中存储的部署格式模型,并使用GPU进行推理。 +predictor = Predictor("static_models/", use_gpu=True) + +# 第二步:调用Predictor的predict()方法执行推理。该方法接受的输入参数如下: +# img_file: 对于场景分类、图像复原、目标检测和图像分割任务来说,该参数可为单一图像路径,或是解码后的、排列格式为(H, W, C) +# 且具有float32类型的图像数据(表示为numpy的ndarray形式),或者是一组图像路径或np.ndarray对象构成的列表;对于变化检测 +# 任务来说,该参数可以为图像路径二元组(分别表示前后两个时相影像路径),或是两幅图像组成的二元组,或者是上述两种二元组 +# 之一构成的列表。 +# topk: 场景分类模型预测时使用,表示选取模型输出概率大小排名前`topk`的类别作为最终结果。默认值为1。 +# transforms: 对输入数据应用的数据变换算子。若为None,则使用从`model.yml`中读取的算子。默认值为None。 +# warmup_iters: 预热轮数,用于评估模型推理以及前后处理速度。若大于1,会预先重复执行`warmup_iters`次推理,而后才开始正式的预测及其速度评估。默认值为0。 +# repeats: 重复次数,用于评估模型推理以及前后处理速度。若大于1,会执行`repeats`次预测并取时间平均值。默认值为1。 +# +# 下面的语句传入两幅输入影像的路径 +res = predictor.predict(("demo_data/A.png", "demo_data/B.png")) + +# 第三步:解析predict()方法返回的结果。 +# 对于图像分割和变化检测任务而言,predict()方法返回的结果为一个字典或字典构成的列表。字典中的`label_map`键对应的值为类别标签图,对于二值变化检测 +# 任务而言只有0(不变类)或者1(变化类)两种取值;`score_map`键对应的值为类别概率图,对于二值变化检测任务来说一般包含两个通道,第0个通道表示不发生 +# 变化的概率,第1个通道表示发生变化的概率。如果返回的结果是由字典构成的列表,则列表中的第n项与输入的img_file中的第n项对应。 +# +# 下面的语句从res中解析二值变化图(binary change map) +cm_1024x1024 = res['label_map'] ``` -* **在预测过程中评估模型预测速度** +请注意,**`predictor.predict()`方法接受的影像列表长度与导出模型时指定的batch size必须一致**(若指定的batch size不为-1),这是因为`Predictor`对象将所有输入影像拼接成一个batch执行预测。您可以在[模型推理API说明](https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/infer.md)中了解关于`predictor.predict()`方法返回结果格式的更多信息。 -加载模型后,对前几张图片的预测速度会较慢,这是因为程序刚启动时需要进行内存、显存初始化等步骤。通常,在处理20-30张图片后,模型的预测速度能够达到稳定值。基于这一观察,**如果需要评估模型的预测速度,可通过指定预热轮数`warmup_iters`对模型进行预热**。此外,**为获得更加精准的预测速度估计值,可指定重复`repeats`次预测后计算平均耗时**。 +### 2.2 指定预热轮数与重复次数 + +加载模型后,对前几张图片的预测速度会较慢,这是因为程序刚启动时需要进行内存、显存初始化等步骤。通常,在处理20-30张图片后,模型的预测速度能够达到稳定值。基于这一观察,**如果需要评估模型的预测速度,可通过指定预热轮数`warmup_iters`对模型进行预热**。此外,**为获得更加精准的预测速度估计值,可指定重复`repeats`次预测后计算平均耗时**。指定预热轮数与重复次数的一个简单例子如下: ```python import paddlers as pdrs + predictor = pdrs.deploy.Predictor('./inference_model') result = predictor.predict(img_file='test.jpg', warmup_iters=100, diff --git a/deploy/export/README.md b/deploy/export/README.md index d3e2eb7..04630d9 100644 --- a/deploy/export/README.md +++ b/deploy/export/README.md @@ -2,10 +2,10 @@ ## 目录 -* [模型格式说明](#1) - * [训练模型格式](#11) - * [部署模型格式](#12) -* [部署模型导出](#2) +- [模型格式说明](#1) + - [训练模型格式](#11) + - [部署模型格式](#12) +- [部署模型导出](#2) ##

    模型格式说明

    @@ -23,6 +23,7 @@ ###

    部署模型格式

    在服务端部署模型时,需要将训练过程中保存的模型导出为专用的格式。具体而言,在部署阶段,使用下述五个文件描述训练好的模型: + - `model.pdmodel`,记录模型的网络结构; - `model.pdiparams`,包含模型权重参数; - `model.pdiparams.info`,包含模型权重名称; @@ -33,7 +34,7 @@ 使用如下指令导出部署格式的模型: -```commandline +```shell python deploy/export/export_model.py --model_dir=./output/deeplabv3p/best_model/ --save_dir=./inference_model/ ``` @@ -51,11 +52,12 @@ python deploy/export/export_model.py --model_dir=./output/deeplabv3p/best_model/ 完整命令示例: -```commandline +```shell python deploy/export_model.py --model_dir=./output/deeplabv3p/best_model/ --save_dir=./inference_model/ --fixed_input_shape=[224,224] ``` 对于`--fixed_input_shape`选项,**请注意**: + - 在推理阶段若需固定分类模型的输入形状,请保持其与训练阶段的输入形状一致。 - 对于检测模型中的YOLO/PPYOLO系列模型,请保证输入影像的`w`和`h`有相同取值、且均为32的倍数;指定`--fixed_input_shape`时,R-CNN模型的`w`和`h`也均需为32的倍数。 - 指定`[w,h]`时,请使用半角逗号(`,`)分隔`w`和`h`,二者之间不允许存在空格等其它字符。 diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index dbadae2..b2d31a3 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -68,7 +68,7 @@ from paddlers.transforms import DecodeImg ### 3 代码风格规范 -PaddleRS对代码风格的规范基本与[Google Python风格规范](https://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_style_rules/)一致,但PaddleRS对类型注释不做强制要求。较为重要的代码风格规范如下: +PaddleRS对代码风格的规范基本与[Google Python风格规范](https://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_style_rules/)一致,但PaddleRS对类型注解(即type hints,参见[PEP 483](https://peps.python.org/pep-0483/)与[PEP 484](https://peps.python.org/pep-0484/))不做强制要求。较为重要的代码风格规范如下: - 空行:顶层定义(例如顶层的函数或者类的定义)之间空2行。类内部不同方法的定义之间、以及类名与第一个方法定义之间空1行。在函数内部需要注意在逻辑上有间断的地方添加1个空行。 diff --git a/docs/README.md b/docs/README.md index 835a89a..7267d44 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,3 +1 @@ -# 开发规范 -请注意,paddlers/models/ppxxx系列除了修改import路径和支持多通道模型外,不要增删改任何代码。 -新增的模型需放在paddlers/models/下的seg、det、clas、cd目录下。 +# PaddleRS文档 diff --git a/docs/apis/data.md b/docs/apis/data.md new file mode 100644 index 0000000..8f8bc4d --- /dev/null +++ b/docs/apis/data.md @@ -0,0 +1,182 @@ +# 数据相关API说明 + +## 数据集 + +在PaddleRS中,所有数据集均继承自父类[`BaseDataset`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/base.py)。 + +### 变化检测数据集`CDDataset` + +`CDDataset`定义在:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/cd_dataset.py + +其初始化参数列表如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`data_dir`|`str`|数据集存放目录。|| +|`file_list`|`str`|file list路径。file list是一个文本文件,其中每一行包含一个样本的路径信息。`CDDataset`对file list的具体要求请参见下文。|| +|`transforms`|`paddlers.transforms.Compose`|对输入数据应用的数据变换算子。|| +|`label_list`|`str` \| `None`|label list文件。label list是一个文本文件,其中每一行包含一个类别的名称。|`None`| +|`num_workers`|`int` \| `str`|加载数据时使用的辅助进程数。若设置为`'auto'`,则按照如下规则确定使用进程数:当CPU核心数大于16时,使用8个数据读取辅助进程;否则,使用CPU核心数一半数量的辅助进程。|`'auto'`| +|`shuffle`|`bool`|是否随机打乱数据集中的样本。|`False`| +|`with_seg_labels`|`bool`|当数据集中包含每个时相的分割标签时,请指定此选项为`True`。|`False`| +|`binarize_labels`|`bool`|若为`True`,则在除`Arrange`以外的所有数据变换算子处理完毕后对变化标签(和分割标签)进行二值化操作。例如,将取值为{0, 255}的标签二值化到{0, 1}。|`False`| + +`CDDataset`对file list的要求如下: + +- 当`with_seg_labels`为`False`时,file list中的每一行应该包含3个以空格分隔的项,依次表示第一时相影像相对`data_dir`的路径、第二时相影像相对`data_dir`的路径以及变化标签相对`data_dir`的路径。 +- 当`with_seg_labels`为`True`时,file list中的每一行应该包含5个以空格分隔的项,其中前3项的表示含义与`with_seg_labels`为`False`时相同,后2项依次表示第一时相和第二时相影像对应的分割标签相对`data_dir`的路径。 + +### 场景分类数据集`ClasDataset` + +`ClasDataset`定义在:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/clas_dataset.py + +其初始化参数列表如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`data_dir`|`str`|数据集存放目录。|| +|`file_list`|`str`|file list路径。file list是一个文本文件,其中每一行包含一个样本的路径信息。`ClasDataset`对file list的具体要求请参见下文。|| +|`transforms`|`paddlers.transforms.Compose`|对输入数据应用的数据变换算子。|| +|`label_list`|`str` \| `None`|label list文件。label list是一个文本文件,其中每一行包含一个类别的名称。|`None`| +|`num_workers`|`int` \| `str`|加载数据时使用的辅助进程数。若设置为`'auto'`,则按照如下规则确定使用进程数:当CPU核心数大于16时,使用8个数据读取辅助进程;否则,使用CPU核心数一半数量的辅助进程。|`'auto'`| +|`shuffle`|`bool`|是否随机打乱数据集中的样本。|`False`| + +`ClasDataset`对file list的要求如下: + +- file list中的每一行应该包含2个以空格分隔的项,依次表示输入影像相对`data_dir`的路径以及影像的类别ID(可解析为整型值)。 + +### COCO格式目标检测数据集`COCODetDataset` + +`COCODetDataset`定义在:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/coco.py + +其初始化参数列表如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`data_dir`|`str`|数据集存放目录。|| +|`image_dir`|`str`|输入图像存放目录。|| +|`ann_path`|`str`|[COCO格式](https://cocodataset.org/#home)标注文件路径。|| +|`transforms`|`paddlers.transforms.Compose`|对输入数据应用的数据变换算子。|| +|`label_list`|`str` \| `None`|label list文件。label list是一个文本文件,其中每一行包含一个类别的名称。|`None`| +|`num_workers`|`int` \| `str`|加载数据时使用的辅助进程数。若设置为`'auto'`,则按照如下规则确定使用进程数:当CPU核心数大于16时,使用8个数据读取辅助进程;否则,使用CPU核心数一半数量的辅助进程。|`'auto'`| +|`shuffle`|`bool`|是否随机打乱数据集中的样本。|`False`| +|`allow_empty`|`bool`|是否向数据集中添加负样本。|`False`| +|`empty_ratio`|`float`|负样本占比,仅当`allow_empty`为`True`时生效。若`empty_ratio`为负值或大于等于1,则保留所有生成的负样本。|`1.0`| + +### VOC格式目标检测数据集`VOCDetDataset` + +`VOCDetDataset`定义在:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/voc.py + +其初始化参数列表如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`data_dir`|`str`|数据集存放目录。|| +|`file_list`|`str`|file list路径。file list是一个文本文件,其中每一行包含一个样本的路径信息。`VOCDetDataset`对file list的具体要求请参见下文。|| +|`transforms`|`paddlers.transforms.Compose`|对输入数据应用的数据变换算子。|| +|`label_list`|`str` \| `None`|label list文件。label list是一个文本文件,其中每一行包含一个类别的名称。|`None`| +|`num_workers`|`int` \| `str`|加载数据时使用的辅助进程数。若设置为`'auto'`,则按照如下规则确定使用进程数:当CPU核心数大于16时,使用8个数据读取辅助进程;否则,使用CPU核心数一半数量的辅助进程。|`'auto'`| +|`shuffle`|`bool`|是否随机打乱数据集中的样本。|`False`| +|`allow_empty`|`bool`|是否向数据集中添加负样本。|`False`| +|`empty_ratio`|`float`|负样本占比,仅当`allow_empty`为`True`时生效。若`empty_ratio`为负值或大于等于1,则保留所有生成的负样本。|`1.0`| + +`VOCDetDataset`对file list的要求如下: + +- file list中的每一行应该包含2个以空格分隔的项,依次表示输入影像相对`data_dir`的路径以及[Pascal VOC格式](http://host.robots.ox.ac.uk/pascal/VOC/)标注文件相对`data_dir`的路径。 + +### 图像分割数据集`SegDataset` + +`SegDataset`定义在:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/datasets/seg_dataset.py + +其初始化参数列表如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`data_dir`|`str`|数据集存放目录。|| +|`file_list`|`str`|file list路径。file list是一个文本文件,其中每一行包含一个样本的路径信息。`SegDataset`对file list的具体要求请参见下文。|| +|`transforms`|`paddlers.transforms.Compose`|对输入数据应用的数据变换算子。|| +|`label_list`|`str` \| `None`|label list文件。label list是一个文本文件,其中每一行包含一个类别的名称。|`None`| +|`num_workers`|`int` \| `str`|加载数据时使用的辅助进程数。若设置为`'auto'`,则按照如下规则确定使用进程数:当CPU核心数大于16时,使用8个数据读取辅助进程;否则,使用CPU核心数一半数量的辅助进程。|`'auto'`| +|`shuffle`|`bool`|是否随机打乱数据集中的样本。|`False`| + +`SegDataset`对file list的要求如下: + +- file list中的每一行应该包含2个以空格分隔的项,依次表示输入影像相对`data_dir`的路径以及分割标签相对`data_dir`的路径。 + +## 数据读取API + +遥感影像的来源多样,数据格式十分繁杂。PaddleRS为不同类型、不同格式的遥感影像提供了统一的读取接口。目前,PaddleRS支持.png、.jpg、.bmp、.npy等常见文件格式的读取,也支持处理遥感领域常用的GeoTiff、img等影像格式。 + +根据实际需要,用户可以选择`paddlers.transforms.decode_image()`或`paddlers.transforms.DecodeImg`进行数据读取。`DecodeImg`是[数据变换算子](#数据变换算子)之一,可以与其它算子组合使用。`decode_image`是对`DecodeImg`算子的封装,方便用户以函数调用的方式使用。 + +`decode_image()`函数的参数列表如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`im_path`|`str`|输入图像路径。|| +|`to_rgb`|`bool`|若为`True`,则执行BGR到RGB格式的转换。|`True`| +|`to_uint8`|`bool`|若为`True`,则将读取的图像数据量化并转换为uint8类型。|`True`| +|`decode_bgr`|`bool`|若为`True`,则自动将非地学格式影像(如jpeg影像)解析为BGR格式。|`True`| +|`decode_sar`|`bool`|若为`True`,则自动将2通道的地学格式影像(如GeoTiff影像)作为SAR影像解析。|`True`| +|`read_geo_info`|`bool`|若为`True`,则从影像中读取地理信息。|`False`| + +返回格式如下: + +- 若`read_geo_info`为`False`,则以np.ndarray形式返回读取的影像数据([h, w, c]排布); +- 若`read_geo_info`为`True`,则返回一个二元组,其中第一个元素为读取的影像数据,第二个元素为一个字典,其中的键值对为影像的地理信息,如地理变换信息、地理投影信息等。 + +## 数据变换算子 + +在PaddleRS中定义了一系列类,这些类在实例化之后,可通过调用`__call__`方法执行某种特定的数据预处理或数据增强操作。PaddleRS将这些类称为数据预处理/数据增强算子,并统称为**数据变换算子**。所有数据变换算子均继承自父类[`Transform`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/transforms/operators.py)。 + +### `Transform` + +`Transform`对象的`__call__`方法接受唯一的参数`sample`。`sample`必须为字典或字典构成的序列。当`sample`是序列时,为`sample`中的每个字典执行数据变换操作,并将变换结果依次存储在一个Python built-in list中返回;当`sample`是字典时,`Transform`对象根据其中的一些键值对提取输入(这些键称为“输入键”),执行变换后,将结果以键值对的形式写入`sample`中(这些键称为“输出键”)。需要注意的是,目前PaddleRS中许多`Transform`对象都存在复写行为,即,输入键与输出键之间存在交集。`sample`中常见的键名及其表示的含义如下表: + +|键名|说明| +|----|----| +|`'image'`|影像路径或数据。对于变化检测任务,指第一时相影像数据。| +|`'image2'`|变化检测任务中第二时相影像数据。| +|`'image_t1'`|变化检测任务中第一时相影像路径。| +|`'image_t2'`|变化检测任务中第二时相影像路径。| +|`'mask'`|图像分割/变化检测任务中的真值标签路径或数据。| +|`'aux_masks'`|图像分割/变化检测任务中的辅助标签路径或数据。| +|`'gt_bbox'`|目标检测任务中的检测框标注数据。| +|`'gt_poly'`|目标检测任务中的多边形标注数据。| + +### 组合数据变换算子 + +使用`paddlers.transforms.Compose`对一组数据变换算子进行组合。`Compose`对象在构造时接受一个列表输入。在调用`Compose`对象时,相当于串行执行列表中的每一个数据变换算子。示例如下: + +```python +# 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 +train_transforms = T.Compose([ + # 读取影像 + T.DecodeImg(), + # 将影像缩放到512x512大小 + T.Resize(target_size=512), + # 以50%的概率实施随机水平翻转 + T.RandomHorizontalFlip(prob=0.5), + # 将数据归一化到[-1,1] + T.Normalize( + mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), + # 挑选并排布后续需要使用的信息 + T.ArrangeSegmenter('train') +]) +``` + +一般来说,`Compose`对象接受的数据变换算子列表中,首个元素为`paddlers.transforms.DecodeImg`对象,用于读取影像数据;最后一个元素为[`Arrange`算子](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/transforms/operators.py),用于从`sample`字典中抽取信息并排列。 + +对于图像分割任务和变化检测任务的验证集而言,可在`Arrange`算子之前插入`ReloadMask`算子以重新加载真值标签。示例如下: + +```python +eval_transforms = T.Compose([ + T.DecodeImg(), + T.Resize(target_size=512), + T.Normalize( + mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), + # 重新加载标签 + T.ReloadMask(), + T.ArrangeSegmenter('eval') +]) +``` diff --git a/docs/apis/infer.md b/docs/apis/infer.md new file mode 100644 index 0000000..c7f3d1c --- /dev/null +++ b/docs/apis/infer.md @@ -0,0 +1,195 @@ +# PaddleRS推理API说明 + +PaddleRS的动态图推理和静态图推理能力分别由训练器([`BaseModel`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/base.py)及其子类)和**预测器**(`paddlers.deploy.Predictor`)提供。 + +## 动态图推理API + +### 整图推理 + +#### `BaseChangeDetector.predict()` + +接口形式: + +```python +def predict(self, img_file, transforms=None): +``` + +输入参数: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`img_file`|`list[tuple]` \| `tuple[str\|np.ndarray]`|输入影像对数据(NumPy数组形式)或输入影像对路径。若仅预测一个影像对,使用一个元组顺序包含第一时相影像数据/路径以及第二时相影像数据/路径。若需要一次性预测一组影像对,以列表包含这些影像对的数据或路径(每个影像对对应列表中的一个元组)。|| +|`transforms`|`paddlers.transforms.Compose` \| `None`|对输入数据应用的数据变换算子。若为`None`,则使用训练器在验证阶段使用的数据变换算子。|`None`| + +返回格式: + +若`img_file`是一个元组,则返回对象为包含下列键值对的字典: + +``` +{"label map": 输出类别标签(以[h, w]格式排布),"score_map": 模型输出的各类别概率(以[h, w, c]格式排布)} +``` + +若`img_file`是一个列表,则返回对象为与`img_file`等长的列表,其中的每一项为一个字典(键值对如上所示),顺序对应`img_file`中的每个元素。 + +#### `BaseClassifier.predict()` + +接口形式: + +```python +def predict(self, img_file, transforms=None): +``` + +输入参数: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`img_file`|`list[str\|np.ndarray]` \| `str` \| `np.ndarray`|输入影像数据(NumPy数组形式)或输入影像路径。若需要一次性预测一组影像,以列表包含这些影像的数据或路径(每幅影像对应列表中的一个元素)。|| +|`transforms`|`paddlers.transforms.Compose` \| `None`|对输入数据应用的数据变换算子。若为`None`,则使用训练器在验证阶段使用的数据变换算子。|`None`| + +返回格式: + +若`img_file`是一个字符串或NumPy数组,则返回对象为包含下列键值对的字典: + +``` +{"label map": 输出类别标签, + "scores_map": 输出类别概率, + "label_names_map": 输出类别名称} +``` + +若`img_file`是一个列表,则返回对象为与`img_file`等长的列表,其中的每一项为一个字典(键值对如上所示),顺序对应`img_file`中的每个元素。 + +#### `BaseDetector.predict()` + +接口形式: + +```python +def predict(self, img_file, transforms=None): +``` + +输入参数: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`img_file`|`list[str\|np.ndarray]` \| `str` \| `np.ndarray`|输入影像数据(NumPy数组形式)或输入影像路径。若需要一次性预测一组影像,以列表包含这些影像的数据或路径(每幅影像对应列表中的一个元素)。|| +|`transforms`|`paddlers.transforms.Compose` \| `None`|对输入数据应用的数据变换算子。若为`None`,则使用训练器在验证阶段使用的数据变换算子。|`None`| + +返回格式: + +若`img_file`是一个字符串或NumPy数组,则返回对象为一个列表,列表中每个元素对应一个预测的目标框。列表中的元素为包含下列键值对的字典: + +``` +{"category_id": 类别ID, + "category": 类别名称, + "bbox": 目标框位置信息,依次包含目标框左上角的横、纵坐标以及目标框的宽度和长度, + "score": 类别置信度, + "mask": [RLE格式](https://baike.baidu.com/item/rle/366352)的掩模图(mask),仅实例分割模型预测结果包含此键值对} +``` + +若`img_file`是一个列表,则返回对象为与`img_file`等长的列表,其中的每一项为一个由字典(键值对如上所示)构成的列表,顺序对应`img_file`中的每个元素。 + +#### `BaseSegmenter.predict()` + +接口形式: + +```python +def predict(self, img_file, transforms=None): +``` + +输入参数: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`img_file`|`list[str\|np.ndarray]` \| `str` \| `np.ndarray`|输入影像数据(NumPy数组形式)或输入影像路径。若需要一次性预测一组影像,以列表包含这些影像的数据或路径(每幅影像对应列表中的一个元素)。|| +|`transforms`|`paddlers.transforms.Compose` \| `None`|对输入数据应用的数据变换算子。若为`None`,则使用训练器在验证阶段使用的数据变换算子。|`None`| + +返回格式: + +若`img_file`是一个字符串或NumPy数组,则返回对象为包含下列键值对的字典: + +``` +{"label map": 输出类别标签(以[h, w]格式排布),"score_map": 模型输出的各类别概率(以[h, w, c]格式排布)} +``` + +若`img_file`是一个列表,则返回对象为与`img_file`等长的列表,其中的每一项为一个字典(键值对如上所示),顺序对应`img_file`中的每个元素。 + +### 滑窗推理 + +考虑到遥感影像的大幅面性质,PaddleRS为部分任务提供了滑窗推理支持。PaddleRS的滑窗推理功能具有如下特色: + +1. 为了解决一次读入整张大图直接导致内存不足的问题,PaddleRS采用延迟载入内存的技术,一次仅读取并处理一个窗口内的影像块。 +2. 用户可自定义滑窗的大小和步长。支持滑窗重叠,对于窗口之间重叠的部分,PaddleRS将自动对模型预测结果进行融合。 +3. 支持将推理结果保存为GeoTiff格式,支持对地理变换信息、地理投影信息的读取与写入。 + +目前,图像分割训练器([`BaseSegmenter`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/segmenter.py)及其子类)与变化检测训练器([`BaseChangeDetector`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py)及其子类)具有动态图滑窗推理API,以图像分割任务的API为例,说明如下: + +接口形式: + +```python +def slider_predict(self, + img_file, + save_dir, + block_size, + overlap=36, + transforms=None): +``` + +输入参数列表: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`img_file`|`str`|输入影像路径。|| +|`save_dir`|`str`|预测结果输出路径。|| +|`block_size`|`list[int]` \| `tuple[int]` \| `int`|滑窗的窗口大小(以列表或元组指定长、宽或以一个整数指定相同的长宽)。|| +|`overlap`|`list[int]` \| `tuple[int]` \| `int`|滑窗的滑动步长(以列表或元组指定长、宽或以一个整数指定相同的长宽)。|`36`| +|`transforms`|`paddlers.transforms.Compose` \| `None`|对输入数据应用的数据变换算子。若为`None`,则使用训练器在验证阶段使用的数据变换算子。|`None`| + +变化检测任务的滑窗推理API与图像分割任务类似,但需要注意的是输出结果中存储的地理变换、投影等信息以从第一时相影像中读取的信息为准。 + +## 静态图推理API + +### Python API + +[将模型导出为部署格式](https://github.com/PaddlePaddle/PaddleRS/blob/develop/deploy/export/README.md)或执行模型量化后,PaddleRS提供`paddlers.deploy.Predictor`用于加载部署或量化格式模型以及执行基于[Paddle Inference](https://www.paddlepaddle.org.cn/tutorials/projectdetail/3952715)的推理。 + +#### 初始化`Predictor`对象 + +`Predictor.__init__()`接受如下参数: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`model_dir`|`str`|模型路径(必须是导出的部署或量化模型)。|| +|`use_gpu`|`bool`|是否使用GPU。|`False`| +|`gpu_id`|`int`|使用GPU的ID。|`0`| +|`cpu_thread_num`|`int`|使用CPU执行推理时的线程数。|`1`| +|`use_mkl`|`bool`|是否使用MKL-DNN计算库(此选项仅在使用CPU执行推理时生效)。|`False`| +|`mkl_thread_num`|`int`|MKL-DNN计算线程数。|`4`| +|`use_trt`|`bool`|是否使用TensorRT。|`False`| +|`use_glog`|`bool`|是否启用glog日志。|`False`| +|`memory_optimize`|`bool`|是否启用内存优化。|`True`| +|`max_trt_batch_size`|`int`|在使用TensorRT时配置的最大batch size。|`1`| +|`trt_precision_mode`|`str`|在使用TensorRT时采用的精度,可选值为`'float32'`或`'float16'`。|`'float32'`| + +#### `Predictor.predict()` + +接口形式: + +```python +def predict(self, + img_file, + topk=1, + transforms=None, + warmup_iters=0, + repeats=1): +``` + +输入参数列表: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`img_file`|`list[str\|tuple\|np.ndarray]` \| `str` \| `tuple` \| `np.ndarray`|对于场景分类、目标检测和图像分割任务来说,该参数可为单一图像路径,或是解码后的、排列格式为[h, w, c]且具有float32类型的图像数据(表示为NumPy数组形式),或者是一组图像路径或np.ndarray对象构成的列表;对于变化检测任务来说,该参数可以为图像路径二元组(分别表示前后两个时相影像路径),或是解码后的两幅图像组成的二元组,或者是上述两种二元组之一构成的列表。|| +|`topk`|`int`|场景分类模型预测时使用,表示选取模型输出概率大小排名前`topk`的类别作为最终结果。|`1`| +|`transforms`|`paddlers.transforms.Compose`\|`None`|对输入数据应用的数据变换算子。若为`None`,则使用从`model.yml`中读取的算子。|`None`| +|`warmup_iters`|`int`|预热轮数,用于评估模型推理以及前后处理速度。若大于1,将预先重复执行`warmup_iters`次推理,而后才开始正式的预测及其速度评估。|`0`| +|`repeats`|`int`|重复次数,用于评估模型推理以及前后处理速度。若大于1,将执行`repeats`次预测并取时间平均值。|`1`| + +`Predictor.predict()`的返回格式与相应的动态图推理API的返回格式完全相同,详情请参考[动态图推理API](#动态图推理api)。 diff --git a/docs/apis/model_zoo.md b/docs/apis/model_zoo.md deleted file mode 100644 index 18701fe..0000000 --- a/docs/apis/model_zoo.md +++ /dev/null @@ -1,33 +0,0 @@ -# 模型库 - -PaddleRS的基础模型库来自[PaddleClas](https://github.com/PaddlePaddle/PaddleClas/blob/release/2.3/docs/zh_CN/algorithm_introduction/ImageNet_models.md)、[PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.4/docs/model_zoo_overview_cn.md)、[PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.3/README_cn.md#模型库)以及[PaddleGAN](https://github.com/PaddlePaddle/PaddleGAN/blob/develop/README_cn.md#模型库),可以通过相关的链接进行查看。而在此之外,PaddleRS也针对遥感任务添加了一些特有的模型库,可用于遥感图像语义分割、遥感变化检测等。 - -## 遥感专用模型库 - -| 模型名称 | 用途 | -| --------------- | -------- | -| FarSeg | 语义分割 | -| BIT | 变化检测 | -| CDNet | 变化检测 | -| DSIFN | 变化检测 | -| STANet | 变化检测 | -| SNUNet | 变化检测 | -| DSAMNet | 变化检测 | -| FCEarlyFusion | 变化检测 | -| FCSiamConc | 变化检测 | -| FCSiamDiff | 变化检测 | - - -## 如何导入 - -模型均位于`paddlers/models`和`paddlers/rs_models`中,对于套件中的模型可以通过如下方法进行使用 - -```python -from paddlers.models import xxxx -``` - -而PaddleRS所特有的模型可以通过如下方法调用 - -```python -from paddlers.rs_models import xxxx -``` diff --git a/docs/apis/train.md b/docs/apis/train.md new file mode 100644 index 0000000..97f55b1 --- /dev/null +++ b/docs/apis/train.md @@ -0,0 +1,341 @@ +# PaddleRS训练API说明 + +**训练器**封装了模型训练、验证、量化以及动态图推理等逻辑,定义在`paddlers/tasks/`目录下的文件中。为了方便用户使用,PaddleRS为所有支持的模型均提供了继承自父类[`BaseModel`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/base.py)的训练器,并对外提供数个API。变化检测、场景分类、图像分割以及目标检测任务对应的训练器类型分别为`BaseChangeDetector`、`BaseClassifier`、`BaseDetector`和`BaseSegmenter`。本文档介绍训练器的初始化函数以及`train()`、`evaluate()` API。 + +## 初始化训练器 + +所有训练器均支持默认参数构造(即构造对象时不传入任何参数),在这种情况下,构造出的训练器对象适用于三通道RGB数据。 + +### 初始化`BaseChangeDetector`子类对象 + +- 一般支持设置`num_classes`、`use_mixed_loss`以及`in_channels`参数,分别表示模型输出类别数、是否使用预置的混合损失以及输入通道数。部分子类如`DSIFN`暂不支持对`in_channels`参数的设置。 +- `use_mixed_loss`参将在未来被弃用,因此不建议使用。 +- 不同的子类支持与模型相关的输入参数,详情请参考[模型定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/rs_models/cd)和[训练器定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py)。 + +### 初始化`BaseClassifier`子类对象 + +- 一般支持设置`num_classes`和`use_mixed_loss`参数,分别表示模型输出类别数以及是否使用预置的混合损失。 +- `use_mixed_loss`参将在未来被弃用,因此不建议使用。 +- 不同的子类支持与模型相关的输入参数,详情请参考[模型定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/rs_models/clas)和[训练器定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/classifier.py)。 + +### 初始化`Baseetector`子类对象 + +- 一般支持设置`num_classes`和`backbone`参数,分别表示模型输出类别数以及所用的骨干网络类型。相比其它任务,目标检测任务的训练器支持设置的初始化参数较多,囊括网络结构、损失函数、后处理策略等方面。 +- 不同的子类支持与模型相关的输入参数,详情请参考[模型定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/rs_models/det)和[训练器定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/object_detector.py)。 + +### 初始化`BaseSegmenter`子类对象 + +- 一般支持设置`input_channel`、`num_classes`以及`use_mixed_loss`参数,分别表示输入通道数、输出类别数以及是否使用预置的混合损失。部分模型如`FarSeg`暂不支持对`input_channel`参数的设置。 +- `use_mixed_loss`参将在未来被弃用,因此不建议使用。 +- 不同的子类支持与模型相关的输入参数,详情请参考[模型定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/rs_models/seg)和[训练器定义](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/segmentor.py)。 + +## `train()` + +### `BaseChangeDetector.train()` + +接口形式: + +```python +def train(self, + num_epochs, + train_dataset, + train_batch_size=2, + eval_dataset=None, + optimizer=None, + save_interval_epochs=1, + log_interval_steps=2, + save_dir='output', + pretrain_weights=None, + learning_rate=0.01, + lr_decay_power=0.9, + early_stop=False, + early_stop_patience=5, + use_vdl=True, + resume_checkpoint=None): +``` + +其中各参数的含义如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`num_epochs`|`int`|训练的epoch数目。|| +|`train_dataset`|`paddlers.datasets.CDDataset`|训练数据集。|| +|`train_batch_size`|`int`|训练时使用的batch size。|`2`| +|`eval_dataset`|`paddlers.datasets.CDDataset` \| `None`|验证数据集。|`None`| +|`optimizer`|`paddle.optimizer.Optimizer` \| `None`|训练时使用的优化器。若为`None`,则使用默认定义的优化器。|`None`| +|`save_interval_epochs`|`int`|训练时存储模型的间隔epoch数。|`1`| +|`log_interval_steps`|`int`|训练时打印日志的间隔step数(即迭代数)。|`2`| +|`save_dir`|`str`|存储模型的路径。|`'output'`| +|`pretrain_weights`|`str` \| `None`|预训练权重的名称/路径。若为`None`,则不适用预训练权重。|`None`| +|`learning_rate`|`float`|训练时使用的学习率大小,适用于默认优化器。|`0.01`| +|`lr_decay_power`|`float`|学习率衰减系数,适用于默认优化器。|`0.9`| +|`early_stop`|`bool`|训练过程是否启用早停策略。|`False`| +|`early_stop_patience`|`int`|启用早停策略时的`patience`参数(参见[`EarlyStop`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/utils/utils.py))。|`5`| +|`use_vdl`|`bool`|是否启用VisualDL日志。|`True`| +|`resume_checkpoint`|`str` \| `None`|检查点路径。PaddleRS支持从检查点(包含先前训练过程中存储的模型权重和优化器权重)继续训练,但需注意`resume_checkpoint`与`pretrain_weights`不得同时设置为`None`以外的值。|`None`| + +### `BaseClassifier.train()` + +接口形式: + +```python +def train(self, + num_epochs, + train_dataset, + train_batch_size=2, + eval_dataset=None, + optimizer=None, + save_interval_epochs=1, + log_interval_steps=2, + save_dir='output', + pretrain_weights='IMAGENET', + learning_rate=0.1, + lr_decay_power=0.9, + early_stop=False, + early_stop_patience=5, + use_vdl=True, + resume_checkpoint=None): +``` + +其中各参数的含义如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`num_epochs`|`int`|训练的epoch数目。|| +|`train_dataset`|`paddlers.datasets.ClasDataset`|训练数据集。|| +|`train_batch_size`|`int`|训练时使用的batch size。|`2`| +|`eval_dataset`|`paddlers.datasets.ClasDataset` \| `None`|验证数据集。|`None`| +|`optimizer`|`paddle.optimizer.Optimizer` \| `None`|训练时使用的优化器。若为`None`,则使用默认定义的优化器。|`None`| +|`save_interval_epochs`|`int`|训练时存储模型的间隔epoch数。|`1`| +|`log_interval_steps`|`int`|训练时打印日志的间隔step数(即迭代数)。|`2`| +|`save_dir`|`str`|存储模型的路径。|`'output'`| +|`pretrain_weights`|`str` \| `None`|预训练权重的名称/路径。若为`None`,则不适用预训练权重。|`'IMAGENET'`| +|`learning_rate`|`float`|训练时使用的学习率大小,适用于默认优化器。|`0.1`| +|`lr_decay_power`|`float`|学习率衰减系数,适用于默认优化器。|`0.9`| +|`early_stop`|`bool`|训练过程是否启用早停策略。|`False`| +|`early_stop_patience`|`int`|启用早停策略时的`patience`参数(参见[`EarlyStop`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/utils/utils.py))。|`5`| +|`use_vdl`|`bool`|是否启用VisualDL日志。|`True`| +|`resume_checkpoint`|`str` \| `None`|检查点路径。PaddleRS支持从检查点(包含先前训练过程中存储的模型权重和优化器权重)继续训练,但需注意`resume_checkpoint`与`pretrain_weights`不得同时设置为`None`以外的值。|`None`| + +### `BaseDetector.train()` + +接口形式: + +```python +def train(self, + num_epochs, + train_dataset, + train_batch_size=64, + eval_dataset=None, + optimizer=None, + save_interval_epochs=1, + log_interval_steps=10, + save_dir='output', + pretrain_weights='IMAGENET', + learning_rate=.001, + warmup_steps=0, + warmup_start_lr=0.0, + lr_decay_epochs=(216, 243), + lr_decay_gamma=0.1, + metric=None, + use_ema=False, + early_stop=False, + early_stop_patience=5, + use_vdl=True, + resume_checkpoint=None): +``` + +其中各参数的含义如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`num_epochs`|`int`|训练的epoch数目。|| +|`train_dataset`|`paddlers.datasets.COCODetDataset` \| `paddlers.datasets.VOCDetDataset` |训练数据集。|| +|`train_batch_size`|`int`|训练时使用的batch size(多卡训练时,为所有设备合计batch size)。|`64`| +|`eval_dataset`|`paddlers.datasets.COCODetDataset` \| `paddlers.datasets.VOCDetDataset` \| `None`|验证数据集。|`None`| +|`optimizer`|`paddle.optimizer.Optimizer` \| `None`|训练时使用的优化器。若为`None`,则使用默认定义的优化器。|`None`| +|`save_interval_epochs`|`int`|训练时存储模型的间隔epoch数。|`1`| +|`log_interval_steps`|`int`|训练时打印日志的间隔step数(即迭代数)。|`10`| +|`save_dir`|`str`|存储模型的路径。|`'output'`| +|`pretrain_weights`|`str` \| `None`|预训练权重的名称/路径。若为`None`,则不适用预训练权重。|`'IMAGENET'`| +|`learning_rate`|`float`|训练时使用的学习率大小,适用于默认优化器。|`0.001`| +|`warmup_steps`|`int`|默认优化器使用[warm-up策略](https://www.mdpi.com/2079-9292/10/16/2029/htm)的预热轮数。|`0`| +|`warmup_start_lr`|`int`|默认优化器warm-up阶段使用的初始学习率。|`0`| +|`lr_decay_epochs`|`list` \| `tuple`|默认优化器学习率衰减的milestones,以epoch计。即,在第几个epoch执行学习率的衰减。|`(216, 243)`| +|`lr_decay_gamma`|`float`|学习率衰减系数,适用于默认优化器。|`0.1`| +|`metric`|`str` \| `None`|评价指标,可以为`'VOC'`、`COCO`或`None`。若为`Nnoe`,则根据数据集格式自动确定使用的评价指标。|`None`| +|`use_ema`|`bool`|是否启用[指数滑动平均策略](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/models/ppdet/optimizer.py)更新模型权重参数。|`False`| +|`early_stop`|`bool`|训练过程是否启用早停策略。|`False`| +|`early_stop_patience`|`int`|启用早停策略时的`patience`参数(参见[`EarlyStop`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/utils/utils.py))。|`5`| +|`use_vdl`|`bool`|是否启用VisualDL日志。|`True`| +|`resume_checkpoint`|`str` \| `None`|检查点路径。PaddleRS支持从检查点(包含先前训练过程中存储的模型权重和优化器权重)继续训练,但需注意`resume_checkpoint`与`pretrain_weights`不得同时设置为`None`以外的值。|`None`| + +### `BaseSegmenter.train()` + +接口形式: + +```python +def train(self, + num_epochs, + train_dataset, + train_batch_size=2, + eval_dataset=None, + optimizer=None, + save_interval_epochs=1, + log_interval_steps=2, + save_dir='output', + pretrain_weights='CITYSCAPES', + learning_rate=0.01, + lr_decay_power=0.9, + early_stop=False, + early_stop_patience=5, + use_vdl=True, + resume_checkpoint=None): +``` + +其中各参数的含义如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`num_epochs`|`int`|训练的epoch数目。|| +|`train_dataset`|`paddlers.datasets.SegDataset`|训练数据集。|| +|`train_batch_size`|`int`|训练时使用的batch size。|`2`| +|`eval_dataset`|`paddlers.datasets.SegDataset` \| `None`|验证数据集。|`None`| +|`optimizer`|`paddle.optimizer.Optimizer` \| `None`|训练时使用的优化器。若为`None`,则使用默认定义的优化器。|`None`| +|`save_interval_epochs`|`int`|训练时存储模型的间隔epoch数。|`1`| +|`log_interval_steps`|`int`|训练时打印日志的间隔step数(即迭代数)。|`2`| +|`save_dir`|`str`|存储模型的路径。|`'output'`| +|`pretrain_weights`|`str` \| `None`|预训练权重的名称/路径。若为`None`,则不适用预训练权重。|`'CITYSCAPES'`| +|`learning_rate`|`float`|训练时使用的学习率大小,适用于默认优化器。|`0.01`| +|`lr_decay_power`|`float`|学习率衰减系数,适用于默认优化器。|`0.9`| +|`early_stop`|`bool`|训练过程是否启用早停策略。|`False`| +|`early_stop_patience`|`int`|启用早停策略时的`patience`参数(参见[`EarlyStop`](https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/utils/utils.py))。|`5`| +|`use_vdl`|`bool`|是否启用VisualDL日志。|`True`| +|`resume_checkpoint`|`str` \| `None`|检查点路径。PaddleRS支持从检查点(包含先前训练过程中存储的模型权重和优化器权重)继续训练,但需注意`resume_checkpoint`与`pretrain_weights`不得同时设置为`None`以外的值。|`None`| + +## `evaluate()` + +### `BaseChangeDetector.evaluate()` + +接口形式: + +```python +def evaluate(self, eval_dataset, batch_size=1, return_details=False): +``` + +输入参数如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`eval_dataset`|`paddlers.datasets.CDDataset`|评估数据集。|| +|`batch_size`|`int`|评估时使用的batch size(多卡训练时,为所有设备合计batch size)。|`1`| +|`return_details`|`bool`|是否返回详细信息。|`False`| + +当`return_details`为`False`(默认行为)时,输出为一个`collections.OrderedDict`对象。对于二类变化检测任务,输出包含如下键值对: + +``` +{"iou": 变化类的IoU指标, + "f1": 变化类的F1分数, + "oacc": 总体精度(准确率), + "kappa": kappa系数} +``` + +对于多类变化检测任务,输出包含如下键值对: + +``` +{"miou": mIoU指标, + "category_iou": 各类的IoU指标, + "oacc": 总体精度(准确率), + "category_acc": 各类精确率, + "kappa": kappa系数, + "category_F1score": 各类F1分数} +``` + +当`return_details`为`True`时,返回一个由两个字典构成的二元组,其中第一个元素为上述评价指标,第二个元素为仅包含一个key的字典,其`'confusion_matrix'`键对应值为以Python built-in list存储的混淆矩阵。 + +### `BaseClassifier.evaluate()` + +接口形式: + +```python +def evaluate(self, eval_dataset, batch_size=1, return_details=False): +``` + +输入参数如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`eval_dataset`|`paddlers.datasets.ClasDataset`|评估数据集。|| +|`batch_size`|`int`|评估时使用的batch size(多卡训练时,为所有设备合计batch size)。|`1`| +|`return_details`|`bool`|*当前版本请勿手动设置此参数。*|`False`| + +输出为一个`collections.OrderedDict`对象,包含如下键值对: + +``` +{"top1": top1准确率, + "top5": `top5准确率} +``` + +### `BaseDetector.evaluate()` + +接口形式: + +```python +def evaluate(self, + eval_dataset, + batch_size=1, + metric=None, + return_details=False): +``` + +输入参数如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`eval_dataset`|`paddlers.datasets.COCODetDataset` \| `paddlers.datasets.VOCDetDataset`|评估数据集。|| +|`batch_size`|`int`|评估时使用的batch size(多卡训练时,为所有设备合计batch size)。|`1`| +|`metric`|`str` \| `None`|评价指标,可以为`'VOC'`、`COCO`或`None`。若为`Nnoe`,则根据数据集格式自动确定使用的评价指标。|`None`| +|`return_details`|`bool`|是否返回详细信息。|`False`| + +当`return_details`为`False`(默认行为)时,输出为一个`collections.OrderedDict`对象,包含如下键值对: + +``` +{"bbox_mmap": 预测结果的mAP值} +``` + +当`return_details`为`True`时,返回一个由两个字典构成的二元组,其中第一个字典为上述评价指标,第二个字典包含如下3个键值对: + +``` +{"gt": 数据集标注信息, + "bbox": 预测得到的目标框信息, + "mask": 预测得到的掩模图信息} +``` + +### `BaseSegmenter.evaluate()` + +接口形式: + +```python +def evaluate(self, eval_dataset, batch_size=1, return_details=False): +``` + +输入参数如下: + +|参数名称|类型|参数说明|默认值| +|-------|----|--------|-----| +|`eval_dataset`|`paddlers.datasets.SegDataset`|评估数据集。|| +|`batch_size`|`int`|评估时使用的batch size(多卡训练时,为所有设备合计batch size)。|`1`| +|`return_details`|`bool`|是否返回详细信息。|`False`| + +当`return_details`为`False`(默认行为)时,输出为一个`collections.OrderedDict`对象,包含如下键值对: + +``` +{"miou": mIoU指标, + "category_iou": 各类的IoU指标, + "oacc": 总体精度(准确率), + "category_acc": 各类精确率, + "kappa": kappa系数, + "category_F1score": 各类F1分数} +``` + +当`return_details`为`True`时,返回一个由两个字典构成的二元组,其中第一个元素为上述评价指标,第二个元素为仅包含一个key的字典,其`'confusion_matrix'`键对应值为以Python built-in list存储的混淆矩阵。 diff --git a/docs/apis/transforms.md b/docs/apis/transforms.md deleted file mode 100644 index f43b3e0..0000000 --- a/docs/apis/transforms.md +++ /dev/null @@ -1,53 +0,0 @@ -# 数据增强 - -PaddleRS将多种任务需要的数据增强进行了有机整合,均通过`Compose`进行使用,数据读取方面通过`DecodeImg`可以对不只三通道RGB图像进行读取,还可以对SAR以及多通道图像进行读取,提供有转为`uint8`的选项。此外提供以下数据增强的方法。 - -| 数据增强名称 | 用途 | 任务 | ... | -| -------------------- | ----------------------------------------------- | -------- | ---- | -| Resize | 调整输入大小 | 所有 | ... | -| RandomResize | 随机调整输入大小 | 所有 | ... | -| ResizeByShort | 调整输入大小,保持纵横比不变 | 所有 | ... | -| RandomResizeByShort | 随机调整输入大小,保持纵横比不变 | 所有 | ... | -| ResizeByLong | 调整输入大小,保持纵横比不变 | 所有 | ... | -| RandomHorizontalFlip | 随机水平翻转输入 | 所有 | ... | -| RandomVerticalFlip | 随机竖直翻转输入 | 所有 | ... | -| Normalize | 对输入中的图像应用最小-最大标准化 | 所有 | ... | -| CenterCrop | 对输入进行中心裁剪 | 所有 | ... | -| RandomCrop | 对输入进行随机中心裁剪 | 所有 | ... | -| RandomScaleAspect | 裁剪输入并重新调整大小至原始大小 | 所有 | ... | -| RandomExpand | 通过根据随机偏移填充来随机扩展输入 | 所有 | ... | -| Pad | 将输入填充到指定的大小 | 所有 | ... | -| MixupImage | 将两张图片和它们的`gt_bbbox/gt_score`混合在一起 | 目标检测 | ... | -| RandomDistort | 对输入进行随机色彩变换 | 所有 | ... | -| RandomBlur | 对输入进行随机模糊 | 所有 | ... | -| Dehaze | 对输入图像进行去雾 | 所有 | ... | -| ReduceDim | 对输入图像进行降维 | 所有 | ... | -| SelectBand | 选择输入图像的波段 | 所有 | ... | -| RandomSwap | 随机交换两个输入图像 | 变化检测 | ... | -| ... | ... | | ... | - -## 如何使用 - -以变化检测任务为例,其余任务的使用方法与此类似。 - -```python -import paddlers.transforms as T -from paddlers.datasets import CDDataset - - -train_transforms = T.Compose([ - T.DecodeImg(), - T.Resize(target_size=512), - T.RandomHorizontalFlip(), - T.Normalize( - mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]), - T.ArrangeChangeDetector('train') -]) - -train_dataset = CDDataset( - data_dir='xxx/xxx', - file_list='xxx/train_list.txt', - label_list='xxx/labels.txt', - transforms=train_transforms, - shuffle=True) -``` diff --git a/docs/cases/csc_cd_cn.md b/docs/cases/csc_cd_cn.md index 169fb10..b6f0678 100644 --- a/docs/cases/csc_cd_cn.md +++ b/docs/cases/csc_cd_cn.md @@ -588,5 +588,5 @@ Image.frombytes('RGB', fig.canvas.get_width_height(), fig.canvas.tostring_rgb()) ## 参考资料 -- [遥感数据介绍](https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/data/rs_data_cn.md) +- [遥感数据介绍](https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/data/rs_data.md) - [PaddleRS文档](https://github.com/PaddlePaddle/PaddleRS/blob/develop/tutorials/train/README.md) diff --git a/docs/data/coco_tools_cn.md b/docs/data/coco_tools.md similarity index 63% rename from docs/data/coco_tools_cn.md rename to docs/data/coco_tools.md index 362c427..3e8f81e 100644 --- a/docs/data/coco_tools_cn.md +++ b/docs/data/coco_tools.md @@ -1,31 +1,30 @@ -# coco_tools说明 +# coco_tools使用说明 -## 0.工具说明 +## 1 工具说明 -coco_tools是PaddleRS中,用coco类标注文件处理的工具集,详见[tools/coco_tools/](tools/coco_tools/)。 +coco_tools是PaddleRS提供的用于处理COCO格式标注文件的工具集,位于`tools/coco_tools/`目录。由于[pycocotools库](https://pypi.org/project/pycocotools/)在部分环境下无法安装,PaddleRS提供coco_tools作为替代,进行一些简单的文件处理工作。 -由于pycocotools库在部分环境下无法安装,因此可以使用coco_tools进行一些简单的文件处理工作。 - -## 1.文件说明 +## 2 文件说明 目前coco_tools共有6个文件,各文件及其功能如下: -* json_InfoShow: 打印json文件中各个字典的基本信息; -* json_ImgSta: 统计json文件中的图像信息,生成统计表、统计图; -* json_AnnoSta: 统计json文件中的标注信息,生成统计表、统计图; -* json_Img2Json: 统计test集图像,生成json文件; -* json_Split: json文件拆分,划分为train set、val set -* json_Merge: json文件合并,将多个json合并为1个json +- `json_InfoShow.py`: 打印json文件中各个字典的基本信息; +- `json_ImgSta.py`: 统计json文件中的图像信息,生成统计表、统计图; +- `json_AnnoSta.py`: 统计json文件中的标注信息,生成统计表、统计图; +- `json_Img2Json.py`: 统计test集图像,生成json文件; +- `json_Split.py`: 将json文件中的内容划分为train set和val set; +- `json_Merge.py`: 将多个json文件合并为1个。 -## 2. 应用案例说明 +## 3 使用示例 -通过本教程,你将快速学会PaddleRS中关于coco_tools的API调用,帮助你完成coco类数据集的信息统计、文件操作。 +## 3.1 示例数据集 -## 2.1 示例数据集 +本文档以COCO 2017数据集作为示例数据进行演示。您可以在以下链接下载该数据集: -本文档以COCO 2017数据集作为示例数据,进行演示。COCO 2017 [官方下载链接](https://cocodataset.org/#download)、[aistudio备份链接](https://aistudio.baidu.com/aistudio/datasetdetail/7122) +- [官方下载链接](https://cocodataset.org/#download) +- [aistudio备份链接](https://aistudio.baidu.com/aistudio/datasetdetail/7122) -COCO 2017 文件结构 +下载完成后,为方便后续使用,您可以将`coco_tools`目录从PaddleRS项目中复制或链接到数据集目录中。完整的数据集目录结构如下: ``` ./COCO2017/ # 数据集根目录 @@ -48,15 +47,13 @@ COCO 2017 文件结构 | |--... ``` -## 2.2 打印json信息 - -使用json_InfoShow.py,可以打印`instances_val2017.json`中的各个key, 并输出value中的前n个元素,从而帮助快速了解标注信息。 +## 3.2 打印json信息 -尤其是对于coco格式标注数据中的image、annotation,可以查看其具体的标注格式 +使用`json_InfoShow.py`可以打印json文件中的各个键值对的key, 并输出value中排列靠前的元素,从而帮助您快速了解标注信息。对于COCO格式标注数据而言,您应该特别留意`'image'`和`'annotation'`字段的内容。 -### 2.2.1 命令演示 +### 3.2.1 命令演示 -可以执行如下命令,打印`instances_val2017.json`信息 +执行如下命令,打印`instances_val2017.json`中的信息: ``` python ./coco_tools/json_InfoShow.py \ @@ -64,16 +61,16 @@ python ./coco_tools/json_InfoShow.py \ --show_num 5 ``` -### 2.2.2 参数说明 +### 3.2.2 参数说明 -| 参数名 | 含义 | 默认值 | -| ------------- | ------------------------------ | -------- | -| --json_path | 需要统计的json文件路径 | | -| --show_num | (可选)输出value元素的个数 | 5 | -| --Args_show | (可选)是否打印输入的参数信息 | True | +| 参数名 | 含义 | 默认值 | +| ------------- | ------------------------------------| -------- | +| `--json_path` | 需要统计的json文件路径 | | +| `--show_num` | (可选)输出value中排列靠前的元素的个数 | `5` | +| `--Args_show` | (可选)是否打印输入参数信息 | `True` | -### 2.2.3 结果展示 +### 3.2.3 结果展示 执行上述命令后,输出结果如下: @@ -154,31 +151,28 @@ contributor : COCO Consortium ``` -### 2.2.4 结果说明 +### 3.2.4 结果说明 -`instances_val2017.json`的key有5个,分别为 +`instances_val2017.json`的key有5个,分别为: ``` 'info', 'licenses', 'images', 'annotations', 'categories' ``` +其中, -info键,对应的值为字典,共有6个键值对,输出展示了前5对 - -licenses键,对应的值为列表,共有8个元素,输出展示了前5个 - -images键,对应的值为列表,共有5000个元素,输出展示了前5个 - -annotations键,对应的值为列表,共有36781个元素,输出展示了前5个 +- `info`键对应的值为字典,共有6个键值对,输出展示了前5对; +- `licenses`键对应的值为列表,共有8个元素,输出展示了前5个; +- `images`键对应的值为列表,共有5000个元素,输出展示了前5个; +- `annotations`键对应的值为列表,共有36781个元素,输出展示了前5个; +- `categories`键对应的值为列表,共有80个元素,输出展示了前5个。 -categories键,对应的值为列表,共有80个元素,输出展示了前5个 +## 3.3 统计图像信息 -## 2.3 统计图像信息 +使用`json_ImgSta.py`可以从`instances_val2017.json`中快速提取图像信息,生成csv表格,并生成统计图。 -使用json_ImgSta.py,可以从`instances_val2017.json`中,快速提取图像信息,生成csv表格,并生成统计图 +### 3.3.1 命令演示 -### 2.3.1 命令演示 - -可以执行如下命令,打印`instances_val2017.json`信息 +执行如下命令,打印`instances_val2017.json`信息: ``` python ./coco_tools/json_ImgSta.py \ @@ -188,19 +182,18 @@ python ./coco_tools/json_ImgSta.py \ --png_shapeRate_path=./img_sta/images_shapeRate.png ``` -### 2.3.2 参数说明 - +### 3.3.2 参数说明 -| 参数名 | 含义 | 默认值 | +| 参数名 | 含义 | 默认值 | | ---------------------- | --------------------------------------------------------------------- | -------- | -| --json_path | 需要统计的json文件路径 | | -| --csv_path | (可选)统计表格保存路径 | None | -| --png_shape_path | (可选)png图片保存路径,图片内容为所有图像shape的二维分布 | 5 | -| --png_shapeRate_path | (可选)png图片保存路径,图片内容为所有图像shape比例(宽/高)的一维分布 | 5 | -| --image_keyname | (可选)json文件中,图像key的名称 | images | -| --Args_show | (可选)是否打印输入的参数信息 | True | +| `--json_path` | 需要统计的json文件路径 | | +| `--csv_path` | (可选)统计表格保存路径 | `None` | +| `--png_shape_path` | (可选)png图片保存路径,图片内容为所有图像shape的二维分布 | `5` | +| `--png_shapeRate_path` | (可选)png图片保存路径,图片内容为所有图像shape比例(宽/高)的一维分布 | `5` | +| `--image_keyname` | (可选)json文件中,图像所对应的key |`'images'`| +| `--Args_show` | (可选)是否打印输入参数信息 |`True` | -### 2.3.3 结果展示 +### 3.3.3 结果展示 执行上述命令后,输出结果如下: @@ -233,18 +226,19 @@ csv save to ./img_sta/images.csv 保存的图片内容: -所有图像shape的二维分布 +所有图像shape的二维分布: ![image.png](./assets/1650011491220-image.png) -所有图像shape比例(宽/高)的一维分布 + +所有图像shape比例(宽/高)的一维分布: ![image.png](./assets/1650011634205-image.png) -## 2.4 统计目标检测标注框信息 +## 3.4 统计目标检测标注框信息 -使用json_AnnoSta.py,可以从`instances_val2017.json`中,快速提取图像信息,生成csv表格,并生成统计图 +使用`json_AnnoSta.py`,可以从`instances_val2017.json`中快速提取标注信息,生成csv表格,并生成统计图。 -### 2.4.1 命令演示 +### 3.4.1 命令演示 -可以执行如下命令,打印`instances_val2017.json`信息 +执行如下命令,打印`instances_val2017.json`信息: ``` python ./coco_tools/json_AnnoSta.py \ @@ -259,25 +253,24 @@ python ./coco_tools/json_AnnoSta.py \ --get_relative=True ``` -### 2.4.2 参数说明 - +### 3.4.2 参数说明 -| 参数名 | 含义 | 默认值 | +| 参数名 | 含义 | 默认值 | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------- | -| --json_path | (可选)需要统计的json文件路径 | | -| --csv_path | (可选)统计表格保存路径 | None | -| --png_shape_path | (可选)png图片保存路径,图片内容为所有目标检测框shape的二维分布 | None | -| --png_shapeRate_path | (可选)png图片保存路径,图片内容为所有目标检测框shape比例(宽/高)的一维分布 | None | -| --png_pos_path | (可选)png图片保存路径,图片内容为所有目标检测框左上角坐标的二维分布 | None | -| --png_posEnd_path | (可选)png图片保存路径,图片内容为所有目标检测框右下角坐标的二维分布 | None | -| --png_cat_path | (可选)png图片保存路径,图片内容为各个类别的对象数量分布 | None | -| --png_objNum_path | (可选)png图片保存路径,图片内容为单个图像中含有标注对象的数量分布 | None | -| --get_relative | (可选)是否生成图像目标检测框shape、目标检测框左上角坐标、右下角坐标的相对比例值
    (横轴坐标/图片长,纵轴坐标/图片宽) | None | -| --image_keyname | (可选)json文件中,图像key的名称 | images | -| --anno_keyname | (可选)json文件中,图像anno的名称 | annotations | -| --Args_show | (可选)是否打印输入的参数信息 | True | - -### 2.4.3 结果展示 +| `--json_path` | (可选)需要统计的json文件路径 | | +| `--csv_path` | (可选)统计表格保存路径 | `None` | +| `--png_shape_path` | (可选)png图片保存路径,图片内容为所有目标检测框shape的二维分布 | `None` | +| `--png_shapeRate_path` | (可选)png图片保存路径,图片内容为所有目标检测框shape比例(宽/高)的一维分布 | `None` | +| `--png_pos_path` | (可选)png图片保存路径,图片内容为所有目标检测框左上角坐标的二维分布 | `None` | +| `--png_posEnd_path` | (可选)png图片保存路径,图片内容为所有目标检测框右下角坐标的二维分布 | `None` | +| `--png_cat_path` | (可选)png图片保存路径,图片内容为各个类别的对象数量分布 | `None` | +| `--png_objNum_path` | (可选)png图片保存路径,图片内容为单个图像中含有标注对象的数量分布 | `None` | +| `--get_relative` | (可选)是否生成图像目标检测框shape、目标检测框左上角坐标、右下角坐标的相对比例值
    (横轴坐标/图片长,纵轴坐标/图片宽) | `None` | +| `--image_keyname` | (可选)json文件中,图像所对应的key | `'images'` | +| `--anno_keyname` | (可选)json文件中,标注所对应的key | `'annotations'`| +| `--Args_show` | (可选)是否打印输入参数信息 | `True` | + +### 3.4.3 结果展示 执行上述命令后,输出结果如下: @@ -315,49 +308,49 @@ csv save to ./anno_sta/annos.csv ![image.png](./assets/1650025881244-image.png) -所有目标检测框shape的二维分布: +所有目标检测框shape的二维分布: ![image.png](./assets/1650025909461-image.png) -所有目标检测框shape在图像中相对比例的二维分布: +所有目标检测框shape在图像中相对比例的二维分布: ![image.png](./assets/1650026052596-image.png) -所有目标检测框shape比例(宽/高)的一维分布: +所有目标检测框shape比例(宽/高)的一维分布: ![image.png](./assets/1650026072233-image.png) -所有目标检测框左上角坐标的二维分布: +所有目标检测框左上角坐标的二维分布: ![image.png](./assets/1650026247150-image.png) -所有目标检测框左上角坐标的相对比例值的二维分布: +所有目标检测框左上角坐标的相对比例值的二维分布: ![image.png](./assets/1650026289987-image.png) -所有目标检测框右下角坐标的二维分布: +所有目标检测框右下角坐标的二维分布: ![image.png](./assets/1650026457254-image.png) -所有目标检测框右下角坐标的相对比例值的二维分布: +所有目标检测框右下角坐标的相对比例值的二维分布: ![image.png](./assets/1650026487732-image.png) -各个类别的对象数量分布 +各个类别的对象数量分布: ![image.png](./assets/1650026546304-image.png) -单个图像中含有标注对象的数量分布 +单个图像中含有标注对象的数量分布: ![image.png](./assets/1650026559309-image.png) -## 2.5 统计图像信息生成json +## 3.5 统计图像信息生成json -使用json_Test2Json.py,可以根据`test2017`中的文件信息与训练集json文件,快速提取图像信息,生成json文件 +使用`json_Test2Json.py`,可以根据`test2017`中的文件信息与训练集json文件快速提取图像信息,生成测试集json文件。 -### 2.5.1 命令演示 +### 3.5.1 命令演示 -可以执行如下命令,统计并生成`test2017`信息 +执行如下命令,统计并生成`test2017`信息: ``` python ./coco_tools/json_Img2Json.py \ @@ -366,19 +359,19 @@ python ./coco_tools/json_Img2Json.py \ --json_test_path=./test.json ``` -### 2.5.2 参数说明 +### 3.5.2 参数说明 -| 参数名 | 含义 | 默认值 | +| 参数名 | 含义 | 默认值 | | ------------------- | ---------------------------------------- | ------------ | -| --test_image_path | 需要统计的图像文件夹路径 | | -| --json_train_path | 用于参考的训练集json文件路径 | | -| --json_test_path | 生成的测试集json文件路径 | | -| --image_keyname | (可选)json文件中,图像key的名称 | images | -| --cat_keyname | (可选)json文件中,图像categories的名称 | categories | -| --Args_show | (可选)是否打印输入的参数信息 | True | +| `--test_image_path` | 需要统计的图像目录路径 | | +| `--json_train_path` | 用于参考的训练集json文件路径 | | +| `--json_test_path` | 生成的测试集json文件路径 | | +| `--image_keyname` | (可选)json文件中,图像对应的key | `'images'` | +| `--cat_keyname` | (可选)json文件中,类别对应的key | `'categories'`| +| `--Args_show` | (可选)是否打印输入参数信息 | `True` | -### 2.5.3 结果展示 +### 3.5.3 结果展示 执行上述命令后,输出结果如下: @@ -438,13 +431,13 @@ json keys: dict_keys(['images', 'categories']) ... ``` -## 2.6 json文件拆分 +## 3.6 json文件拆分 -使用json_Split.py,可以拆分`instances_val2017.json`文件 +使用`json_Split.py`,可以将`instances_val2017.json`文件拆分为2个子集。 -### 2.6.1 命令演示 +### 3.6.1 命令演示 -可以执行如下命令,拆分`instances_val2017.json`文件 +执行如下命令,拆分`instances_val2017.json`文件: ``` python ./coco_tools/json_Split.py \ @@ -453,22 +446,22 @@ python ./coco_tools/json_Split.py \ --json_val_path=./instances_val2017_val.json ``` -### 2.6.2 参数说明 +### 3.6.2 参数说明 -| 参数名 | 含义 | 默认值 | +| 参数名 | 含义 | 默认值 | | -------------------- | ------------------------------------------------------------------------------------- | ------------ | -| --json_all_path | 需要拆分的json文件路径 | | -| --json_train_path | 生成的train部分json文件 | | -| --json_val_path | 生成的val部分json文件 | | -| --val_split_rate | (可选)拆分过程中,val集文件的比例 | 0.1 | -| --val_split_num | (可选)拆分过程中,val集文件的数量,
    如果设置了该参数,则val_split_rate参数失效 | None | -| --keep_val_inTrain | (可选)拆分过程中,是否在train中仍然保留val部分 | False | -| --image_keyname | (可选)json文件中,图像key的名称 | images | -| --cat_keyname | (可选)json文件中,图像categories的名称 | categories | -| --Args_show | (可选)是否打印输入的参数信息 | True | - -### 2.6.3 结果展示 +| `--json_all_path` | 需要拆分的json文件路径 | | +| `--json_train_path` | 生成的train部分json文件 | | +| `--json_val_path` | 生成的val部分json文件 | | +| `--val_split_rate` | (可选)拆分过程中,val集文件的比例 | `0.1` | +| `--val_split_num` | (可选)拆分过程中,val集文件的数量,
    如果设置了该参数,则`--val_split_rate`参数失效 | `None` | +| `--keep_val_inTrain` | (可选)拆分过程中,是否在train中仍然保留val部分 | `False` | +| `--image_keyname` | (可选)json文件中,图像对应的key | `'images'` | +| `--cat_keyname` | (可选)json文件中,类别对应的key | `'categories'`| +| `--Args_show` | (可选)是否打印输入参数信息 | `'True'` | + +### 3.6.3 结果展示 执行上述命令后,输出结果如下: @@ -492,13 +485,13 @@ image total 5000, train 4500, val 500 anno total 36781, train 33119, val 3662 ``` -## 2.7 json文件合并 +## 3.7 json文件合并 -使用json_Merge.py,可以合并`instances_train2017.json、instances_val2017.json`文件 +使用`json_Merge.py`,可以合并2个json文件。 -### 2.7.1 命令演示 +### 3.7.1 命令演示 -可以执行如下命令,合并`instances_train2017.json、instances_val2017.json`文件 +执行如下命令,合并`instances_train2017.json`与`instances_val2017.json`: ``` python ./coco_tools/json_Merge.py \ @@ -507,18 +500,18 @@ python ./coco_tools/json_Merge.py \ --save_path=./instances_trainval2017.json ``` -### 2.7.2 参数说明 +### 3.7.2 参数说明 -| 参数名 | 含义 | 默认值 | +| 参数名 | 含义 | 默认值 | | -------------- | ------------------------------- | --------------------------- | -| --json1_path | 需要合并的json文件1路径 | | -| --json2_path | 需要合并的json文件2路径 | | -| --save_path | 生成的json文件 | | -| --merge_keys | (可选)合并过程中需要合并的key | ['images', 'annotations'] | -| --Args_show | (可选)是否打印输入的参数信息 | True | +| `--json1_path` | 需要合并的json文件1路径 | | +| `--json2_path` | 需要合并的json文件2路径 | | +| `--save_path` | 生成的json文件 | | +| `--merge_keys` | (可选)合并过程中需要合并的key | `['images', 'annotations']` | +| `--Args_show` | (可选)是否打印输入参数信息 | `True` | -### 2.7.3 结果展示 +### 3.7.3 结果展示 执行上述命令后,输出结果如下: diff --git a/docs/data/dataset.md b/docs/data/dataset.md new file mode 100644 index 0000000..0f8dc4c --- /dev/null +++ b/docs/data/dataset.md @@ -0,0 +1,19 @@ +# 遥感开源数据集 + +PaddleRS搜集汇总了遥感领域常用的**开源**深度学习数据集,提供每个数据集的以下信息:数据集说明,影像信息,标注信息,源地址,AI Studio备份链接。这些数据集按任务类型可分为**图像分类、图像分割、变化检测、目标检测、目标跟踪、多标签分类、图像生成**等多种类型。目前已收录的遥感数据集有: + +* 图像分类数据集32个; +* 目标检测数据集40个; +* 图像分割数据集70个; +* 变化检测数据集28个; +* 实例分割数据集7个; +* 多标签分类数据集3个; +* 目标跟踪数据集9个; +* 图像标题数据集3个; +* 图像生成数据集8个。 + +欢迎访问[遥感数据集汇总](./dataset_summary.md),以获取详细信息。 + +## 特别贡献数据集 + +* 2020年中国典型城市道路样本数据CHN6-CUG,由中国地质大学[朱祺琪](http://grzy.cug.edu.cn/zhuqiqi)教授提供。相关介绍和下载方式请参考[此处](http://grzy.cug.edu.cn/zhuqiqi/zh_CN/yjgk/32368/content/1733.htm)。 diff --git a/docs/data/dataset_cn.md b/docs/data/dataset_cn.md deleted file mode 100644 index 7242473..0000000 --- a/docs/data/dataset_cn.md +++ /dev/null @@ -1,20 +0,0 @@ -## 公开数据集 - -PaddleRS搜集汇总了 遥感影像领域 常用的 **开源**深度学习数据集,每个数据集信息包括:数据集说明,影像信息,标注信息,源地址,aistudio备份链接。这些数据集按任务类型可分为 **图像分类、图像分割、变化检测、目标检测、目标跟踪、多标签分类、图像生成** 等多种类型,目前已收录的遥感数据集: - -* 图像分类数据集32个; -* 目标检测数据集40个; -* 图像分割数据集70个; -* 变化检测数据集28个; -* 实例分割数据集7个; -* 多标签分类数据集3个; -* 目标跟踪数据集9个; -* 图像标题数据集3个; -* 图像生成数据集8个 - - -欢迎访问[遥感数据集汇总](./dataset_summary.md),获取详细数据集内容。 - -## 特别贡献数据集 - -* 2020年中国典型城市道路样本数据CHN6-CUG,由中国地质大学[朱祺琪](http://grzy.cug.edu.cn/zhuqiqi)教授提供,相关介绍和下载方式请参考[该地址](http://grzy.cug.edu.cn/zhuqiqi/zh_CN/yjgk/32368/content/1733.htm)。 diff --git a/docs/data/rs_data.md b/docs/data/rs_data.md new file mode 100644 index 0000000..c453330 --- /dev/null +++ b/docs/data/rs_data.md @@ -0,0 +1,111 @@ +# 遥感数据介绍 + +## 1 遥感与遥感影像的定义 + +广义上,遥感指的是"遥远的感知",即在不直接接触的情况下,对目标或自然现象进行远距离探测和感知。狭义上的遥感一般指电磁波遥感技术,即在某种平台(如飞机或卫星)上利用传感器探测电磁波的反射特性、并从中提取信息的过程。这个过程获取的影像数据被称作遥感影像,一般包括卫星和航空影像。遥感数据的用途广泛,在诸如空间分析等GIS任务中、或是包括场景分类、影像分割与目标检测在内的计算机视觉(Computer Vision, CV)领域都可以见到它们的身影。 + +相比航空影像,卫星影像的覆盖面积更广,因此得到了更加长足的应用。常见的卫星影像可能由商业卫星摄制,也可能来自NASA、ESA等机构的开放数据库。 + +## 2 遥感影像的特点 + +遥感技术具有宏观性、多波段性、周期性和经济性的特点。其中,宏观性指的是遥感平台越高,视角就越广,可以同步探测到的地面范围就越广;多波段性指的是传感器可以从紫外、可见光、近红外到微波等各个不同波段进行探测和记录信息;周期性指的是遥感卫星具有以一定周期重复获取图像的特点,可以在短时间内对同一地区进行重复观测;经济性指的是遥感技术可以作为一种获取大面积地表信息的方式,而相对不需要花费太多人力物力。 + +遥感技术的特点决定了遥感影像具有如下特性: + +1. 大尺度。一幅遥感影像能够覆盖广大的地表面积。 +2. 多光谱。相比自然图像,遥感影像往往具有较多的波段数。 +3. 来源丰富。不同传感器、不同卫星可以提供多样的数据源。 + +## 3 栅格影像的定义与遥感影像成像原理 + +为介绍遥感影像的成像原理,首先需要引入栅格的概念。栅格是一种基于像素的数据格式,可以有效地表示连续表面。栅格中的信息存储在网格结构中,每个信息单元或像素具有相同的大小和形状,但值不同。数码照片、正射影像和卫星影像都可以这种格式存储。 + +栅格格式非常适合用于查看空间和时间变化的分析,因为每个数据值都有一个基于网格的可访问位置。这使我们能够访问两个或多个不同栅格中的相同地理位置并比较它们的值。 + +当地球观测卫星拍摄照片时,传感器会记录不同波长电磁波在栅格像元中的DN值(Digital Number)。通过DN值,可以反求地物的辐照率和反射率。它们之间的关系如以下公式所示,其中$gain$和$bias$分别指传感器的增益和偏移;$L$是辐射率,也称为辐射亮度值;$\rho$是地物反射率;$d_{s}$、$E_{0}$和$\theta$分别表示日地天文单位距离、太阳辐照度以及太阳天顶角。 + +$$ +L = gain * DN + bias \\ +\rho = \pi Ld^{2}_{s}/(E_{0}\cos{\theta}) +$$ + +电磁波谱是人类根据电磁波的波长或频率、波数、能量等的大小顺序进行排列的成果。在电磁波谱中人眼只能感受到一个很小的波段范围,这个范围被称为可见光,波长范围在0.38-0.76μm。这是因为我们的视觉进化为在太阳发出最多光的地方最敏感,并且广泛地局限于构成我们所谓的红色、绿色和蓝色的波长。但卫星传感器可以感知范围更广的电磁频谱,这使得我们能够与借助传感器感知更多的频谱范围。 + +![band](../images/band.jpg) + +电磁波谱范围很广,使用一个传感器同时收集所有波长的信息是不切实际的。在实际中,不同的传感器优先考虑从不同波长的光谱收集信息。由传感器捕获和分类的频谱的每个部分都被归类为一个信息带。信息带的大小各不相同,可以编译成不同类型的合成影像,每幅合成影像都强调不同的物理特性。同时,大多数遥感影像都为16位的图像,与传统的8位图像不同,它能表示更精细的光谱信息。 + +## 4 遥感影像的分类 + +遥感影像具有覆盖面积广、波段数多、来源丰富等特点,其分类方式也十分多样。例如,根据空间分辨率,可将遥感影像分为低分辨率遥感影像、中分辨率遥感影像、高分辨率遥感影像等;根据波段数,又可分为多光谱影像、高光谱影像、全色影像等类型。本文档旨在为不具备遥感专业背景的开发者提供快速了解的途径,因此仅介绍几种常见的遥感影像类型。 + +### 4.1 RGB影像 + +RGB影像与生活中常见的自然图像类似,其中显示的地物特征也符合人类的视觉常识(如树是绿色的、水泥是灰色的等),三个通道分别表示红、绿和蓝。下图展示了一幅RGB遥感影像: + +![rgb](../images/rgb.jpg) + +由于当前大多数CV任务的处理流程都是基于自然图像设计的,因此RGB类型的遥感数据集在CV领域使用较多。 + +### 4.2 MSI/HSI影像 + +MSI(Multispectral Image,多光谱影像)和HSI(Hyperspectral Image,高光谱影像)通常包括数个到数百个不等的波段,二者以不同的光谱分辨率(*光谱分辨率是指传感器所能记录的电磁波谱中某一特定的波长范围值,波长范围值越宽,则光谱分辨率越低*)进行区分。通常光谱分辨率在波长的1/10数量级范围内称为多光谱。MSI的波段数相对HSI较少,谱带较宽,空间分辨率较高;而HSI的波段数较多,谱带较窄,光谱分辨率较高。 + +在实际中常常根据应用需求选取MSI/HSI的一些特定波段:例如中红外波段的透射率在60%-70%,包含地物反射及发射光谱,可以用来探测火灾等高温目标;红边波段(*绿色植物在0.67-0.76μm之间反射率增高最快的点,也是一阶导数光谱在该区间内的拐点*)是指示绿色植物生长状况的敏感性波段,可以有效地监测植被的生长状况,用于研究植物养分、健康状态监测、植被识别和生理生化参数等信息等。 + +下面以天宫一号高光谱成像仪拍摄的北京大兴机场为例,简单介绍一下MSI/HSI处理中常见的波段组合、光谱曲线和波段选择的概念。天宫一号高光谱数据集根据波段信噪比和信息熵评价结果剔除信噪比和信息熵较低的波段,并结合影像实际目视结果剔除部分波段,共保留可见近红外谱段54个、短波红外谱段52个以及全色谱段数据。 + +**波段组合** + +波段组合是指在MSI/HSI中选择三个波段数据进行组合、代替RGB三个通道所得到的结果,称为彩色图(*使用真实的RGB三波段合成的结果称为真彩色图,否则称为假彩色图*)。不同波段的组合能够突出不同的地物特征,下图展示了几种不同组合的目视效果: + +![图片3](../images/band_combination.jpg) + +**光谱曲线解读** + +光谱信息往往能够反映地物特征,不同的波段反映的地物特征也不尽相同。以电磁波的波长或频率为横轴,反射率为纵轴,可以绘制光谱曲线。以植被的光谱曲线为例,如下图所示,植被在0.8μm波段反射率大于40%,相比在0.6μm波段10%左右的反射率明显更大,因此在成像时反射回更多的辐射能量。体现在图中,植被部分在0.8μm的影像中看起来更加明亮。 + +![band_mean](../images/band_mean.jpg) + +**波段选择** + +MSI/HSI包含的波段数量可能较多。一方面,并不是所有波段都适用于待处理的任务;另一方面,过多的波段数可能带来沉重的资源负担。在实际应用中,可以根据需求选用MSI/HSI的部分波段完成任务,也可以使用如PCA、小波变换等方法对MSI/HSI进行降维处理,以减少冗余,节省计算资源。 + +### 4.3 SAR影像 + +SAR(Synthetic Aperture Radar)指的是主动式侧视雷达系统。SAR的成像几何属于斜距投影类型,因此SAR影像与光学影像在成像机理、几何特征、辐射特征等方面都有较大的区别。 + +光学影像中不同波段的信息来自于不同波长电磁波的反射能量,而SAR影像则以二进制复数形式记录了不同极化(*即电磁波发射和接收的振动方向*)的回波信息。基于记录的复数数据,可将原始的SAR影像通过变换提取相应的振幅和相位信息。人类无法直接分辨相位信息,但可以直观地感知振幅信息,利用振幅信息可以得到强度图像,如下图所示: + +![sar](../images/sar.jpg) + +由于SAR影像的特殊成像机理,其分辨率相对较低,信噪比也较低,所以SAR影像中所包含的振幅信息远达不到光学影像的成像水平。这也是为什么SAR影像在CV领域中的应用较少。目前,SAR影像被主要用于基于相位信息的沉降检测反演、三维重建等。值得一提的是,由于SAR的波长较长,具有一定的云层和地表穿透能力,因此在部分应用场景中有其独特的优势。 + +### 4.4 RGBD影像 + +RGBD影像与RGB影像的区别在于多了一个D通道,即深度(depth)。深度影像类似于灰度图像,只是其中的每个像素值代表的是传感器距离物体的实际距离。通常RGBD影像中的RGB数据和深度数据是相互配准的。如下图所示为无人机航摄的RGBD影像,其中可以看出建筑物与地面之间的相对高度。 + +![rgbd](../images/rgbd.jpg) + +深度影像提供了RGB影像所不具有的高度信息,能够在某些下游任务中对一些光谱特征相似的地物起到一定的区分作用。 + +## 5 遥感影像的预处理 + +相比自然图像,遥感影像的预处理过程十分繁琐。具体而言,主要可分为以下步骤: + +1. **辐射定标**:将DN值转化为辐射亮度值或者反射率等物理量。 +2. **大气校正**:消除由大气影响所造成的辐射误差,反演地物真实的表面反射率。该步骤与辐射定标合称为**辐射校正**。 +3. **正射校正**:对影像同时进行倾斜改正和投影差改正,将影像重采样为正射影像。 +4. **影像配准**:将不同时间、不同传感器(成像设备)或不同条件下(天候、照度、摄像位置和角度等)获取的两幅或多幅影像进行匹配、叠加。 +5. **影像融合**:将多源信道所采集到的关于同一目标的影像数据综合成高质量影像。 +6. **影像裁剪**:将大幅遥感影像裁剪为小块,提取感兴趣区域。 +7. **定义投影**:对数据定义投影信息(地理坐标系)。 + +需要说明的是,在实际应用中,上述的步骤并不都是必须的,可根据需要选择性地执行其中某些步骤。 + +## 参考资料 + +- [Remote sensing in Wikipedia](https://en.wikipedia.org/wiki/Remote_sensing) +- [宁津生等 《测绘学概论》](https://book.douban.com/subject/3116967/) +- [孙家抦 《遥感原理与应用》](https://book.douban.com/subject/3826668/) +- [遥感影像预处理步骤](https://blog.csdn.net/qq_35093027/article/details/119808941) diff --git a/docs/data/rs_data_cn.md b/docs/data/rs_data_cn.md deleted file mode 100644 index 6e4e66c..0000000 --- a/docs/data/rs_data_cn.md +++ /dev/null @@ -1,80 +0,0 @@ -# 遥感数据介绍 - -广义上,遥感是指遥远的感知,是指在不直接接触的情况下,对目标或自然现象远距离探测和感知的一种技术。一般我们所说的遥感为电磁波遥感,即在某平台上利用传感器探测电磁波反射或发射,并从中提取信息的过程。这个过程获取的图像数据一般即为卫星和航空影像。遥感数据可以被用于各种应用程序中,为空间分析等提供数据源,也可以在包括场景分类、图像分割与检测等CV领域进行判别或提取。 - -目前常用的遥感影像来自各种商业卫星影像提供商如Google等,以及来自NASA、ESA等的开放数据。可以从它们的官网中找到更多信息。 - -## 图像的工作原理 - -卫星和航空图像来自各种来源的栅格数据,经过接收方的部分处理后进行发布,如几何校正、辐射校正、大气校正或者色彩校正等,使其可以进行较准确的定量分析或具有更加逼真的视觉效果。 - -### 栅格数据 - -所有卫星和航空图像都以光栅格式存储。栅格是一种基于像素的数据格式,可以有效地表示连续表面。栅格中的信息存储在网格结构中,每个信息单元或像素具有相同的大小和形状,但值不同。数码照片、正射影像和卫星图像都以这种格式存储。 - -栅格格式非常适合用于查看空间和时间变化的分析,因为每个数据值都有一个基于网格的可访问位置。这使我们能够访问两个或多个不同栅格中的相同地理位置并比较它们的值。 - -### 卫星栅格 - -当地球观测卫星拍摄照片时,传感器会读取并记录从沿电磁光谱的波长收集的反射率值,并利用反射率计算各个栅格像元的DN值(Digital Number),即遥感影像像元的亮度值,记录的地物的灰度值。 - -而利用遥感图像的目的之一就是使用DN值可以反算地物的辐照率和反射率。它们之间的关系如下公式所示,其中$gain$和$bias$分别指传感器的增益和偏移;$L$是辐射率,也称为辐射亮度值;$\rho$是地物反射率;$d_{s}$、$E_{0}$和$\theta$分别表示日地天文单位距离、太阳辐照度以及太阳天顶角。 - -$$ -L = gain * DN + bias \\ -\rho = \pi Ld^{2}_{s}/(E_{0}\cos{\theta}) -$$ - -电磁波谱是人类根据电磁波的波长或频率、波数、能量等的大小顺序进行排列的成果。在电磁波谱中人眼只能感受到一个很小的波段范围,这个范围被称为可见光,波长范围在0.38-0.76μm。这是因为我们的视觉进化为在太阳发出最多光的地方最敏感,并且广泛地局限于构成我们所谓的红色、绿色和蓝色的波长。但卫星传感器可以感知范围更广的电磁频谱,这使得我们能够与借助传感器感知更多的频谱范围。 - -![band](../images/band.jpg) - -电磁波谱范围很广,传感器同时收集所有波长的信息是不切实际的。相反,不同的传感器优先考虑从不同波长的光谱收集信息。由传感器捕获和分类的频谱的每个部分都被归类为一个信息带。信息带的大小各不相同,可以编译成不同类型的合成图像,每个图像都强调不同的物理特性。同时,大多数遥感图像都为16位的图像,与传统的8位图像不同,它能表示更精细的光谱信息。 - -#### RGB - -RGB图像与我们常见的自然图像类似,也符合人类的视觉常识(如树是绿色的、水泥是灰色的等),三个通道分别表示红、绿和蓝。一般的RGB数据来自于无人机影像、各种电子地图下载器等,如下图所示。 - -![rgb](../images/rgb.jpg) - -由于当前大多数CV任务的流程都是基于自然图像进行设计的,因此RGB类型的遥感数据集依然是使用较多的。 - -#### MSI/HSI - -MSI(*Multispectral Image,多光谱图像*)和HSI(*Hyperspectral Image,高光谱图像*)均是一种波段数均大于3的遥感影像,其波段由几个到几百个不等,以不同的光谱分辨率(*光谱分辨率是指传感器所能记录的电磁波谱中,某一特定的波长范围值,波长范围值越宽,光谱分辨率越低*)进行区分。通常光谱分辨率在波长的1/10数量级范围内称为多光谱。其中多光谱影像的波段较少,谱带较宽,空间分辨率较高;而高光谱影像的波段较多,谱带较窄,光谱分辨率较高。 - -在使用中,MSI/HSI有一些常用波段具有不同的作用,例如中红外波段的透射率在60%-70%,包含地物反射及发射光谱,可以用来探测火灾等高温目标;红边波段(*绿色植物在0.67-0.76μm之间反射率增高最快的点,也是一阶导数光谱在该区间内的拐点*)是指示绿色植物生长状况的敏感性波段,可以有效地监测植被的生长状况,用于研究植物养分、健康状态监测、植被识别和生理生化参数等信息等。 - -下面以天宫一号高光谱成像仪拍摄的北京大兴机场为例,简单介绍一下波段组合和光谱曲线。天宫一号高光谱数据集根据波段信噪比和信息熵评价结果,剔除信噪比和信息熵较低的波段,结合图像实际目视结果,剔除了部分波段,共有可见近红外谱段54 个;短波红外谱段 52 个以及1个全色谱段数据。 - -##### 波段组合 - -波段组合是指在MSI/HSI中选择三个波段数据进行组合,代替RGB三个通道所得到的结果,称为彩色图(*RGB三波段的合成图称为真彩色图,任意非RGB波段的合成图称为假彩色图*)。不同彩色图的组合能够突出不同的地物特征,下图展示了不同的几种组合的效果。 - -![图片3](../images/band_combination.jpg) - -##### 光谱曲线解读 - -不同的光谱能够突出不同的地物特征,以植物的光谱曲线为例,如下图所示,植被在0.8μm波段,反射率大于40%,相比在0.6μm波段10%左右的反射率明显更大,因此在成像时反射回更多的辐射能量。所以成像时0.8μm波段的植被亮度大于0.6μm波段的植被亮度,也就是图上看起来就更明亮了。 - -![band_mean](../images/band_mean.jpg) - -了解MSI/HSI的波段后,可以根据资源使用不同数量和不同组合方式的使用MSI/HSI完成各类任务,也可以使用如PCA、小波变换等方法对MSI/HSI进行降维处理,以减少冗余,使用更少的计算资源完成任务。 - -#### SAR - -SAR(Synthetic Aperture Radar)是主动式侧视雷达系统,且成像几何属于斜距投影类型。因此SAR图像与光学图像在成像机理、几何特征、辐射特征等方面都有较大的区别。 - -与光学图像不同,光学图像不同波段的信息来自不不同波长的电磁波反射,以便于识别目标和分类提取;SAR图像则记录了不同极化(*即电磁波发射和接收的振动方向*)的回波信息,以二进制复数形式记录下来,并且基于每个像素的复数数据可变换提取相应的振幅和相位信息。相位信息人类无法直接分辨,但振幅信息可以,利用振幅信息可以得到强度图像如下图所示。 - -![sar](../images/sar.jpg) - -由于SAR图像的成像机理的不同,SAR影像分辨率相对较低、信噪比较低,所以SAR影像中所包含的振幅信息远达不到同光学影像的成像水平,因此在CV领域使用较少。而其的主要作用在于基于相位信息可以进行沉降检测反演、三维重建等,同时SAR卫星波长较长,具有一定的云层和地表穿透能力,有其独特的使用优势。 - -#### RGBD - -RGBD与RGB图像的区别在于多了一个D通道,即深度。深度图像类似于灰度图像,只是它的每个像素值是传感器距离物体的实际距离。通常RGB图像和深度图像是配准的,因而两幅图像对应于同一空间位置的点是一一对应的。如下图所示为部分无人机航摄的RGBD图像,其中可以看出建筑物与地面之间的相对高度。 - -![rgbd](../images/rgbd.jpg) - -深度图像提供了RGB图像所不具有的高度信息,能够在下游任务中对一些光谱特征相似的地物起到一定的区分作用。 diff --git a/docs/data/tools.md b/docs/data/tools.md index 8d4793f..f434c49 100644 --- a/docs/data/tools.md +++ b/docs/data/tools.md @@ -1,102 +1,85 @@ -# 工具箱 +# 遥感影像处理工具集 -工具箱位于`tools`文件夹下,目前有如下工具: +PaddleRS在`tools`目录中提供了丰富的遥感影像处理工具,包括: -- `coco2mask`:用于将geojson格式的分割标注标签转换为png格式。 -- `mask2shp`:用于对推理得到的png提取shapefile。 -- `mask2geojson`:用于对推理得到的png提取geojson。 -- `geojson2mask`:用于从geojson和原图中提取mask作为训练标签。 -- `matcher`:用于在推理前匹配两个时段的影响。 -- `spliter`:用于将大图数据进行分割以作为训练数据。 -- `coco_tools`:用于统计处理coco类标注文件。 +- `coco2mask.py`:用于将COCO格式的标注文件转换为png格式。 +- `mask2shape.py`:用于将模型推理输出的.png格式栅格标签转换为矢量格式。 +- `mask2geojson.py`:用于将模型推理输出的.png格式栅格标签转换为GeoJSON格式。 +- `match.py`:用于实现两幅影像的配准。 +- `split.py`:用于对大幅面影像数据进行切片。 +- `coco_tools/`:COCO工具合集,用于统计处理COCO格式标注文件。 -后期将根据DL和RS/GIS方面的前后处理需求增加更多的工具。 +## 使用示例 -## 如何使用 - -首先需要`clone`此repo并进入到`tools`的文件夹中: +首先请确保您已将PaddleRS下载到本地。进入`tools`目录: ```shell -git clone https://github.com/PaddlePaddle/PaddleRS.git -cd PaddleRS\tools +cd tools ``` ### coco2mask -`coco2mask`的主要功能是将图像以及对应json格式的分割标签转换为图像与png格式的标签,结果会分别存放在`img`和`gt`两个文件夹中。相关的数据样例可以参考[中国典型城市建筑物实例数据集](https://www.scidb.cn/detail?dataSetId=806674532768153600&dataSetType=journal)。保存结果为单通道的伪彩色图像。使用代码如下: +`coco2mask.py`的主要功能是将图像以及对应的COCO格式的分割标签转换为图像与.png格式的标签,结果会分别存放在`img`和`gt`两个目录中。相关的数据样例可以参考[中国典型城市建筑物实例数据集](https://www.scidb.cn/detail?dataSetId=806674532768153600&dataSetType=journal)。对于mask,保存结果为单通道的伪彩色图像。使用方式如下: ```shell -python coco2mask.py --raw_folder xxx --save_folder xxx +python coco2mask.py --raw_dir {输入目录路径} --save_dir {输出目录路径} ``` 其中: -- `raw_folder`:存放原始数据的文件夹,图像存放在`images`文件夹中,标签以`xxx.json`进行保存。 -- `save_folder`:保存结果文件的文件夹,其中图像保存在`img`中,png格式的标签保存在`gt`中。 +- `raw_dir`:存放原始数据的目录,其中图像存放在`images`子目录中,标签以`xxx.json`格式保存。 +- `save_dir`:保存输出结果的目录,其中图像保存在`img`子目录中,.png格式的标签保存在`gt`子目录中。 -### mask2shp +### mask2shape -`mask2shp`的主要功能是将推理得到的png格式的分割结果转换为shapefile格式,其中还可以设置不生成多边形的索引号。使用代码如下: +`mask2shape.py`的主要功能是将.png格式的分割结果转换为shapefile格式(矢量图)。使用方式如下: ```shell -python mask2shp.py --srcimg_path xxx.tif --mask_path xxx.png [--save_path output] [--ignore_index 255] +python mask2shape.py --srcimg_path {带有地理信息的原始影像路径} --mask_path {输入分割标签路径} [--save_path {输出矢量图路径}] [--ignore_index {需要忽略的索引值}] ``` 其中: -- `srcimg_path`:原始图像的路径,需要带有地理信息,以便为生成的shapefile提供crs等信息。 -- `mask_path`:推理得到的png格式的标签的路径。 +- `srcimg_path`:原始影像路径,需要带有地理坐标信息,以便为生成的shapefile提供crs等信息。 +- `mask_path`:模型推理得到的.png格式的分割结果。 - `save_path`:保存shapefile的路径,默认为`output`。 -- `ignore_index`:忽略生成shp的索引,如背景等,默认为255。 +- `ignore_index`:需要在shapefile中忽略的索引值(例如分割任务中的背景类),默认为255。 ### mask2geojson -`mask2geojson`的主要功能是将推理得到的png格式的分割结果转换为geojson格式。使用代码如下: - -```shell -python mask2geojson.py --mask_path xxx.tif --save_path xxx.json [--epsilon 0] -``` - -其中: - -- `mask_path`:推理得到的png格式的标签的路径。 -- `save_path`:保存geojson的路径。 -- `epsilon`:opencv的简化参数,默认为0。 - -### geojson2mask - -`geojson2mask`的主要功能是从原图和geojson文件中提取mask图像。使用代码如下: +`mask2geojson.py`的主要功能是将.png格式的分割结果转换为GeoJSON格式。使用方式如下: ```shell -python geojson2mask.py --image_path xxx.tif --geojson_path xxx.json +python mask2geojson.py --mask_path {输入分割标签路径} --save_path {输出路径} ``` 其中: -- `image_path`:原图像的路径。 -- `geojson_path`:geojson的路径。 +- `mask_path`:模型推理得到的.png格式的分割结果。 +- `save_path`:保存GeoJSON文件的路径。 -### matcher +### match -` matcher`的主要功能是在进行变化检测的推理前,匹配两期影像的位置,并将转换后的`im2`图像保存在原地址下,命名为`im2_M.tif`。使用代码如下: +`match.py`的主要功能是在对两个时相的遥感影像进行空间配准。使用方式如下: ```shell -python matcher.py --im1_path xxx.tif --im2_path xxx.xxx [--im1_bands 1 2 3] [--im2_bands 1 2 3] +python match.py --im1_path [时相1影像路径] --im2_path [时相2影像路径] --save_path [配准后时相2影像输出路径] [--im1_bands 1 2 3] [--im2_bands 1 2 3] ``` 其中: -- `im1_path`:时段一的图像路径,该图像需要存在地理信息,且以该图像为基准图像。 -- `im2_path`:时段二的图像路径,该图像可以为非遥感格式的图像,该图像为带匹配图像。 -- `im1_bands`:时段一图像所用于配准的波段,为RGB或单通道,默认为[1, 2, 3]。 -- `im2_bands`:时段二图像所用于配准的波段,为RGB或单通道,默认为[1, 2, 3]。 +- `im1_path`:时相1影像路径。该影像必须包含地理信息,且配准过程中以该影像为基准图像。 +- `im2_path`:时相2影像路径。该影像的地理信息将不被用到。配准过程中将该影像配准到时相1影像。 +- `im1_bands`:时相1影像用于配准的波段,指定为三通道(分别代表R、G、B)或单通道,默认为[1, 2, 3]。 +- `im2_bands`:时相2影像用于配准的波段,指定为三通道(分别代表R、G、B)或单通道,默认为[1, 2, 3]。 +- `save_path`: 配准后时相2影像输出路径。 -### spliter +### split -`spliter`的主要功能是在划分大的遥感图像为图像块,便于进行训练。使用代码如下: +`split.py`的主要功能是将大幅面遥感图像划分为图像块,这些图像块可以作为训练时的输入。使用方式如下: ```shell -python spliter.py --image_path xxx.tif [--mask_path None] [--block_size 512] [--save_folder output] +python split.py --image_path {输入影像路径} [--mask_path {真值标签路径}] [--block_size {图像块尺寸}] [--save_dir {输出目录}] ``` 其中: @@ -108,13 +91,13 @@ python spliter.py --image_path xxx.tif [--mask_path None] [--block_size 512] [-- ### coco_tools -目前coco_tools共有6个文件,各文件及其功能如下: +目前`coco_tools`目录中共包含6个工具,各工具功能如下: -* json_InfoShow: 打印json文件中各个字典的基本信息; -* json_ImgSta: 统计json文件中的图像信息,生成统计表、统计图; -* json_AnnoSta: 统计json文件中的标注信息,生成统计表、统计图; -* json_Img2Json: 统计test集图像,生成json文件; -* json_Split: json文件拆分,划分为train set、val set -* json_Merge: json文件合并,将多个json合并为1个json +- `json_InfoShow.py`: 打印json文件中各个字典的基本信息; +- `json_ImgSta.py`: 统计json文件中的图像信息,生成统计表、统计图; +- `json_AnnoSta.py`: 统计json文件中的标注信息,生成统计表、统计图; +- `json_Img2Json.py`: 统计test集图像,生成json文件; +- `json_Split.py`: 将json文件中的内容划分为train set和val set; +- `json_Merge.py`: 将多个json文件合并为一个。 -详细使用方法与参数见[coco_tools说明](coco_tools_cn.md) +详细使用方法请参见[coco_tools使用说明](coco_tools.md)。 diff --git a/docs/datasets.md b/docs/datasets.md deleted file mode 100644 index a332350..0000000 --- a/docs/datasets.md +++ /dev/null @@ -1,41 +0,0 @@ -# 遥感数据集 - -遥感影像的格式多种多样,不同传感器产生的数据格式也可能不同。PaddleRS至少兼容以下6种格式图片读取: - -- `tif` -- `png`, `jpeg`, `bmp` -- `img` -- `npy` - -标注图要求必须为单通道的png格式图像,像素值即为对应的类别,像素标注类别需要从0开始递增。例如0,1,2,3表示有4种类别,255用于指定不参与训练和评估的像素,标注类别最多为256类。 - -## L8 SPARCS数据集 -[L8 SPARCS公开数据集](https://www.usgs.gov/land-resources/nli/landsat/spatial-procedures-automated-removal-cloud-and-shadow-sparcs-validation)进行云雪分割,该数据集包含80张卫星影像,涵盖10个波段。原始标注图片包含7个类别,分别是`cloud`, `cloud shadow`, `shadow over water`, `snow/ice`, `water`, `land`和`flooded`。由于`flooded`和`shadow over water`2个类别占比仅为`1.8%`和`0.24%`,我们将其进行合并,`flooded`归为`land`,`shadow over water`归为`shadow`,合并后标注包含5个类别。 - -数值、类别、颜色对应表: - -|Pixel value|Class|Color| -|---|---|---| -|0|cloud|white| -|1|shadow|black| -|2|snow/ice|cyan| -|3|water|blue| -|4|land|grey| - -

    - - - -

    - L8 SPARCS数据集示例 -

    - -执行以下命令下载并解压经过类别合并后的数据集: -```shell script -mkdir dataset && cd dataset -wget https://paddleseg.bj.bcebos.com/dataset/remote_sensing_seg.zip -unzip remote_sensing_seg.zip -cd .. -``` -其中`data`目录存放遥感影像,`data_vis`目录存放彩色合成预览图,`mask`目录存放标注图。 diff --git a/docs/images/whole_image.jpg b/docs/images/whole_image.jpg deleted file mode 100644 index fd56e93..0000000 Binary files a/docs/images/whole_image.jpg and /dev/null differ diff --git a/docs/images/whole_picture.png b/docs/images/whole_picture.png new file mode 100644 index 0000000..780fce0 Binary files /dev/null and b/docs/images/whole_picture.png differ diff --git a/docs/intro/model_zoo.md b/docs/intro/model_zoo.md new file mode 100644 index 0000000..0fbafc7 --- /dev/null +++ b/docs/intro/model_zoo.md @@ -0,0 +1,36 @@ +# 模型库 + +PaddleRS的基础模型库来自Paddle-CV系列套件:[PaddleClas](https://github.com/PaddlePaddle/PaddleClas/blob/release/2.3/docs/zh_CN/algorithm_introduction/ImageNet_models.md)、[PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.4/docs/model_zoo_overview_cn.md)、[PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.3/README_cn.md#模型库)以及[PaddleGAN](https://github.com/PaddlePaddle/PaddleGAN/blob/develop/README_cn.md#模型库)。除此之外,PaddleRS也包含一系列遥感特色模型,可用于遥感影像分割、变化检测等。 + +## PaddleRS已支持的模型列表 + +PaddleRS目前已支持的全部模型如下(标注\*的为遥感专用模型): + +| 任务 | 模型 | 多波段支持 | +|--------|---------|------| +| 变化检测 | \*BIT | 是 | +| 变化检测 | \*CDNet | 是 | +| 变化检测 | \*DSAMNet | 是 | +| 变化检测 | \*DSIFN | 否 | +| 变化检测 | \*SNUNet | 是 | +| 变化检测 | \*STANet | 是 | +| 变化检测 | \*FC-EF | 是 | +| 变化检测 | \*FC-Siam-conc | 是 | +| 变化检测 | \*FC-Siam-diff | 是 | +| 变化检测 | \*ChangeStar | 否 | +| 变化检测 | \*ChangeFormer | 是 | +| 场景分类 | HRNet | 是 | +| 场景分类 | MobileNetV3 | 是 | +| 场景分类 | ResNet50-vd | 是 | +| 场景分类 | CondenseNetV2 | 是 | +| 图像复原 | DRN | 否 | +| 图像复原 | ESRGAN | 否 | +| 图像复原 | LESRCNN | 否 | +| 目标检测 | Faster R-CNN | 是 | +| 目标检测 | PP-YOLO | 是 | +| 目标检测 | PP-YOLO Tiny | 是 | +| 目标检测 | PP-YOLOv2 | 是 | +| 目标检测 | YOLOv3 | 是 | +| 图像分割 | DeepLab V3+ | 是 | +| 图像分割 | UNet | 是 | +| 图像分割 | \*FarSeg | 否 | diff --git a/docs/intro/transforms.md b/docs/intro/transforms.md new file mode 100644 index 0000000..6144704 --- /dev/null +++ b/docs/intro/transforms.md @@ -0,0 +1,33 @@ +# 数据预处理/数据增强 + +## PaddleRS已支持的数据变换算子列表 + +PaddleRS对不同遥感任务需要的数据预处理/数据增强(合称为数据变换)策略进行了有机整合,设计统一的算子。考虑到遥感影像的多波段特性,PaddleRS的大部分数据处理算子均能够处理任意数量波段的输入。PaddleRS目前提供的所有数据变换算子如下表: + +| 数据变换算子名 | 用途 | 任务 | ... | +| -------------------- | ------------------------------------------------- | -------- | ---- | +| Resize | 调整输入影像大小。 | 所有任务 | ... | +| RandomResize | 随机调整输入影像大小。 | 所有任务 | ... | +| ResizeByShort | 调整输入影像大小,保持纵横比不变(根据短边计算缩放系数)。 | 所有任务 | ... | +| RandomResizeByShort | 随机调整输入影像大小,保持纵横比不变(根据短边计算缩放系数)。 | 所有任务 | ... | +| ResizeByLong | 调整输入影像大小,保持纵横比不变(根据长边计算缩放系数)。 | 所有任务 | ... | +| RandomHorizontalFlip | 随机水平翻转输入影像。 | 所有任务 | ... | +| RandomVerticalFlip | 随机竖直翻转输入影像。 | 所有任务 | ... | +| Normalize | 对输入影像应用标准化。 | 所有任务 | ... | +| CenterCrop | 对输入影像进行中心裁剪。 | 所有任务 | ... | +| RandomCrop | 对输入影像进行随机中心裁剪。 | 所有任务 | ... | +| RandomScaleAspect | 裁剪输入影像并重新缩放到原始尺寸。 | 所有任务 | ... | +| RandomExpand | 根据随机偏移扩展输入影像。 | 所有任务 | ... | +| Pad | 将输入影像填充到指定的大小。 | 所有任务 | ... | +| MixupImage | 将两幅影像(及对应的目标检测标注)混合在一起作为新的样本。 | 目标检测 | ... | +| RandomDistort | 对输入施加随机色彩变换。 | 所有任务 | ... | +| RandomBlur | 对输入施加随机模糊。 | 所有任务 | ... | +| Dehaze | 对输入图像进行去雾。 | 所有任务 | ... | +| ReduceDim | 对输入图像进行波段降维。 | 所有任务 | ... | +| SelectBand | 对输入影像进行波段选择。 | 所有任务 | ... | +| RandomSwap | 随机交换两个时相的输入影像。 | 变化检测 | ... | +| ... | ... | ... | ... | + +## 组合算子 + +在实际的模型训练过程中,常常需要组合多种数据预处理与数据增强策略。PaddleRS提供了`paddlers.transforms.Compose`以便捷地组合多个数据变换算子,使这些算子能够串行执行。关于`paddlers.transforms.Compose`的具体用法请参见[API说明](https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md)。 diff --git a/docs/quick_start.md b/docs/quick_start.md deleted file mode 100644 index 3be27ba..0000000 --- a/docs/quick_start.md +++ /dev/null @@ -1,42 +0,0 @@ - -## 环境准备 - -- [PaddlePaddle安装](https://www.paddlepaddle.org.cn/install/quick) -* 版本要求:PaddlePaddle>=2.1.0 - -- PaddleRS安装 - - -PaddleRS代码会跟随开发进度不断更新,可以安装develop分支的代码使用最新的功能,安装方式如下: - -``` -git clone https://github.com/PaddlePaddle/PaddleRS -cd PaddleRS -git checkout develop -pip install -r requirements.txt -python setup.py install -``` - -## 开始训练 -* 在安装PaddleRS后,使用如下命令开始训练,代码会自动下载训练数据, 并均使用单张GPU卡进行训练。 - -```commandline -export CUDA_VISIBLE_DEVICES=0 -python tutorials/train/semantic_segmentation/deeplabv3p_resnet50_multi_channel.py -``` - -* 若需使用多张GPU卡进行训练,例如使用2张卡时执行: - -```commandline -python -m paddle.distributed.launch --gpus 0,1 tutorials/train/semantic_segmentation/deeplabv3p_resnet50_multi_channel.py -``` -使用多卡时,参考[训练参数调整](../../docs/parameters.md)调整学习率和批量大小。 - - -## VisualDL可视化训练指标 -在模型训练过程,在`train`函数中,将`use_vdl`设为True,则训练过程会自动将训练日志以VisualDL的格式打点在`save_dir`(用户自己指定的路径)下的`vdl_log`目录,用户可以使用如下命令启动VisualDL服务,查看可视化指标 -```commandline -visualdl --logdir output/deeplabv3p_resnet50_multi_channel/vdl_log --port 8001 -``` - -服务启动后,使用浏览器打开 https://0.0.0.0:8001 或 https://localhost:8001 diff --git a/paddlers/datasets/cd_dataset.py b/paddlers/datasets/cd_dataset.py index 655f5c4..2a2d85a 100644 --- a/paddlers/datasets/cd_dataset.py +++ b/paddlers/datasets/cd_dataset.py @@ -32,7 +32,7 @@ class CDDataset(BaseDataset): bi-temporal images, the path of the change mask, and the paths of the segmentation masks in both temporal phases. transforms (paddlers.transforms.Compose): Data preprocessing and data augmentation operators to apply. - label_list (str, optional): Path of the file that contains the category names. Defaults to None. + label_list (str|None, optional): Path of the file that contains the category names. Defaults to None. num_workers (int|str, optional): Number of processes used for data loading. If `num_workers` is 'auto', the number of workers will be automatically determined according to the number of CPU cores: If there are more than 16 cores,8 workers will be used. Otherwise, the number of workers will be half diff --git a/paddlers/datasets/clas_dataset.py b/paddlers/datasets/clas_dataset.py index cb5ec60..c0c15ad 100644 --- a/paddlers/datasets/clas_dataset.py +++ b/paddlers/datasets/clas_dataset.py @@ -26,7 +26,7 @@ class ClasDataset(BaseDataset): data_dir (str): Root directory of the dataset. file_list (str): Path of the file that contains relative paths of images and labels. transforms (paddlers.transforms.Compose): Data preprocessing and data augmentation operators to apply. - label_list (str, optional): Path of the file that contains the category names. Defaults to None. + label_list (str|None, optional): Path of the file that contains the category names. Defaults to None. num_workers (int|str, optional): Number of processes used for data loading. If `num_workers` is 'auto', the number of workers will be automatically determined according to the number of CPU cores: If there are more than 16 cores,8 workers will be used. Otherwise, the number of workers will be half diff --git a/paddlers/datasets/coco.py b/paddlers/datasets/coco.py index f80ae13..1f97a53 100644 --- a/paddlers/datasets/coco.py +++ b/paddlers/datasets/coco.py @@ -36,7 +36,7 @@ class COCODetDataset(BaseDataset): image_dir (str): Directory that contains the images. ann_path (str): Path to COCO annotations. transforms (paddlers.transforms.Compose): Data preprocessing and data augmentation operators to apply. - label_list (str, optional): Path of the file that contains the category names. Defaults to None. + label_list (str|None, optional): Path of the file that contains the category names. Defaults to None. num_workers (int|str, optional): Number of processes used for data loading. If `num_workers` is 'auto', the number of workers will be automatically determined according to the number of CPU cores: If there are more than 16 cores,8 workers will be used. Otherwise, the number of workers will be half diff --git a/paddlers/datasets/seg_dataset.py b/paddlers/datasets/seg_dataset.py index 58ff2c6..0bfab96 100644 --- a/paddlers/datasets/seg_dataset.py +++ b/paddlers/datasets/seg_dataset.py @@ -27,7 +27,7 @@ class SegDataset(BaseDataset): data_dir (str): Root directory of the dataset. file_list (str): Path of the file that contains relative paths of images and annotation files. transforms (paddlers.transforms.Compose): Data preprocessing and data augmentation operators to apply. - label_list (str, optional): Path of the file that contains the category names. Defaults to None. + label_list (str|None, optional): Path of the file that contains the category names. Defaults to None. num_workers (int|str, optional): Number of processes used for data loading. If `num_workers` is 'auto', the number of workers will be automatically determined according to the number of CPU cores: If there are more than 16 cores,8 workers will be used. Otherwise, the number of workers will be half diff --git a/paddlers/datasets/voc.py b/paddlers/datasets/voc.py index d12defd..aad0b5c 100644 --- a/paddlers/datasets/voc.py +++ b/paddlers/datasets/voc.py @@ -37,7 +37,7 @@ class VOCDetDataset(BaseDataset): data_dir (str): Root directory of the dataset. file_list (str): Path of the file that contains relative paths of images and annotation files. transforms (paddlers.transforms.Compose): Data preprocessing and data augmentation operators to apply. - label_list (str, optional): Path of the file that contains the category names. Defaults to None. + label_list (str|None, optional): Path of the file that contains the category names. Defaults to None. num_workers (int|str, optional): Number of processes used for data loading. If `num_workers` is 'auto', the number of workers will be automatically determined according to the number of CPU cores: If there are more than 16 cores,8 workers will be used. Otherwise, the number of workers will be half diff --git a/paddlers/deploy/predictor.py b/paddlers/deploy/predictor.py index af780d0..7579120 100644 --- a/paddlers/deploy/predictor.py +++ b/paddlers/deploy/predictor.py @@ -260,8 +260,8 @@ class Predictor(object): Args: img_file(list[str|tuple|np.ndarray] | str | tuple | np.ndarray): For scene classification, image restoration, - object detection and semantic segmentation tasks, `img_file` should be either the path of the image to predict - , a decoded image (a np.ndarray, which should be consistent with what you get from passing image path to + object detection and semantic segmentation tasks, `img_file` should be either the path of the image to predict, + a decoded image (a np.ndarray, which should be consistent with what you get from passing image path to paddlers.transforms.decode_image()), or a list of image paths or decoded images. For change detection tasks, img_file should be a tuple of image paths, a tuple of decoded images, or a list of tuples. topk(int, optional): Top-k values to reserve in a classification result. Defaults to 1. diff --git a/paddlers/tasks/classifier.py b/paddlers/tasks/classifier.py index aaa8710..79a5099 100644 --- a/paddlers/tasks/classifier.py +++ b/paddlers/tasks/classifier.py @@ -208,7 +208,7 @@ class BaseClassifier(BaseModel): train_dataset (paddlers.datasets.ClasDataset): Training dataset. train_batch_size (int, optional): Total batch size among all cards used in training. Defaults to 2. - eval_dataset (paddlers.datasets.ClasDataset, optional): Evaluation dataset. + eval_dataset (paddlers.datasets.ClasDataset|None, optional): Evaluation dataset. If None, the model will not be evaluated during training process. Defaults to None. optimizer (paddle.optimizer.Optimizer|None, optional): Optimizer used in @@ -318,7 +318,7 @@ class BaseClassifier(BaseModel): train_dataset (paddlers.datasets.ClasDataset): Training dataset. train_batch_size (int, optional): Total batch size among all cards used in training. Defaults to 2. - eval_dataset (paddlers.datasets.ClasDataset, optional): Evaluation dataset. + eval_dataset (paddlers.datasets.ClasDataset|None, optional): Evaluation dataset. If None, the model will not be evaluated during training process. Defaults to None. optimizer (paddle.optimizer.Optimizer|None, optional): Optimizer used in @@ -437,7 +437,9 @@ class BaseClassifier(BaseModel): Returns: If `img_file` is a string or np.array, the result is a dict with key-value pairs: - {"label map": `class_ids_map`, "scores_map": `label_names_map`}. + {"label map": `class_ids_map`, + "scores_map": `scores_map`, + "label_names_map": `label_names_map`}. If `img_file` is a list, the result is a list composed of dicts with the corresponding fields: class_ids_map (np.ndarray): class_ids diff --git a/paddlers/tasks/object_detector.py b/paddlers/tasks/object_detector.py index ed3cfff..8a0acaa 100644 --- a/paddlers/tasks/object_detector.py +++ b/paddlers/tasks/object_detector.py @@ -211,7 +211,7 @@ class BaseDetector(BaseModel): Training dataset. train_batch_size (int, optional): Total batch size among all cards used in training. Defaults to 64. - eval_dataset (paddlers.datasets.COCODetDataset|paddlers.datasets.VOCDetDataset, optional): + eval_dataset (paddlers.datasets.COCODetDataset|paddlers.datasets.VOCDetDataset|None, optional): Evaluation dataset. If None, the model will not be evaluated during training process. Defaults to None. optimizer (paddle.optimizer.Optimizer|None, optional): Optimizer used for @@ -405,7 +405,7 @@ class BaseDetector(BaseModel): Training dataset. train_batch_size (int, optional): Total batch size among all cards used in training. Defaults to 64. - eval_dataset (paddlers.datasets.COCODetDataset|paddlers.datasets.VOCDetDataset, optional): + eval_dataset (paddlers.datasets.COCODetDataset|paddlers.datasets.VOCDetDataset|None, optional): Evaluation dataset. If None, the model will not be evaluated during training process. Defaults to None. optimizer (paddle.optimizer.Optimizer or None, optional): Optimizer used for @@ -486,7 +486,7 @@ class BaseDetector(BaseModel): Returns: collections.OrderedDict with key-value pairs: - {"mAP(0.50, 11point)":`mean average precision`}. + {"bbox_mmap":`mean average precision (0.50, 11point)`}. """ if metric is None: @@ -585,9 +585,13 @@ class BaseDetector(BaseModel): Returns: If `img_file` is a string or np.array, the result is a list of dict with key-value pairs: - {"category_id": `category_id`, "category": `category`, "bbox": `[x, y, w, h]`, "score": `score`}. - If `img_file` is a list, the result is a list composed of dicts with the - corresponding fields: + {"category_id": `category_id`, + "category": `category`, + "bbox": `[x, y, w, h]`, + "score": `score`, + "mask": `mask`}. + If `img_file` is a list, the result is a list composed of list of dicts + with the corresponding fields: category_id(int): the predicted category ID. 0 represents the first category in the dataset, and so on. category(str): category name diff --git a/paddlers/tasks/segmenter.py b/paddlers/tasks/segmenter.py index 48bc99f..dea068a 100644 --- a/paddlers/tasks/segmenter.py +++ b/paddlers/tasks/segmenter.py @@ -242,7 +242,7 @@ class BaseSegmenter(BaseModel): pretrain_weights (str|None, optional): None or name/path of pretrained weights. If None, no pretrained weights will be loaded. Defaults to 'CITYSCAPES'. - learning_rate (float, optional): Learning rate for training. Defaults to .025. + learning_rate (float, optional): Learning rate for training. Defaults to .01. lr_decay_power (float, optional): Learning decay power. Defaults to .9. early_stop (bool, optional): Whether to adopt early stop strategy. Defaults to False. diff --git a/paddlers/transforms/__init__.py b/paddlers/transforms/__init__.py index 03b253e..aafc4dd 100644 --- a/paddlers/transforms/__init__.py +++ b/paddlers/transforms/__init__.py @@ -24,11 +24,13 @@ def decode_image(im_path, to_rgb=True, to_uint8=True, decode_bgr=True, - decode_sar=True): + decode_sar=True, + read_geo_info=False): """ Decode an image. Args: + im_path (str): Path of the image to decode. to_rgb (bool, optional): If True, convert input image(s) from BGR format to RGB format. Defaults to True. to_uint8 (bool, optional): If True, quantize and convert decoded image(s) to @@ -38,9 +40,14 @@ def decode_image(im_path, decode_sar (bool, optional): If True, automatically interpret a two-channel geo image (e.g. geotiff images) as a SAR image, set this argument to True. Defaults to True. + read_geo_info (bool, optional): If True, read geographical information from + the image. Deafults to False. Returns: - np.ndarray: Decoded image. + np.ndarray|tuple: If `read_geo_info` is False, return the decoded image. + Otherwise, return a tuple that contains the decoded image and a dictionary + of geographical information (e.g. geographical transform and geographical + projection). """ # Do a presence check. osp.exists() assumes `im_path` is a path-like object. @@ -50,11 +57,15 @@ def decode_image(im_path, to_rgb=to_rgb, to_uint8=to_uint8, decode_bgr=decode_bgr, - decode_sar=decode_sar) + decode_sar=decode_sar, + read_geo_info=read_geo_info) # Deepcopy to avoid inplace modification sample = {'image': copy.deepcopy(im_path)} sample = decoder(sample) - return sample['image'] + if read_geo_info: + return sample['image'], sample['geo_info_dict'] + else: + return sample['image'] def build_transforms(transforms_info): diff --git a/paddlers/transforms/operators.py b/paddlers/transforms/operators.py index fa8c4af..ec9b424 100644 --- a/paddlers/transforms/operators.py +++ b/paddlers/transforms/operators.py @@ -180,22 +180,28 @@ class DecodeImg(Transform): decode_sar (bool, optional): If True, automatically interpret a two-channel geo image (e.g. geotiff images) as a SAR image, set this argument to True. Defaults to True. + read_geo_info (bool, optional): If True, read geographical information from + the image. Deafults to False. """ def __init__(self, to_rgb=True, to_uint8=True, decode_bgr=True, - decode_sar=True): + decode_sar=True, + read_geo_info=False): super(DecodeImg, self).__init__() self.to_rgb = to_rgb self.to_uint8 = to_uint8 self.decode_bgr = decode_bgr self.decode_sar = decode_sar + self.read_geo_info = False def read_img(self, img_path): img_format = imghdr.what(img_path) name, ext = os.path.splitext(img_path) + geo_trans, geo_proj = None, None + if img_format == 'tiff' or ext == '.img': try: import gdal @@ -209,7 +215,7 @@ class DecodeImg(Transform): dataset = gdal.Open(img_path) if dataset == None: - raise IOError('Can not open', img_path) + raise IOError('Cannot open', img_path) im_data = dataset.ReadAsArray() if im_data.ndim == 2 and self.decode_sar: im_data = to_intensity(im_data) @@ -217,26 +223,38 @@ class DecodeImg(Transform): else: if im_data.ndim == 3: im_data = im_data.transpose((1, 2, 0)) - return im_data + if self.read_geo_info: + geo_trans = dataset.GetGeoTransform() + geo_proj = dataset.GetGeoProjection() elif img_format in ['jpeg', 'bmp', 'png', 'jpg']: if self.decode_bgr: - return cv2.imread(img_path, cv2.IMREAD_ANYDEPTH | - cv2.IMREAD_ANYCOLOR | cv2.IMREAD_COLOR) + im_data = cv2.imread(img_path, cv2.IMREAD_ANYDEPTH | + cv2.IMREAD_ANYCOLOR | cv2.IMREAD_COLOR) else: - return cv2.imread(img_path, cv2.IMREAD_ANYDEPTH | - cv2.IMREAD_ANYCOLOR) + im_data = cv2.imread(img_path, cv2.IMREAD_ANYDEPTH | + cv2.IMREAD_ANYCOLOR) elif ext == '.npy': - return np.load(img_path) + im_data = np.load(img_path) else: raise TypeError("Image format {} is not supported!".format(ext)) + if self.read_geo_info: + return im_data, geo_trans, geo_proj + else: + return im_data + def apply_im(self, im_path): if isinstance(im_path, str): try: - image = self.read_img(im_path) + data = self.read_img(im_path) except: raise ValueError("Cannot read the image file {}!".format( im_path)) + if self.read_geo_info: + image, geo_trans, geo_proj = data + geo_info_dict = {'geo_trans': geo_trans, 'geo_proj': geo_proj} + else: + image = data else: image = im_path @@ -246,7 +264,10 @@ class DecodeImg(Transform): if self.to_uint8: image = to_uint8(image) - return image + if self.read_geo_info: + return image, geo_info_dict + else: + return image def apply_mask(self, mask): try: @@ -269,15 +290,37 @@ class DecodeImg(Transform): """ if 'image' in sample: - sample['image_ori'] = copy.deepcopy(sample['image']) - sample['image'] = self.apply_im(sample['image']) + if self.read_geo_info: + image, geo_info_dict = self.apply_im(sample['image']) + sample['image'] = image + sample['geo_info_dict'] = geo_info_dict + else: + sample['image'] = self.apply_im(sample['image']) + if 'image2' in sample: - sample['image2'] = self.apply_im(sample['image2']) + if self.read_geo_info: + image2, geo_info_dict2 = self.apply_im(sample['image2']) + sample['image2'] = image2 + sample['geo_info_dict2'] = geo_info_dict2 + else: + sample['image2'] = self.apply_im(sample['image2']) + if 'image_t1' in sample and not 'image' in sample: if not ('image_t2' in sample and 'image2' not in sample): raise ValueError - sample['image'] = self.apply_im(sample['image_t1']) - sample['image2'] = self.apply_im(sample['image_t2']) + if self.read_geo_info: + image, geo_info_dict = self.apply_im(sample['image_t1']) + sample['image'] = image + sample['geo_info_dict'] = geo_info_dict + else: + sample['image'] = self.apply_im(sample['image_t1']) + if self.read_geo_info: + image2, geo_info_dict2 = self.apply_im(sample['image_t2']) + sample['image2'] = image2 + sample['geo_info_dict2'] = geo_info_dict2 + else: + sample['image2'] = self.apply_im(sample['image_t2']) + if 'mask' in sample: sample['mask_ori'] = copy.deepcopy(sample['mask']) sample['mask'] = self.apply_mask(sample['mask']) @@ -286,6 +329,7 @@ class DecodeImg(Transform): if im_height != se_height or im_width != se_width: raise ValueError( "The height or width of the image is not same as the mask.") + if 'aux_masks' in sample: sample['aux_masks_ori'] = copy.deepcopy(sample['aux_masks']) sample['aux_masks'] = list( @@ -295,6 +339,7 @@ class DecodeImg(Transform): sample['im_shape'] = np.array( sample['image'].shape[:2], dtype=np.float32) sample['scale_factor'] = np.array([1., 1.], dtype=np.float32) + return sample diff --git a/test_tipc/README.md b/test_tipc/README.md index c14e61d..8f72eb8 100644 --- a/test_tipc/README.md +++ b/test_tipc/README.md @@ -1,6 +1,6 @@ # 飞桨训推一体全流程(TIPC) -## 1. 简介 +## 1 简介 飞桨除了基本的模型训练和预测,还提供了支持多端多平台的高性能推理部署工具。本文档提供了飞桨训推一体全流程(Training and Inference Pipeline Criterion(TIPC))信息和测试工具,方便用户查阅每种模型的训练推理部署打通情况,并可以进行一键测试。 @@ -8,7 +8,7 @@ -## 2. 汇总信息 +## 2 汇总信息 打通情况汇总如下,已填写的部分表示可以使用本工具进行一键测试,未填写的表示正在支持中。 @@ -28,7 +28,7 @@ | 图像分割 | UNet | 支持 | - | - | - | -## 3. 测试工具简介 +## 3 测试工具简介 ### 3.1 目录介绍 @@ -50,7 +50,7 @@ test_tipc 使用本工具,可以测试不同功能的支持情况。测试过程包含: -1. 准备数据与环境 +1. 准备数据与环境; 2. 运行测试脚本,观察不同配置是否运行成功。 diff --git a/test_tipc/docs/test_train_inference_python.md b/test_tipc/docs/test_train_inference_python.md index 37726c3..5100f81 100644 --- a/test_tipc/docs/test_train_inference_python.md +++ b/test_tipc/docs/test_train_inference_python.md @@ -2,7 +2,7 @@ Linux GPU/CPU 基础训练推理测试的主程序为`test_train_inference_python.sh`,可以测试基于Python的模型训练、评估、推理等基本功能。 -## 1. 测试结论汇总 +## 1 测试结论汇总 - 训练相关: @@ -23,7 +23,7 @@ Linux GPU/CPU 基础训练推理测试的主程序为`test_train_inference_pytho | 图像分割 | UNet | 支持 | 支持 | 1 | -## 2. 测试流程 +## 2 测试流程 ### 2.1 环境配置 diff --git a/tools/raster2geotiff.py b/tools/mask2geojson.py similarity index 88% rename from tools/raster2geotiff.py rename to tools/mask2geojson.py index 25646b6..0b213d4 100644 --- a/tools/raster2geotiff.py +++ b/tools/mask2geojson.py @@ -61,11 +61,11 @@ def convert_data(image_path, geojson_path): parser = argparse.ArgumentParser() -parser.add_argument("--raster_path", type=str, required=True, \ - help="Path of original raster image.") -parser.add_argument("--geotiff_path", type=str, required=True, \ - help="Path to store the geotiff file (the coordinate system is WGS84).") +parser.add_argument("--mask_path", type=str, required=True, \ + help="Path of mask data.") +parser.add_argument("--save_path", type=str, required=True, \ + help="Path to store the GeoJSON file (the coordinate system is WGS84).") if __name__ == "__main__": args = parser.parse_args() - convert_data(args.raster_path, args.geotiff_path) + convert_data(args.raster_path, args.geojson_path) diff --git a/tools/raster2vector.py b/tools/mask2shape.py similarity index 93% rename from tools/raster2vector.py rename to tools/mask2shape.py index a76ea92..4f108ba 100644 --- a/tools/raster2vector.py +++ b/tools/mask2shape.py @@ -1,105 +1,105 @@ -# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import os.path as osp -import argparse - -import numpy as np -from PIL import Image -try: - from osgeo import gdal, ogr, osr -except ImportError: - import gdal - import ogr - import osr - -from utils import Raster, save_geotiff, time_it - - -def _mask2tif(mask_path, tmp_path, proj, geot): - dst_ds = save_geotiff( - np.asarray(Image.open(mask_path)), tmp_path, proj, geot, - gdal.GDT_UInt16, False) - return dst_ds - - -def _polygonize_raster(mask_path, vec_save_path, proj, geot, ignore_index, ext): - if proj is None or geot is None: - tmp_path = None - ds = gdal.Open(mask_path) - else: - tmp_path = vec_save_path.replace("." + ext, ".tif") - ds = _mask2tif(mask_path, tmp_path, proj, geot) - srcband = ds.GetRasterBand(1) - maskband = srcband.GetMaskBand() - gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES") - gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8") - ogr.RegisterAll() - drv = ogr.GetDriverByName("ESRI Shapefile" if ext == "shp" else "GeoJSON") - if osp.exists(vec_save_path): - os.remove(vec_save_path) - dst_ds = drv.CreateDataSource(vec_save_path) - prosrs = osr.SpatialReference(wkt=ds.GetProjection()) - dst_layer = dst_ds.CreateLayer( - "POLYGON", geom_type=ogr.wkbPolygon, srs=prosrs) - dst_fieldname = "CLAS" - fd = ogr.FieldDefn(dst_fieldname, ogr.OFTInteger) - dst_layer.CreateField(fd) - gdal.Polygonize(srcband, maskband, dst_layer, 0, []) - # TODO: temporary: delete ignored values - dst_ds.Destroy() - ds = None - vec_ds = drv.Open(vec_save_path, 1) - lyr = vec_ds.GetLayer() - lyr.SetAttributeFilter("{} = '{}'".format(dst_fieldname, str(ignore_index))) - for holes in lyr: - lyr.DeleteFeature(holes.GetFID()) - vec_ds.Destroy() - if tmp_path is not None: - os.remove(tmp_path) - - -@time_it -def raster2vector(srcimg_path, mask_path, save_path, ignore_index=255): - vec_ext = save_path.split(".")[-1].lower() - if vec_ext not in ["json", "geojson", "shp"]: - raise ValueError( - "The extension of `save_path` must be 'json/geojson' or 'shp', not {}.". - format(vec_ext)) - ras_ext = srcimg_path.split(".")[-1].lower() - if osp.exists(srcimg_path) and ras_ext in ["tif", "tiff", "geotiff", "img"]: - src = Raster(srcimg_path) - _polygonize_raster(mask_path, save_path, src.proj, src.geot, - ignore_index, vec_ext) - src = None - else: - _polygonize_raster(mask_path, save_path, None, None, ignore_index, - vec_ext) - - -parser = argparse.ArgumentParser() -parser.add_argument("--mask_path", type=str, required=True, \ - help="Path of mask data.") -parser.add_argument("--save_path", type=str, required=True, \ - help="Path to save the shape file (the extension is .json/geojson or .shp).") -parser.add_argument("--srcimg_path", type=str, default="", \ - help="Path of original data with geoinfo. Default to empty.") -parser.add_argument("--ignore_index", type=int, default=255, \ - help="The ignored index will not be converted to a value in the shape file. Default value is 255.") - -if __name__ == "__main__": - args = parser.parse_args() - raster2vector(args.srcimg_path, args.mask_path, args.save_path, - args.ignore_index) +# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import os.path as osp +import argparse + +import numpy as np +from PIL import Image +try: + from osgeo import gdal, ogr, osr +except ImportError: + import gdal + import ogr + import osr + +from utils import Raster, save_geotiff, time_it + + +def _mask2tif(mask_path, tmp_path, proj, geot): + dst_ds = save_geotiff( + np.asarray(Image.open(mask_path)), tmp_path, proj, geot, + gdal.GDT_UInt16, False) + return dst_ds + + +def _polygonize_raster(mask_path, vec_save_path, proj, geot, ignore_index, ext): + if proj is None or geot is None: + tmp_path = None + ds = gdal.Open(mask_path) + else: + tmp_path = vec_save_path.replace("." + ext, ".tif") + ds = _mask2tif(mask_path, tmp_path, proj, geot) + srcband = ds.GetRasterBand(1) + maskband = srcband.GetMaskBand() + gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES") + gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8") + ogr.RegisterAll() + drv = ogr.GetDriverByName("ESRI Shapefile" if ext == "shp" else "GeoJSON") + if osp.exists(vec_save_path): + os.remove(vec_save_path) + dst_ds = drv.CreateDataSource(vec_save_path) + prosrs = osr.SpatialReference(wkt=ds.GetProjection()) + dst_layer = dst_ds.CreateLayer( + "POLYGON", geom_type=ogr.wkbPolygon, srs=prosrs) + dst_fieldname = "CLAS" + fd = ogr.FieldDefn(dst_fieldname, ogr.OFTInteger) + dst_layer.CreateField(fd) + gdal.Polygonize(srcband, maskband, dst_layer, 0, []) + # TODO: temporary: delete ignored values + dst_ds.Destroy() + ds = None + vec_ds = drv.Open(vec_save_path, 1) + lyr = vec_ds.GetLayer() + lyr.SetAttributeFilter("{} = '{}'".format(dst_fieldname, str(ignore_index))) + for holes in lyr: + lyr.DeleteFeature(holes.GetFID()) + vec_ds.Destroy() + if tmp_path is not None: + os.remove(tmp_path) + + +@time_it +def mask2shape(srcimg_path, mask_path, save_path, ignore_index=255): + vec_ext = save_path.split(".")[-1].lower() + if vec_ext not in ["json", "geojson", "shp"]: + raise ValueError( + "The extension of `save_path` must be 'json/geojson' or 'shp', not {}.". + format(vec_ext)) + ras_ext = srcimg_path.split(".")[-1].lower() + if osp.exists(srcimg_path) and ras_ext in ["tif", "tiff", "geotiff", "img"]: + src = Raster(srcimg_path) + _polygonize_raster(mask_path, save_path, src.proj, src.geot, + ignore_index, vec_ext) + src = None + else: + _polygonize_raster(mask_path, save_path, None, None, ignore_index, + vec_ext) + + +parser = argparse.ArgumentParser() +parser.add_argument("--mask_path", type=str, required=True, \ + help="Path of mask data.") +parser.add_argument("--save_path", type=str, required=True, \ + help="Path to save the shape file (the extension is .json/geojson or .shp).") +parser.add_argument("--srcimg_path", type=str, default="", \ + help="Path of original data with geoinfo. Default to empty.") +parser.add_argument("--ignore_index", type=int, default=255, \ + help="The ignored index will not be converted to a value in the shape file. Default value is 255.") + +if __name__ == "__main__": + args = parser.parse_args() + mask2shape(args.srcimg_path, args.mask_path, args.save_path, + args.ignore_index) diff --git a/tutorials/train/README.md b/tutorials/train/README.md index 0328607..c63cf26 100644 --- a/tutorials/train/README.md +++ b/tutorials/train/README.md @@ -1,11 +1,12 @@ # 使用教程——训练模型 -本目录下整理了使用PaddleRS训练模型的示例代码。代码中均提供了示例数据的自动下载,并均使用GPU对模型进行训练。 +本目录中整理了使用PaddleRS训练模型的示例代码。代码中均提供对示例数据的自动下载,并均使用GPU对模型进行训练。 |示例代码路径 | 任务 | 模型 | |------|--------|---------| |change_detection/bit.py | 变化检测 | BIT | |change_detection/cdnet.py | 变化检测 | CDNet | +|change_detection/changeformer.py | 变化检测 | ChangeFormer | |change_detection/dsamnet.py | 变化检测 | DSAMNet | |change_detection/dsifn.py | 变化检测 | DSIFN | |change_detection/snunet.py | 变化检测 | SNUNet | @@ -27,22 +28,16 @@ |semantic_segmentation/deeplabv3p.py | 图像分割 | DeepLab V3+ | |semantic_segmentation/unet.py | 图像分割 | UNet | - - ## 环境准备 -- [PaddlePaddle安装](https://www.paddlepaddle.org.cn/install/quick) - * 版本要求:PaddlePaddle>=2.2.0 ++ [PaddlePaddle安装](https://www.paddlepaddle.org.cn/install/quick) + - 版本要求:PaddlePaddle>=2.2.0 -- PaddleRS安装 ++ PaddleRS安装 PaddleRS代码会跟随开发进度不断更新,可以安装develop分支的代码使用最新的功能,安装方式如下: -``` +```shell git clone https://github.com/PaddlePaddle/PaddleRS cd PaddleRS git checkout develop @@ -50,47 +45,49 @@ pip install -r requirements.txt python setup.py install ``` -- \*GDAL安装 ++ (可选)GDAL安装 -PaddleRS支持多种类型的卫星数据IO以及地理处理等,可能需要使用GDAL,可以根据需求进行安装,安装方式如下: +PaddleRS支持对多种类型卫星数据的读取。完整使用PaddleRS的遥感数据读取功能需要安装GDAL,安装方式如下: - Linux / MacOS 推荐使用conda进行安装: -``` +```shell conda install gdal ``` - Windows -Windows用户可以通过[这里](https://www.lfd.uci.edu/~gohlke/pythonlibs/#gdal)下载对应Python和系统版本的二进制文件(\*.whl)到本地,以*GDAL‑3.3.3‑cp39‑cp39‑win_amd64.whl*为例,进入下载目录进行安装: +Windows用户可以在[此站点](https://www.lfd.uci.edu/~gohlke/pythonlibs/#gdal)下载与Python和系统版本相对应的.whl格式安装包到本地,以*GDAL‑3.3.3‑cp39‑cp39‑win_amd64.whl*为例,使用pip工具安装: -``` -cd download +```shell pip install GDAL‑3.3.3‑cp39‑cp39‑win_amd64.whl ``` ## 开始训练 -* 在安装PaddleRS后,使用如下命令进行单卡训练。代码会自动下载训练数据。以DeepLab V3+图像分割模型为例: -```commandline ++ 在安装完成PaddleRS后,使用如下命令执行单卡训练。脚本将自动下载训练数据。以DeepLab V3+图像分割模型为例: + +```shell # 指定需要使用的GPU设备编号 export CUDA_VISIBLE_DEVICES=0 python tutorials/train/semantic_segmentation/deeplabv3p.py ``` -* 如需使用多块GPU进行训练,例如使用2张显卡时,执行如下命令: ++ 如需使用多块GPU进行训练,例如使用2张显卡时,执行如下命令: -```commandline +```shell python -m paddle.distributed.launch --gpus 0,1 tutorials/train/semantic_segmentation/deeplabv3p.py ``` ## VisualDL可视化训练指标 -将传入`train`方法的`use_vdl`参数设为`True`,则模型训练过程中将自动把训练日志以VisualDL的格式存储到`save_dir`(用户自己指定的路径)目录下名为`vdl_log`的子目录中。用户可以使用如下命令启动VisualDL服务,查看可视化指标。同样以DeepLab V3+模型为例: -```commandline + +将传入`train()`方法的`use_vdl`参数设为`True`,则模型训练过程中将自动把训练日志以VisualDL的格式存储到`save_dir`(用户自己指定的路径)目录下名为`vdl_log`的子目录中。用户可以使用如下命令启动VisualDL服务,查看可视化指标。同样以DeepLab V3+模型为例: + +```shell # 指定端口号为8001 visualdl --logdir output/deeplabv3p/vdl_log --port 8001 ``` -服务启动后,使用浏览器打开 https://0.0.0.0:8001 或 https://localhost:8001 +服务启动后,使用浏览器打开 https://0.0.0.0:8001 或 https://localhost:8001 即可进入可视化页面。 diff --git a/tutorials/train/change_detection/bit.py b/tutorials/train/change_detection/bit.py index c2e92b3..83c96ce 100644 --- a/tutorials/train/change_detection/bit.py +++ b/tutorials/train/change_detection/bit.py @@ -21,7 +21,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -72,7 +72,7 @@ eval_dataset = pdrs.datasets.CDDataset( binarize_labels=True) # 使用默认参数构建BIT模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py model = pdrs.tasks.cd.BIT() diff --git a/tutorials/train/change_detection/cdnet.py b/tutorials/train/change_detection/cdnet.py index 53a1fa5..2aa2ad6 100644 --- a/tutorials/train/change_detection/cdnet.py +++ b/tutorials/train/change_detection/cdnet.py @@ -21,7 +21,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -72,7 +72,7 @@ eval_dataset = pdrs.datasets.CDDataset( binarize_labels=True) # 使用默认参数构建CDNet模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py model = pdrs.tasks.cd.CDNet() diff --git a/tutorials/train/change_detection/dsamnet.py b/tutorials/train/change_detection/dsamnet.py index d5d7884..2a0d3ae 100644 --- a/tutorials/train/change_detection/dsamnet.py +++ b/tutorials/train/change_detection/dsamnet.py @@ -21,7 +21,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -72,7 +72,7 @@ eval_dataset = pdrs.datasets.CDDataset( binarize_labels=True) # 使用默认参数构建DSAMNet模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py model = pdrs.tasks.cd.DSAMNet() diff --git a/tutorials/train/change_detection/dsifn.py b/tutorials/train/change_detection/dsifn.py index a68fdb5..6a2ed19 100644 --- a/tutorials/train/change_detection/dsifn.py +++ b/tutorials/train/change_detection/dsifn.py @@ -21,7 +21,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -72,7 +72,7 @@ eval_dataset = pdrs.datasets.CDDataset( binarize_labels=True) # 使用默认参数构建DSIFN模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py model = pdrs.tasks.cd.DSIFN() diff --git a/tutorials/train/change_detection/fc_ef.py b/tutorials/train/change_detection/fc_ef.py index 9b1663e..4324564 100644 --- a/tutorials/train/change_detection/fc_ef.py +++ b/tutorials/train/change_detection/fc_ef.py @@ -21,7 +21,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -72,7 +72,7 @@ eval_dataset = pdrs.datasets.CDDataset( binarize_labels=True) # 使用默认参数构建FC-EF模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py model = pdrs.tasks.cd.FCEarlyFusion() diff --git a/tutorials/train/change_detection/fc_siam_conc.py b/tutorials/train/change_detection/fc_siam_conc.py index ea164a3..d63f5dc 100644 --- a/tutorials/train/change_detection/fc_siam_conc.py +++ b/tutorials/train/change_detection/fc_siam_conc.py @@ -21,7 +21,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -72,7 +72,7 @@ eval_dataset = pdrs.datasets.CDDataset( binarize_labels=True) # 使用默认参数构建FC-Siam-conc模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py model = pdrs.tasks.cd.FCSiamConc() diff --git a/tutorials/train/change_detection/fc_siam_diff.py b/tutorials/train/change_detection/fc_siam_diff.py index cd98a3a..55f8681 100644 --- a/tutorials/train/change_detection/fc_siam_diff.py +++ b/tutorials/train/change_detection/fc_siam_diff.py @@ -21,7 +21,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -72,7 +72,7 @@ eval_dataset = pdrs.datasets.CDDataset( binarize_labels=True) # 使用默认参数构建FC-Siam-diff模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py model = pdrs.tasks.cd.FCSiamDiff() diff --git a/tutorials/train/change_detection/snunet.py b/tutorials/train/change_detection/snunet.py index 6e36c89..a4b6d65 100644 --- a/tutorials/train/change_detection/snunet.py +++ b/tutorials/train/change_detection/snunet.py @@ -21,7 +21,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -72,7 +72,7 @@ eval_dataset = pdrs.datasets.CDDataset( binarize_labels=True) # 使用默认参数构建SNUNet模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py model = pdrs.tasks.cd.SNUNet() diff --git a/tutorials/train/change_detection/stanet.py b/tutorials/train/change_detection/stanet.py index c718455..4fe9799 100644 --- a/tutorials/train/change_detection/stanet.py +++ b/tutorials/train/change_detection/stanet.py @@ -21,7 +21,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -72,7 +72,7 @@ eval_dataset = pdrs.datasets.CDDataset( binarize_labels=True) # 使用默认参数构建STANet模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/change_detector.py model = pdrs.tasks.cd.STANet() diff --git a/tutorials/train/classification/hrnet.py b/tutorials/train/classification/hrnet.py index 3641976..658dcef 100644 --- a/tutorials/train/classification/hrnet.py +++ b/tutorials/train/classification/hrnet.py @@ -23,7 +23,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -66,7 +66,7 @@ eval_dataset = pdrs.datasets.ClasDataset( shuffle=False) # 使用默认参数构建HRNet模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/classifier.py model = pdrs.tasks.clas.HRNet_W18_C(num_classes=len(train_dataset.labels)) diff --git a/tutorials/train/classification/mobilenetv3.py b/tutorials/train/classification/mobilenetv3.py index 5a175a0..1d85a06 100644 --- a/tutorials/train/classification/mobilenetv3.py +++ b/tutorials/train/classification/mobilenetv3.py @@ -23,7 +23,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -66,7 +66,7 @@ eval_dataset = pdrs.datasets.ClasDataset( shuffle=False) # 使用默认参数构建MobileNetV3模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/classifier.py model = pdrs.tasks.clas.MobileNetV3_small_x1_0( num_classes=len(train_dataset.labels)) diff --git a/tutorials/train/classification/resnet50_vd.py b/tutorials/train/classification/resnet50_vd.py index 562a194..40891e6 100644 --- a/tutorials/train/classification/resnet50_vd.py +++ b/tutorials/train/classification/resnet50_vd.py @@ -23,7 +23,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -66,7 +66,7 @@ eval_dataset = pdrs.datasets.ClasDataset( shuffle=False) # 使用默认参数构建ResNet50-vd模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/classifier.py model = pdrs.tasks.clas.ResNet50_vd(num_classes=len(train_dataset.labels)) diff --git a/tutorials/train/object_detection/faster_rcnn.py b/tutorials/train/object_detection/faster_rcnn.py index ec2d06f..bad300d 100644 --- a/tutorials/train/object_detection/faster_rcnn.py +++ b/tutorials/train/object_detection/faster_rcnn.py @@ -25,7 +25,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -69,7 +69,7 @@ eval_dataset = pdrs.datasets.VOCDetDataset( shuffle=False) # 构建Faster R-CNN模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/object_detector.py model = pdrs.tasks.det.FasterRCNN(num_classes=len(train_dataset.labels)) diff --git a/tutorials/train/object_detection/ppyolo.py b/tutorials/train/object_detection/ppyolo.py index 4559067..5fd3f2b 100644 --- a/tutorials/train/object_detection/ppyolo.py +++ b/tutorials/train/object_detection/ppyolo.py @@ -25,7 +25,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -69,7 +69,7 @@ eval_dataset = pdrs.datasets.VOCDetDataset( shuffle=False) # 构建PP-YOLO模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/object_detector.py model = pdrs.tasks.det.PPYOLO(num_classes=len(train_dataset.labels)) diff --git a/tutorials/train/object_detection/ppyolotiny.py b/tutorials/train/object_detection/ppyolotiny.py index 677b313..71271cd 100644 --- a/tutorials/train/object_detection/ppyolotiny.py +++ b/tutorials/train/object_detection/ppyolotiny.py @@ -25,7 +25,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -69,7 +69,7 @@ eval_dataset = pdrs.datasets.VOCDetDataset( shuffle=False) # 构建PP-YOLO Tiny模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/object_detector.py model = pdrs.tasks.det.PPYOLOTiny(num_classes=len(train_dataset.labels)) diff --git a/tutorials/train/object_detection/ppyolov2.py b/tutorials/train/object_detection/ppyolov2.py index bc36de0..5fb1918 100644 --- a/tutorials/train/object_detection/ppyolov2.py +++ b/tutorials/train/object_detection/ppyolov2.py @@ -25,7 +25,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -69,7 +69,7 @@ eval_dataset = pdrs.datasets.VOCDetDataset( shuffle=False) # 构建PP-YOLOv2模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/object_detector.py model = pdrs.tasks.det.PPYOLOv2(num_classes=len(train_dataset.labels)) diff --git a/tutorials/train/object_detection/yolov3.py b/tutorials/train/object_detection/yolov3.py index b05e030..5c25cd9 100644 --- a/tutorials/train/object_detection/yolov3.py +++ b/tutorials/train/object_detection/yolov3.py @@ -25,7 +25,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -69,7 +69,7 @@ eval_dataset = pdrs.datasets.VOCDetDataset( shuffle=False) # 构建YOLOv3模型,使用DarkNet53作为backbone -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/object_detector.py model = pdrs.tasks.det.YOLOv3( num_classes=len(train_dataset.labels), backbone='DarkNet53') diff --git a/tutorials/train/semantic_segmentation/deeplabv3p.py b/tutorials/train/semantic_segmentation/deeplabv3p.py index 3868669..b3dbd50 100644 --- a/tutorials/train/semantic_segmentation/deeplabv3p.py +++ b/tutorials/train/semantic_segmentation/deeplabv3p.py @@ -26,7 +26,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -68,7 +68,7 @@ eval_dataset = pdrs.datasets.SegDataset( shuffle=False) # 构建DeepLab V3+模型,使用ResNet-50作为backbone -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/segmenter.py model = pdrs.tasks.seg.DeepLabV3P( input_channel=NUM_BANDS, diff --git a/tutorials/train/semantic_segmentation/unet.py b/tutorials/train/semantic_segmentation/unet.py index 94fd4a1..e1e8b82 100644 --- a/tutorials/train/semantic_segmentation/unet.py +++ b/tutorials/train/semantic_segmentation/unet.py @@ -26,7 +26,7 @@ pdrs.utils.download_and_decompress( # 定义训练和验证时使用的数据变换(数据增强、预处理等) # 使用Compose组合多种变换方式。Compose中包含的变换将按顺序串行执行 -# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/transforms.md +# API说明:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/data.md train_transforms = T.Compose([ # 读取影像 T.DecodeImg(), @@ -68,7 +68,7 @@ eval_dataset = pdrs.datasets.SegDataset( shuffle=False) # 构建UNet模型 -# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/apis/model_zoo.md +# 目前已支持的模型请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/docs/intro/model_zoo.md # 模型输入参数请参考:https://github.com/PaddlePaddle/PaddleRS/blob/develop/paddlers/tasks/segmenter.py model = pdrs.tasks.seg.UNet( input_channel=NUM_BANDS, num_classes=len(train_dataset.labels))