diff --git a/docs/apis/datasets.md b/docs/apis/datasets.md index c02d642842f95c02dc95447d0349afc8e4198b5f..ae3595be7ece185ce1992d0e5a0c75e2977ef362 100644 --- a/docs/apis/datasets.md +++ b/docs/apis/datasets.md @@ -5,7 +5,7 @@ ``` paddlex.datasets.ImageNet(data_dir, file_list, label_list, transforms=None, num_workers=‘auto’, buffer_size=100, parallel_method='thread', shuffle=False) ``` -读取ImageNet格式的分类数据集,并对样本进行相应的处理。ImageNet数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md) +读取ImageNet格式的分类数据集,并对样本进行相应的处理。ImageNet数据集格式的介绍可查看文档:[数据集格式说明](../data/format/index.html) 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/classification/mobilenetv2.py#L25) @@ -26,7 +26,7 @@ paddlex.datasets.ImageNet(data_dir, file_list, label_list, transforms=None, num_ paddlex.datasets.PascalVOC(data_dir, file_list, label_list, transforms=None, num_workers=‘auto’, buffer_size=100, parallel_method='thread', shuffle=False) ``` -> 读取PascalVOC格式的检测数据集,并对样本进行相应的处理。PascalVOC数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md) +> 读取PascalVOC格式的检测数据集,并对样本进行相应的处理。PascalVOC数据集格式的介绍可查看文档:[数据集格式说明](../data/format/index.html) > 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/detection/yolov3_darknet53.py#L29) @@ -47,7 +47,7 @@ paddlex.datasets.PascalVOC(data_dir, file_list, label_list, transforms=None, num paddlex.datasets.MSCOCO(data_dir, ann_file, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False) ``` -> 读取MSCOCO格式的检测数据集,并对样本进行相应的处理,该格式的数据集同样可以应用到实例分割模型的训练中。MSCOCO数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md) +> 读取MSCOCO格式的检测数据集,并对样本进行相应的处理,该格式的数据集同样可以应用到实例分割模型的训练中。MSCOCO数据集格式的介绍可查看文档:[数据集格式说明](../data/format/index.html) > 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/detection/mask_rcnn_r50_fpn.py#L27) @@ -67,7 +67,7 @@ paddlex.datasets.MSCOCO(data_dir, ann_file, transforms=None, num_workers='auto', paddlex.datasets.SegDataset(data_dir, file_list, label_list, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False) ``` -> 读取语义分割任务数据集,并对样本进行相应的处理。语义分割任务数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md) +> 读取语义分割任务数据集,并对样本进行相应的处理。语义分割任务数据集格式的介绍可查看文档:[数据集格式说明](../data/format/index.html) > 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/segmentation/unet.py#L27) @@ -88,7 +88,7 @@ paddlex.datasets.SegDataset(data_dir, file_list, label_list, transforms=None, nu paddlex.datasets.EasyDataCls(data_dir, file_list, label_list, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False) ``` -> 读取EasyData平台标注图像分类数据集,并对样本进行相应的处理。EasyData图像分类任务数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md)。 +> 读取EasyData平台标注图像分类数据集,并对样本进行相应的处理。 > **参数** @@ -107,7 +107,7 @@ paddlex.datasets.EasyDataCls(data_dir, file_list, label_list, transforms=None, n paddlex.datasets.EasyDataDet(data_dir, file_list, label_list, transforms=None, num_workers=‘auto’, buffer_size=100, parallel_method='thread', shuffle=False) ``` -> 读取EasyData目标检测格式数据集,并对样本进行相应的处理,该格式的数据集同样可以应用到实例分割模型的训练中。EasyData目标检测或实例分割任务数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md) +> 读取EasyData目标检测/实例分割格式数据集,并对样本进行相应的处理,该格式的数据集同样可以应用到实例分割模型的训练中。 > **参数** @@ -127,7 +127,7 @@ paddlex.datasets.EasyDataDet(data_dir, file_list, label_list, transforms=None, n paddlex.datasets.EasyDataSeg(data_dir, file_list, label_list, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False) ``` -> 读取EasyData语义分割任务数据集,并对样本进行相应的处理。EasyData语义分割任务数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md) +> 读取EasyData语义分割任务数据集,并对样本进行相应的处理。 > **参数** diff --git a/docs/apis/models/classification.md b/docs/apis/models/classification.md index 53314880748714d1da5a92019b91d4668afb65c6..135b50ed6dc73ef4f9becae9132a800424835c69 100755 --- a/docs/apis/models/classification.md +++ b/docs/apis/models/classification.md @@ -69,7 +69,7 @@ predict(self, img_file, transforms=None, topk=5) > **参数** > -> > - **img_file** (str): 预测图像路径。 +> > - **img_file** (str|np.ndarray): 预测图像路径或numpy数组(HWC排列,BGR格式)。 > > - **transforms** (paddlex.cls.transforms): 数据预处理操作。 > > - **topk** (int): 预测时前k个最大值。 diff --git a/docs/apis/models/detection.md b/docs/apis/models/detection.md index 47cec854398181c80990af5e13e87c1cbb467d7e..ab3f413e18b7fad427f2e3ec0db32927a800b29b 100755 --- a/docs/apis/models/detection.md +++ b/docs/apis/models/detection.md @@ -87,7 +87,7 @@ predict(self, img_file, transforms=None) > **参数** > -> > - **img_file** (str): 预测图像路径。 +> > - **img_file** (str|np.ndarray): 预测图像路径或numpy数组(HWC排列,BGR格式)。 > > - **transforms** (paddlex.det.transforms): 数据预处理操作。 > > **返回值** @@ -172,7 +172,7 @@ predict(self, img_file, transforms=None) > **参数** > -> > - **img_file** (str): 预测图像路径。 +> > - **img_file** (str|np.ndarray): 预测图像路径或numpy数组(HWC排列,BGR格式)。 > > - **transforms** (paddlex.det.transforms): 数据预处理操作。 > > **返回值** diff --git a/docs/apis/models/instance_segmentation.md b/docs/apis/models/instance_segmentation.md index b1184c4fdcd8a5cbf5da0b774e1c078fad100a79..916b8510855c1796b7e4fc45843702eb1a0553b7 100755 --- a/docs/apis/models/instance_segmentation.md +++ b/docs/apis/models/instance_segmentation.md @@ -77,7 +77,7 @@ predict(self, img_file, transforms=None) > **参数** > -> > - **img_file** (str): 预测图像路径。 +> > - **img_file** (str|np.ndarray): 预测图像路径或numpy数组(HWC排列,BGR格式)。 > > - **transforms** (paddlex.det.transforms): 数据预处理操作。 > > **返回值** diff --git a/docs/apis/models/semantic_segmentation.md b/docs/apis/models/semantic_segmentation.md index 69daf4751a7838589bd78d3a5793e293d2843aa9..f6d940abde6020dea74c134d7f3dc29d4aa8201a 100755 --- a/docs/apis/models/semantic_segmentation.md +++ b/docs/apis/models/semantic_segmentation.md @@ -83,7 +83,7 @@ predict(self, im_file, transforms=None): > **参数** > > -> > - **img_file** (str): 预测图像路径。 +> > - **img_file** (str|np.ndarray): 预测图像路径或numpy数组(HWC排列,BGR格式)。 > > - **transforms** (paddlex.seg.transforms): 数据预处理操作。 > **返回值** diff --git a/docs/apis/transforms/augment.md b/docs/apis/transforms/augment.md index 3e5e1cc46ed66cd504e72c8f410bd5d01bcf2dc5..f8c66b45d2d853fde57c520b079f9974e5fa4d76 100644 --- a/docs/apis/transforms/augment.md +++ b/docs/apis/transforms/augment.md @@ -1,4 +1,4 @@ -# 数据增强与imgaug支持说明 +# 数据增强与imgaug支持 数据增强操作可用于在模型训练时,增加训练样本的多样性,从而提升模型的泛化能力。 @@ -19,11 +19,11 @@ PaddleX目前已适配imgaug图像增强库,用户可以直接在PaddleX构造 import paddlex as pdx from paddlex.cls import transforms import imgaug.augmenters as iaa -train_transforms = transforms.ComposedClsTransforms(mode='train', crop_size=[224, 224]) -train_transforms.add_augmenters([ +train_transforms = transforms.Compose([ # 随机在[0.0 3.0]中选值对图像进行模糊 iaa.blur.GaussianBlur(sigma=(0.0, 3.0)), - transforms.RandomCrop(crop_size=224) + transforms.RandomCrop(crop_size=224), + transforms.Normalize() ]) ``` 除了上述用法,`Compose`接口中也支持imgaug的`Someof`、`Sometimes`、`Sequential`、`Oneof`等操作,开发者可以通过这些方法随意组合出增强流程。由于imgaug对于标注信息(目标检测框和实例分割mask)与PaddleX模型训练逻辑有部分差异,**目前在检测和分割中,只支持pixel-level的增强方法,(即在增强时,不对图像的大小和方向做改变) 其它方法仍在适配中**,详情可见下表, @@ -58,9 +58,9 @@ from paddlex.cls import transforms img_augmenters = iaa.Sometimes(0.6, [ iaa.blur.GaussianBlur(sigma=(0.0, 3.0)) ]) -train_transforms = transforms.ComposedClsTransforms(mode='train', crop_size=[224, 224]) -train_transforms.add_augmenters([ +train_transforms = transforms.Compose([ img_augmenters, - transforms.RandomCrop(crop_size=224) + transforms.RandomCrop(crop_size=224), + transforms.Normalize() ]) ``` diff --git a/docs/apis/transforms/cls_transforms.md b/docs/apis/transforms/cls_transforms.md index 405699ae3e6b2fda653eaf9728db2f247aed7763..b77bcfa483c9f40aedf90911330163d71c9aff85 100755 --- a/docs/apis/transforms/cls_transforms.md +++ b/docs/apis/transforms/cls_transforms.md @@ -12,68 +12,6 @@ paddlex.cls.transforms.Compose(transforms) > **参数** > * **transforms** (list): 数据预处理/数据增强列表。 - -## ComposedClsTransforms -```python -paddlex.cls.transforms.ComposedClsTransforms(mode, crop_size=[224, 224], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) -``` -分类模型中已经组合好的数据处理流程,开发者可以直接使用ComposedClsTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomCrop](#RandomCrop)和[RandomHorizontalFlip](#RandomHorizontalFlip)两种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 -ComposedClsTransforms共包括以下几个步骤: -> 训练阶段: -> > 1. 随机从图像中crop一块子图,并resize成crop_size大小 -> > 2. 将1的输出按0.5的概率随机进行水平翻转 -> > 3. 将图像进行归一化 -> 验证/预测阶段: -> > 1. 将图像按比例Resize,使得最小边长度为crop_size[0] * 1.14 -> > 2. 从图像中心crop出一个大小为crop_size的图像 -> > 3. 将图像进行归一化 - -### 参数 -* **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test' -* **crop_size** (int|list): 输入到模型里的图像大小,默认为[224, 224](与原图大小无关,根据上述几个步骤,会将原图处理成该图大小输入给模型训练) -* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 -* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 - -### 添加数据增强方式 -```python -ComposedClsTransforms.add_augmenters(augmenters) -``` -> **参数** -> * **augmenters**(list): 数据增强方式列表 - -#### 使用示例 -``` -import paddlex as pdx -from paddlex.cls import transforms -train_transforms = transforms.ComposedClsTransforms(mode='train', crop_size=[320, 320]) -eval_transforms = transforms.ComposedClsTransforms(mode='eval', crop_size=[320, 320]) - -# 添加数据增强 -import imgaug.augmenters as iaa -train_transforms.add_augmenters([ - transforms.RandomDistort(), - iaa.blur.GaussianBlur(sigma=(0.0, 3.0)) -]) -``` -上面代码等价于 -``` -import paddlex as pdx -from paddlex.cls import transforms -train_transforms = transforms.Composed([ - transforms.RandomDistort(), - iaa.blur.GaussianBlur(sigma=(0.0, 3.0)), - # 上面两个为通过add_augmenters额外添加的数据增强方式 - transforms.RandomCrop(crop_size=320), - transforms.RandomHorizontalFlip(prob=0.5), - transforms.Normalize() -]) -eval_transforms = transforms.Composed([ - transforms.ResizeByShort(short_size=int(320*1.14)), - transforms.CenterCrop(crop_size=320), - transforms.Normalize() -]) -``` - ## Normalize ```python paddlex.cls.transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) @@ -183,3 +121,65 @@ paddlex.cls.transforms.RandomDistort(brightness_range=0.9, brightness_prob=0.5, * **saturation_prob** (float): 随机调整饱和度的概率。默认为0.5。 * **hue_range** (int): 色调因子的范围。默认为18。 * **hue_prob** (float): 随机调整色调的概率。默认为0.5。 + +## ComposedClsTransforms +```python +paddlex.cls.transforms.ComposedClsTransforms(mode, crop_size=[224, 224], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], random_horizontal_flip=True) +``` +分类模型中已经组合好的数据处理流程,开发者可以直接使用ComposedClsTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomCrop](#RandomCrop)和[RandomHorizontalFlip](#RandomHorizontalFlip)两种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 +ComposedClsTransforms共包括以下几个步骤: +> 训练阶段: +> > 1. 随机从图像中crop一块子图,并resize成crop_size大小 +> > 2. 将1的输出按0.5的概率随机进行水平翻转, 若random_horizontal_flip为False,则跳过此步骤 +> > 3. 将图像进行归一化 +> 验证/预测阶段: +> > 1. 将图像按比例Resize,使得最小边长度为crop_size[0] * 1.14 +> > 2. 从图像中心crop出一个大小为crop_size的图像 +> > 3. 将图像进行归一化 + +### 参数 +* **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test' +* **crop_size** (int|list): 输入到模型里的图像大小,默认为[224, 224](与原图大小无关,根据上述几个步骤,会将原图处理成该图大小输入给模型训练) +* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 +* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 +* **random_horizontal_flip**(bool): 数据增强,是否以0,5的概率使用随机水平翻转增强,仅在model为'train'时生效,默认为True。底层实现采用[paddlex.cls.transforms.RandomHorizontalFlip](#randomhorizontalflip) + +### 添加数据增强方式 +```python +ComposedClsTransforms.add_augmenters(augmenters) +``` +> **参数** +> * **augmenters**(list): 数据增强方式列表 + +#### 使用示例 +``` +import paddlex as pdx +from paddlex.cls import transforms +train_transforms = transforms.ComposedClsTransforms(mode='train', crop_size=[320, 320]) +eval_transforms = transforms.ComposedClsTransforms(mode='eval', crop_size=[320, 320]) + +# 添加数据增强 +import imgaug.augmenters as iaa +train_transforms.add_augmenters([ + transforms.RandomDistort(), + iaa.blur.GaussianBlur(sigma=(0.0, 3.0)) +]) +``` +上面代码等价于 +``` +import paddlex as pdx +from paddlex.cls import transforms +train_transforms = transforms.Composed([ + transforms.RandomDistort(), + iaa.blur.GaussianBlur(sigma=(0.0, 3.0)), + # 上面两个为通过add_augmenters额外添加的数据增强方式 + transforms.RandomCrop(crop_size=320), + transforms.RandomHorizontalFlip(prob=0.5), + transforms.Normalize() +]) +eval_transforms = transforms.Composed([ + transforms.ResizeByShort(short_size=int(320*1.14)), + transforms.CenterCrop(crop_size=320), + transforms.Normalize() +]) +``` diff --git a/docs/apis/transforms/det_transforms.md b/docs/apis/transforms/det_transforms.md index ac7be78819fb04a3392726fe4ce1f20e256959db..3d623a15eab25ec15f57f088863c3e2a9795f567 100755 --- a/docs/apis/transforms/det_transforms.md +++ b/docs/apis/transforms/det_transforms.md @@ -12,136 +12,6 @@ paddlex.det.transforms.Compose(transforms) ### 参数 * **transforms** (list): 数据预处理/数据增强列表。 -## ComposedRCNNTransforms -```python -paddlex.det.transforms.ComposedRCNNTransforms(mode, min_max_size=[224, 224], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) -``` -目标检测FasterRCNN和实例分割MaskRCNN模型中已经组合好的数据处理流程,开发者可以直接使用ComposedRCNNTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomHorizontalFlip](#RandomHorizontalFlip)数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 -ComposedRCNNTransforms共包括以下几个步骤: -> 训练阶段: -> > 1. 随机以0.5的概率将图像水平翻转 -> > 2. 将图像进行归一化 -> > 3. 图像采用[ResizeByShort](#ResizeByShort)方式,根据min_max_size参数,进行缩入 -> > 4. 使用[Padding](#Padding)将图像的长和宽分别Padding成32的倍数 -> 验证/预测阶段: -> > 1. 将图像进行归一化 -> > 2. 图像采用[ResizeByShort](#ResizeByShort)方式,根据min_max_size参数,进行缩入 -> > 3. 使用[Padding](#Padding)将图像的长和宽分别Padding成32的倍数 - -### 参数 -* **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test' -* **min_max_size** (list): 输入模型中图像的最短边长度和最长边长度,参考[ResizeByShort](#ResizeByShort)(与原图大小无关,根据上述几个步骤,会将原图处理成相应大小输入给模型训练),默认[800, 1333] -* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 -* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 - -### 添加数据增强方式 -```python -ComposedRCNNTransforms.add_augmenters(augmenters) -``` -> **参数** -> * **augmenters**(list): 数据增强方式列表 - -#### 使用示例 -``` -import paddlex as pdx -from paddlex.det import transforms -train_transforms = transforms.ComposedRCNNTransforms(mode='train', min_max_size=[800, 1333]) -eval_transforms = transforms.ComposedRCNNTransforms(mode='eval', min_max_size=[800, 1333]) - -# 添加数据增强 -import imgaug.augmenters as iaa -train_transforms.add_augmenters([ - transforms.RandomDistort(), - iaa.blur.GaussianBlur(sigma=(0.0, 3.0)) -]) -``` -上面代码等价于 -``` -import paddlex as pdx -from paddlex.det import transforms -train_transforms = transforms.Composed([ - transforms.RandomDistort(), - iaa.blur.GaussianBlur(sigma=(0.0, 3.0)), - # 上面两个为通过add_augmenters额外添加的数据增强方式 - transforms.RandomHorizontalFlip(prob=0.5), - transforms.Normalize(), - transforms.ResizeByShort(short_size=800, max_size=1333), - transforms.Padding(coarsest_stride=32) -]) -eval_transforms = transforms.Composed([ - transforms.Normalize(), - transforms.ResizeByShort(short_size=800, max_size=1333), - transforms.Padding(coarsest_stride=32) -]) -``` - - -## ComposedYOLOv3Transforms -```python -paddlex.det.transforms.ComposedYOLOv3Transforms(mode, shape=[608, 608], mixup_epoch=250, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) -``` -目标检测YOLOv3模型中已经组合好的数据处理流程,开发者可以直接使用ComposedYOLOv3Transforms,简化手动组合transforms的过程, 该类中已经包含了[MixupImage](#MixupImage)、[RandomDistort](#RandomDistort)、[RandomExpand](#RandomExpand)、[RandomCrop](#RandomCrop)、[RandomHorizontalFlip](#RandomHorizontalFlip)5种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 -ComposedYOLOv3Transforms共包括以下几个步骤: -> 训练阶段: -> > 1. 在前mixup_epoch轮迭代中,使用MixupImage策略 -> > 2. 对图像进行随机扰动,包括亮度,对比度,饱和度和色调 -> > 3. 随机扩充图像 -> > 4. 随机裁剪图像 -> > 5. 将4步骤的输出图像Resize成shape参数的大小 -> > 6. 随机0.5的概率水平翻转图像 -> > 7. 图像归一化 -> 验证/预测阶段: -> > 1. 将图像Resize成shape参数大小 -> > 2. 图像归一化 - -### 参数 -* **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test' -* **shape** (list): 输入模型中图像的大小(与原图大小无关,根据上述几个步骤,会将原图处理成相应大小输入给模型训练), 默认[608, 608] -* **mixup_epoch**(int): 模型训练过程中,在前mixup_epoch轮迭代中,使用mixup策略,如果为-1,则不使用mixup策略, 默认250。 -* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 -* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 - -### 添加数据增强方式 -```python -ComposedYOLOv3Transforms.add_augmenters(augmenters) -``` -> **参数** -> * **augmenters**(list): 数据增强方式列表 - -#### 使用示例 -``` -import paddlex as pdx -from paddlex.det import transforms -train_transforms = transforms.ComposedYOLOv3Transforms(mode='train', shape=[480, 480]) -eval_transforms = transforms.ComposedYOLOv3Transforms(mode='eval', shape=[480, 480]) - -# 添加数据增强 -import imgaug.augmenters as iaa -train_transforms.add_augmenters([ - iaa.blur.GaussianBlur(sigma=(0.0, 3.0)) -]) -``` -上面代码等价于 -``` -import paddlex as pdx -from paddlex.det import transforms -train_transforms = transforms.Composed([ - iaa.blur.GaussianBlur(sigma=(0.0, 3.0)), - # 上面为通过add_augmenters额外添加的数据增强方式 - transforms.MixupImage(mixup_epoch=250), - transforms.RandomDistort(), - transforms.RandomExpand(), - transforms.RandomCrop(), - transforms.Resize(target_size=480, interp='RANDOM'), - transforms.RandomHorizontalFlip(prob=0.5), - transforms.Normalize() -]) -eval_transforms = transforms.Composed([ - transforms.Resize(target_size=480, interp='CUBIC'), - transforms.Normalize() -]) -``` - ## Normalize ```python paddlex.det.transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) @@ -297,3 +167,138 @@ paddlex.det.transforms.RandomCrop(aspect_ratio=[.5, 2.], thresholds=[.0, .1, .3, * **num_attempts** (int): 在放弃寻找有效裁剪区域前尝试的次数。默认值为50。 * **allow_no_crop** (bool): 是否允许未进行裁剪。默认值为True。 * **cover_all_box** (bool): 是否要求所有的真实标注框都必须在裁剪区域内。默认值为False。 + +## ComposedRCNNTransforms +```python +paddlex.det.transforms.ComposedRCNNTransforms(mode, min_max_size=[224, 224], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], random_horizontal_flip=True) +``` +目标检测FasterRCNN和实例分割MaskRCNN模型中已经组合好的数据处理流程,开发者可以直接使用ComposedRCNNTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomHorizontalFlip](#RandomHorizontalFlip)数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 +ComposedRCNNTransforms共包括以下几个步骤: +> 训练阶段: +> > 1. 随机以0.5的概率将图像水平翻转, 若random_horizontal_flip为False,则跳过此步骤 +> > 2. 将图像进行归一化 +> > 3. 图像采用[ResizeByShort](#ResizeByShort)方式,根据min_max_size参数,进行缩入 +> > 4. 使用[Padding](#Padding)将图像的长和宽分别Padding成32的倍数 +> 验证/预测阶段: +> > 1. 将图像进行归一化 +> > 2. 图像采用[ResizeByShort](#ResizeByShort)方式,根据min_max_size参数,进行缩入 +> > 3. 使用[Padding](#Padding)将图像的长和宽分别Padding成32的倍数 + +### 参数 +* **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test' +* **min_max_size** (list): 输入模型中图像的最短边长度和最长边长度,参考[ResizeByShort](#ResizeByShort)(与原图大小无关,根据上述几个步骤,会将原图处理成相应大小输入给模型训练),默认[800, 1333] +* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 +* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 +* **random_horizontal_flip**(bool): 数据增强,是否以0.5的概率使用随机水平翻转增强,仅在mode为'train'时生效,默认为True。底层实现采用[paddlex.det.transforms.RandomHorizontalFlip](#randomhorizontalflip) + +### 添加数据增强方式 +```python +ComposedRCNNTransforms.add_augmenters(augmenters) +``` +> **参数** +> * **augmenters**(list): 数据增强方式列表 + +#### 使用示例 +``` +import paddlex as pdx +from paddlex.det import transforms +train_transforms = transforms.ComposedRCNNTransforms(mode='train', min_max_size=[800, 1333]) +eval_transforms = transforms.ComposedRCNNTransforms(mode='eval', min_max_size=[800, 1333]) + +# 添加数据增强 +import imgaug.augmenters as iaa +train_transforms.add_augmenters([ + transforms.RandomDistort(), + iaa.blur.GaussianBlur(sigma=(0.0, 3.0)) +]) +``` +上面代码等价于 +``` +import paddlex as pdx +from paddlex.det import transforms +train_transforms = transforms.Composed([ + transforms.RandomDistort(), + iaa.blur.GaussianBlur(sigma=(0.0, 3.0)), + # 上面两个为通过add_augmenters额外添加的数据增强方式 + transforms.RandomHorizontalFlip(prob=0.5), + transforms.Normalize(), + transforms.ResizeByShort(short_size=800, max_size=1333), + transforms.Padding(coarsest_stride=32) +]) +eval_transforms = transforms.Composed([ + transforms.Normalize(), + transforms.ResizeByShort(short_size=800, max_size=1333), + transforms.Padding(coarsest_stride=32) +]) +``` + + +## ComposedYOLOv3Transforms +```python +paddlex.det.transforms.ComposedYOLOv3Transforms(mode, shape=[608, 608], mixup_epoch=250, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], random_distort=True, random_expand=True, random_crop=True, random_horizontal_flip=True) +``` +目标检测YOLOv3模型中已经组合好的数据处理流程,开发者可以直接使用ComposedYOLOv3Transforms,简化手动组合transforms的过程, 该类中已经包含了[MixupImage](#MixupImage)、[RandomDistort](#RandomDistort)、[RandomExpand](#RandomExpand)、[RandomCrop](#RandomCrop)、[RandomHorizontalFlip](#RandomHorizontalFlip)5种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 +ComposedYOLOv3Transforms共包括以下几个步骤: +> 训练阶段: +> > 1. 在前mixup_epoch轮迭代中,使用MixupImage策略,若mixup_epoch为-1,则跳过此步骤 +> > 2. 对图像进行随机扰动,包括亮度,对比度,饱和度和色调,若random_distort为False,则跳过此步骤 +> > 3. 随机扩充图像,若random_expand为False, 则跳过此步骤 +> > 4. 随机裁剪图像,若random_crop为False, 则跳过此步骤 +> > 5. 将4步骤的输出图像Resize成shape参数的大小 +> > 6. 随机0.5的概率水平翻转图像,若random_horizontal_flip为False,则跳过此步骤 +> > 7. 图像归一化 +> 验证/预测阶段: +> > 1. 将图像Resize成shape参数大小 +> > 2. 图像归一化 + +### 参数 +* **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test' +* **shape** (list): 输入模型中图像的大小(与原图大小无关,根据上述几个步骤,会将原图处理成相应大小输入给模型训练), 默认[608, 608] +* **mixup_epoch**(int): 模型训练过程中,在前mixup_epoch轮迭代中,使用mixup策略,如果为-1,则不使用mixup策略, 默认250。底层实现采用[paddlex.det.transforms.MixupImage](#mixupimage) +* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 +* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 +* **random_distort**(bool): 数据增强,是否在训练过程中随机扰动图像,仅在mode为'train'时生效,默认为True。底层实现采用[paddlex.det.transforms.RandomDistort](#randomdistort) +* **random_expand**(bool): 数据增强,是否在训练过程随机扩张图像,仅在mode为'train'时生效,默认为True。底层实现采用[paddlex.det.transforms.RandomExpand](#randomexpand) +* **random_crop**(bool): 数据增强,是否在训练过程中随机裁剪图像,仅在mode为'train'时生效,默认为True。底层实现采用[paddlex.det.transforms.RandomCrop](#randomcrop) +* **random_horizontal_flip**(bool): 数据增强,是否在训练过程中随机水平翻转图像,仅在mode为'train'时生效,默认为True。底层实现采用[paddlex.det.transforms.RandomHorizontalFlip](#randomhorizontalflip) + +### 添加数据增强方式 +```python +ComposedYOLOv3Transforms.add_augmenters(augmenters) +``` +> **参数** +> * **augmenters**(list): 数据增强方式列表 + +#### 使用示例 +``` +import paddlex as pdx +from paddlex.det import transforms +train_transforms = transforms.ComposedYOLOv3Transforms(mode='train', shape=[480, 480]) +eval_transforms = transforms.ComposedYOLOv3Transforms(mode='eval', shape=[480, 480]) + +# 添加数据增强 +import imgaug.augmenters as iaa +train_transforms.add_augmenters([ + iaa.blur.GaussianBlur(sigma=(0.0, 3.0)) +]) +``` +上面代码等价于 +``` +import paddlex as pdx +from paddlex.det import transforms +train_transforms = transforms.Composed([ + iaa.blur.GaussianBlur(sigma=(0.0, 3.0)), + # 上面为通过add_augmenters额外添加的数据增强方式 + transforms.MixupImage(mixup_epoch=250), + transforms.RandomDistort(), + transforms.RandomExpand(), + transforms.RandomCrop(), + transforms.Resize(target_size=480, interp='RANDOM'), + transforms.RandomHorizontalFlip(prob=0.5), + transforms.Normalize() +]) +eval_transforms = transforms.Composed([ + transforms.Resize(target_size=480, interp='CUBIC'), + transforms.Normalize() +]) +``` diff --git a/docs/apis/transforms/seg_transforms.md b/docs/apis/transforms/seg_transforms.md index 975bb9e6e6731bdd3acb9430ddb2dfb086e2a2bb..b7f15e978f617bf9129fa504fc6cf682ea0cb0a7 100755 --- a/docs/apis/transforms/seg_transforms.md +++ b/docs/apis/transforms/seg_transforms.md @@ -11,64 +11,6 @@ paddlex.seg.transforms.Compose(transforms) ### 参数 * **transforms** (list): 数据预处理/数据增强列表。 -## ComposedSegTransforms -```python -paddlex.det.transforms.ComposedSegTransforms(mode, train_crop_shape=[769, 769], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) -``` -语义分割DeepLab和UNet模型中已经组合好的数据处理流程,开发者可以直接使用ComposedSegTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomHorizontalFlip](#RandomHorizontalFlip)、[ResizeStepScaling](#ResizeStepScaling)、[RandomPaddingCrop](#RandomPaddingCrop)3种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 -ComposedSegTransforms共包括以下几个步骤: - > 训练阶段: -> > 1. 随机对图像以0.5的概率水平翻转 -> > 2. 按不同的比例随机Resize原图 -> > 3. 从原图中随机crop出大小为train_crop_size大小的子图,如若crop出来的图小于train_crop_size,则会将图padding到对应大小 -> > 4. 图像归一化 - > 预测阶段: -> > 1. 图像归一化 - -### 参数 -* **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test' -* **train_crop_size** (list): 训练过程中随机Crop和Resize后(验证或预测过程中不需配置该参数,自动使用原图大小),输入到模型中图像的大小(与原图大小无关,根据上述几个步骤,会将原图处理成相应大小输入给模型训练), 默认[769, 769] -* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 -* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 - -### 添加数据增强方式 -```python -ComposedSegTransforms.add_augmenters(augmenters) -``` -> **参数** -> * **augmenters**(list): 数据增强方式列表 - -#### 使用示例 -``` -import paddlex as pdx -from paddlex.seg import transforms -train_transforms = transforms.ComposedSegTransforms(mode='train', train_crop_size=[512, 512]) -eval_transforms = transforms.ComposedSegTransforms(mode='eval') - -# 添加数据增强 -import imgaug.augmenters as iaa -train_transforms.add_augmenters([ - transforms.RandomDistort(), - iaa.blur.GaussianBlur(sigma=(0.0, 3.0)) -]) -``` -上面代码等价于 -``` -import paddlex as pdx -from paddlex.det import transforms -train_transforms = transforms.Composed([ - transforms.RandomDistort(), - iaa.blur.GaussianBlur(sigma=(0.0, 3.0)), - # 上面2行为通过add_augmenters额外添加的数据增强方式 - transforms.RandomHorizontalFlip(prob=0.5), - transforms.ResizeStepScaling(), - transforms.PaddingCrop(crop_size=[512, 512]), - transforms.Normalize() -]) -eval_transforms = transforms.Composed([ - transforms.Normalize() -]) -``` ## RandomHorizontalFlip ```python @@ -224,3 +166,65 @@ paddlex.seg.transforms.RandomDistort(brightness_range=0.5, brightness_prob=0.5, * **saturation_prob** (float): 随机调整饱和度的概率。默认为0.5。 * **hue_range** (int): 色调因子的范围。默认为18。 * **hue_prob** (float): 随机调整色调的概率。默认为0.5。 + +## ComposedSegTransforms +```python +paddlex.det.transforms.ComposedSegTransforms(mode, min_max_size=[400, 600], train_crop_shape=[769, 769], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], random_horizontal_flip=True) +``` +语义分割DeepLab和UNet模型中已经组合好的数据处理流程,开发者可以直接使用ComposedSegTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomHorizontalFlip](#RandomHorizontalFlip)、[ResizeStepScaling](#ResizeStepScaling)、[RandomPaddingCrop](#RandomPaddingCrop)3种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 +ComposedSegTransforms共包括以下几个步骤: + > 训练阶段: +> > 1. 随机对图像以0.5的概率水平翻转,若random_horizontal_flip为False,则跳过此步骤 +> > 2. 按不同的比例随机Resize原图, 处理方式参考[paddlex.seg.transforms.ResizeRangeScaling](#resizerangescaling)。若min_max_size为None,则跳过此步骤 +> > 3. 从原图中随机crop出大小为train_crop_size大小的子图,如若crop出来的图小于train_crop_size,则会将图padding到对应大小 +> > 4. 图像归一化 + > 预测阶段: +> > 1. 将图像的最长边resize至(min_max_size[0] + min_max_size[1])//2, 短边按比例resize。若min_max_size为None,则跳过此步骤 +> > 1. 图像归一化 + +### 参数 +* **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test' +* **min_max_size**(list): 用于对图像进行resize,具体作用参见上述步骤。 +* **train_crop_size** (list): 训练过程中随机裁剪原图用于训练,具体作用参见上述步骤。此参数仅在mode为`train`时生效。 +* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 +* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 +* **random_horizontal_flip**(bool): 数据增强,是否随机水平翻转图像,此参数仅在mode为`train`时生效。 + +### 添加数据增强方式 +```python +ComposedSegTransforms.add_augmenters(augmenters) +``` +> **参数** +> * **augmenters**(list): 数据增强方式列表 + +#### 使用示例 +``` +import paddlex as pdx +from paddlex.seg import transforms +train_transforms = transforms.ComposedSegTransforms(mode='train', train_crop_size=[512, 512]) +eval_transforms = transforms.ComposedSegTransforms(mode='eval') + +# 添加数据增强 +import imgaug.augmenters as iaa +train_transforms.add_augmenters([ + transforms.RandomDistort(), + iaa.blur.GaussianBlur(sigma=(0.0, 3.0)) +]) +``` +上面代码等价于 +``` +import paddlex as pdx +from paddlex.det import transforms +train_transforms = transforms.Composed([ + transforms.RandomDistort(), + iaa.blur.GaussianBlur(sigma=(0.0, 3.0)), + # 上面2行为通过add_augmenters额外添加的数据增强方式 + transforms.RandomHorizontalFlip(prob=0.5), + transforms.ResizeStepScaling(), + transforms.PaddingCrop(crop_size=[512, 512]), + transforms.Normalize() +]) +eval_transforms = transforms.Composed([ + transforms.Normalize() +]) +``` diff --git a/docs/apis/visualize.md b/docs/apis/visualize.md index 18872f52f0e371122568c8e3ec1545fd268a5323..eb4777a1e99f130c99ba4d11fd2542511a046b31 100755 --- a/docs/apis/visualize.md +++ b/docs/apis/visualize.md @@ -10,7 +10,7 @@ paddlex.det.visualize(image, result, threshold=0.5, save_dir='./') 将目标检测/实例分割模型预测得到的Box框和Mask在原图上进行可视化。 ### 参数 -> * **image** (str): 原图文件路径。 +> * **image** (str|np.ndarray): 原图文件路径或numpy数组(HWC排列,BGR格式)。 > * **result** (str): 模型预测结果。 > * **threshold**(float): score阈值,将Box置信度低于该阈值的框过滤不进行可视化。默认0.5 > * **save_dir**(str): 可视化结果保存路径。若为None,则表示不保存,该函数将可视化的结果以np.ndarray的形式返回;若设为目录路径,则将可视化结果保存至该目录下。默认值为'./'。 @@ -32,7 +32,7 @@ paddlex.seg.visualize(image, result, weight=0.6, save_dir='./') 将语义分割模型预测得到的Mask在原图上进行可视化。 ### 参数 -> * **image** (str): 原图文件路径。 +> * **image** (str|np.ndarray): 原图文件路径或numpy数组(HWC排列,BGR格式)。 > * **result** (str): 模型预测结果。 > * **weight**(float): mask可视化结果与原图权重因子,weight表示原图的权重。默认0.6。 > * **save_dir**(str): 可视化结果保存路径。若为None,则表示不保存,该函数将可视化的结果以np.ndarray的形式返回;若设为目录路径,则将可视化结果保存至该目录下。默认值为'./'。 diff --git a/docs/appendix/parameters.md b/docs/appendix/parameters.md index 716cdac92aa6504f1543cb91997f2f1fd89a3e13..408f2faf351f63f1474d4777d38c4ea9124fd12f 100644 --- a/docs/appendix/parameters.md +++ b/docs/appendix/parameters.md @@ -5,53 +5,69 @@ PaddleX所有训练接口中,内置的参数均为根据单GPU卡相应batch_s ## 1.Epoch数的调整 Epoch数是模型训练过程,迭代的轮数,用户可以设置较大的数值,根据模型迭代过程在验证集上的指标表现,来判断模型是否收敛,进而提前终止训练。此外也可以使用`train`接口中的`early_stop`策略,模型在训练过程会自动判断模型是否收敛自动中止。 -## 2.Batch Size的调整 -Batch Size指模型在训练过程中,一次性处理的样本数量, 如若使用多卡训练, batch_size会均分到各张卡上(因此需要让batch size整除卡数)。这个参数跟机器的显存/内存高度相关,`batch_size`越高,所消耗的显存/内存就越高。PaddleX在各个`train`接口中均配置了默认的batch size,如若用户调整batch size,则也注意需要对应调整其它参数,如下表所示展示YOLOv3在训练时的参数配置 +## 2.batch_size和learning_rate -| 参数 | 默认值 | 调整比例 | 示例 | -|:---------------- | :------------ | :------------------ | :------------ | -| train_batch_size | 8 | 调整为 8*alpha | 16 | -| learning_rate | 1.0/8000 | 调整为 alpha/8000 | 2.0/8000 | -| warmup_steps | 1000 | 调整为 1000/alpha
(该参数也可以自行根据数据情况调整) | 500 | -| lr_decay_epochs | [213, 240] | 不变 | [213, 240] | +> - Batch Size指模型在训练过程中,一次性处理的样本数量 +> - 如若使用多卡训练, batch_size会均分到各张卡上(因此需要让batch size整除卡数) +> - Batch Size跟机器的显存/内存高度相关,`batch_size`越高,所消耗的显存/内存就越高 +> - PaddleX在各个`train`接口中均配置了默认的batch size(默认针对单GPU卡),如若训练时提示GPU显存不足,则相应调低BatchSize,如若GPU显存高或使用多张GPU卡时,可相应调高BatchSize。 +> - **如若用户调整batch size,则也注意需要对应调整其它参数,特别是train接口中默认的learning_rate值**。如在YOLOv3模型中,默认`train_batch_size`为8,`learning_rate`为0.000125,当用户将模型在2卡机器上训练时,可以将`train_batch_size`调整为16, 那么同时`learning_rate`也可以对应调整为0.000125 * 2 = 0.00025 +## 3.warmup_steps和warmup_start_lr -更多训练接口可以参考 -- [分类模型-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/classification.html#train) -- [目标检测检测FasterRCNN-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/detection.html#id2) -- [目标检测YOLOv3-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/detection.html#train) -- [实例分割MaskRCNN-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/instance_segmentation.html#train) -- [语义分割DeepLabv3p-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#train) -- [语义分割UNet](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#id2) +在训练模型时,一般都会使用预训练模型,例如检测模型在训练时使用backbone在ImageNet数据集上的预训练权重。但由于在自行训练时,自己的数据与ImageNet数据集存在较大的差异,可能会一开始由于梯度过大使得训练出现问题,因此可以在刚开始训练时,让学习率以一个较小的值,慢慢增长到设定的学习率。因此`warmup_steps`和`warmup_start_lr`就是这个作用,模型开始训练时,学习率会从`warmup_start_lr`开始,在`warmup_steps`个batch数据迭代后线性增长到设定的学习率。 -## 关于lr_decay_epoch, warmup_steps等参数的说明 +> 例如YOLOv3的train接口,默认`train_batch_size`为8,`learning_rate`为0.000125, `warmup_steps`为1000, `warmup_start_lr`为0.0;在此参数配置下表示,模型在启动训练后,在前1000个step(每个step表示一个batch的数据,也就是8个样本)内,学习率会从0.0开始线性增长到设定的0.000125。 -在PaddleX或其它深度学习模型的训练过程中,经常见到lr_decay_epoch, warmup_steps, warmup_start_lr等参数设置,下面介绍一些这些参数的作用。 +## 4.lr_decay_epochs和lr_decay_gamma -首先这些参数都是用于控制模型训练过程中学习率的变化方式,例如我们在训练时将learning_rate设为0.1, 通常情况,在模型的训练过程中,学习率一直以0.1不变训练下去, 但为了调出更好的模型效果,我们往往不希望学习率一直保持不变。 +`lr_decay_epochs`用于让学习率在模型训练后期逐步衰减,它一般是一个list,如[6, 8, 10],表示学习率在第6个epoch时衰减一次,第8个epoch时再衰减一次,第10个epoch时再衰减一次。每次学习率衰减为之前的学习率*lr_decay_gamma。 -### warmup_steps和warmup_start_lr +> 例如YOLOv3的train接口,默认`num_epochs`为270,`learning_rate`为0.000125, `lr_decay_epochs`为[213, 240],`lr_decay_gamma`为0.1;在此参数配置下表示,模型在启动训练后,在前213个epoch中,训练时使用的学习率为0.000125,在第213至240个epoch之间,训练使用的学习率为0.000125*0.1,在240个epoch之后,使用的学习率为0.000125*0.1*0.1 -我们在训练模型时,一般都会使用预训练模型,例如检测模型在训练时使用backbone在ImageNet数据集上的预训练权重。但由于在自行训练时,自己的数据与ImageNet数据集存在较大的差异,可能会一开始由于梯度过大使得训练出现问题,因此可以在刚开始训练时,让学习率以一个较小的值,慢慢增长到设定的学习率。因此`warmup_steps`和`warmup_start_lr`就是这个作用,模型开始训练时,学习率会从`warmup_start_lr`开始,在`warmup_steps`内线性增长到设定的学习率。 +## 5.参数设定时的约束 +根据上述几个参数,可以了解到学习率的变化分为WarmUp热身阶段和Decay衰减阶段, +> - Wamup热身阶段:随着训练迭代,学习率从较低的值逐渐线性增长至设定的值,以step为单位 +> - Decay衰减阶段:随着训练迭代,学习率逐步衰减,如每次衰减为之前的0.1, 以epoch为单位 +> step与epoch的关系:1个epoch由多个step组成,例如训练样本有800张图像,`train_batch_size`为8, 那么每个epoch都要完整用这800张图片训一次模型,而每个epoch总共包含800//8即100个step -### lr_decay_epochs和lr_decay_gamma +在PaddleX中,约束warmup必须在Decay之前结束,因此各参数设置需要满足下面条件 +``` +warmup_steps <= lr_decay_epochs[0] * num_steps_each_epoch +``` +其中`num_steps_each_epoch`计算方式如下, +``` +num_steps_each_eposh = num_samples_in_train_dataset // train_batch_size +``` + +因此,如若你在启动训练时,被提示`warmup_steps should be less than...`时,即表示需要根据上述公式调整你的参数啦,可以调整`lr_decay_epochs`或者是`warmup_steps`。 -`lr_decay_epochs`用于让学习率在模型训练后期逐步衰减,它一般是一个list,如[6, 8, 10],表示学习率在第6个epoch时衰减一次,第8个epoch时再衰减一次,第10个epoch时再衰减一次。每次学习率衰减为之前的学习率*lr_decay_gamma +## 6.如何使用多GPU卡进行训练 +在`import paddlex`前配置环境变量,代码如下 +``` +import os +os.environ['CUDA_VISIBLE_DEVICES'] = '0' # 使用第1张GPU卡进行训练 +# 注意paddle或paddlex都需要在设置环境变量后再import +import paddlex as pdx +``` -### Notice +``` +import os +os.environ['CUDA_VISIBLE_DEVICES'] = '' # 不使用GPU,使用CPU进行训练 +import paddlex as pdx +``` -在PaddleX中,限制warmup需要在第一个学习率decay衰减前结束,因此要满足下面的公式 ``` -warmup_steps <= lr_decay_epochs[0] * num_steps_each_epoch +import os +os.environ['CUDA_VISIBLE_DEVICES'] = '0,1,3' # 使用第1、2、4张GPU卡进行训练 +import paddlex as pdx ``` -其中公式中`num_steps_each_epoch = num_samples_in_train_dataset // train_batch_size`。 -> 因此如若在训练时PaddleX提示`warmup_steps should be less than xxx`时,即可根据上述公式来调整你的`lr_decay_epochs`或者是`warmup_steps`使得两个参数满足上面的条件 -> - 图像分类模型 [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/classification.html#train) -> - FasterRCNN [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/detection.html#fasterrcnn) -> - YOLOv3 [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/detection.html#yolov3) -> - MaskRCNN [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/instance_segmentation.html#maskrcnn) -> - DeepLab [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#deeplabv3p) -> - UNet [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#unet) -> - HRNet [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#hrnet) +## 相关模型接口 + +- 图像分类模型 [train接口](../apis/models/classification.html#train) +- FasterRCNN [train接口](../apis/models/detection.html#id1) +- YOLOv3 [train接口](../apis/models/detection.html#train) +- MaskRCNN [train接口](../apis/models/instance_segmentation.html#train) +- DeepLabv3p [train接口](../apis/models/semantic_segmentation.html#train) diff --git a/docs/change_log.md b/docs/change_log.md index 25c0c75441c98ca3b141cc392a6c1dfeb38543ca..bc8bf5feda99761544232aaf348966e0c945b1db 100644 --- a/docs/change_log.md +++ b/docs/change_log.md @@ -1,12 +1,34 @@ # 更新日志 -## 2020.05.20 -### PaddleX v1.0.0发布 -- 新增XXX -- 新增XXX +**v1.1.0** 2020.07.10 -### PaddleX-GUI V1.0.0发布 -- 新增XXX -- 新增XXX +- 模型更新 +> - 新增语义分割模型HRNet、FastSCNN +> - 目标检测FasterRCNN、实例分割MaskRCNN新增backbone HRNet +> - 目标检测/实例分割模型新增COCO数据集预训练模型 +> - 集成X2Paddle,PaddleX所有分类模型和语义分割模型支持导出为ONNX协议 +- 模型部署更新 +> - 模型加密增加支持Windows平台 +> - 新增Jetson、PaddleLite模型部署预测方案 +> - C++部署代码新增batch批预测,并采用OpenMP对预处理进行并行加速 +- 新增2个PaddleX产业案例 +> - [人像分割案例]() +> - [工业表计读数案例]() +- 新增数据格式转换功能,LabelMe、精灵标注助手和EasyData平台标注的数据转为PaddleX支持加载的数据格式 +- PaddleX文档更新,优化文档结构 + +**v1.0.0** 2020.05.20 + +- 增加模型C++部署和Python部署代码 +- 增加模型加密部署方案 +- 增加分类模型的OpenVINO部署方案 +- 增加模型可解释性的接口 + + +**v0.1.8** 2020.05.17 + +- 修复部分代码Bug +- 新增EasyData平台数据标注格式支持 +- 支持imgaug数据增强库的pixel-level算子 diff --git a/docs/data/annotation.md b/docs/data/annotation.md index b5882ef619ef745068aea4f7b9210d9eaac597ce..646066545cd276cae5c1bf0b12af07edb56d8d49 100755 --- a/docs/data/annotation.md +++ b/docs/data/annotation.md @@ -10,11 +10,13 @@ PaddleX支持图像分类、目标检测、实例分割和语义分割四大视 | 标注工具 | 图像分类 | 目标检测 | 实例分割 | 语义分割 | 安装 | | :--------- | :------- | :------ | :------ | :------- | :----------------------------------------------- | | Labelme | - | √ | √ | √ | pip install labelme (本地数据标注) | -| 精灵标注 | √ | - | √ | √ | [官网下载](http://www.jinglingbiaozhu.com/) (本地数据标注) | +| 精灵标注 | √ | √* | √ | √ | [官网下载](http://www.jinglingbiaozhu.com/) (本地数据标注) | | EasyData | √ | √ | √ | √ | [Web页面标注](https://ai.baidu.com/easydata/) (需上传数据进行标注) | 数据标注完成后,参照如下流程,将标注数据转为可用PaddleX模型训练的数据组织格式。 +> *注*:精灵标注的目标检测数据可以在工具内部导出为PascalVOC格式,因此paddlex未提供精灵标注数据到PascalVOC格式的转换 + ## 标注数据格式转换 @@ -22,6 +24,9 @@ PaddleX支持图像分类、目标检测、实例分割和语义分割四大视 > 1. 将所有的原图文件放在同一个目录下,如`pics`目录 > 2. 将所有的标注json文件放在同一个目录下,如`annotations`目录 > 3. 使用如下命令进行转换 + +> *注*:精灵标注的目标检测数据可以在工具内部导出为PascalVOC格式,因此paddlex未提供精灵标注数据到PascalVOC格式的转换 + ``` paddlex --data_conversion --source labelme --to PascalVOC --pics ./pics --annotations ./annotations --save_dir ./converted_dataset_dir ``` @@ -29,4 +34,3 @@ paddlex --data_conversion --source labelme --to PascalVOC --pics ./pics --annota > `--to`表示数据需要转换成为的格式,支持`ImageNet`(图像分类)、`PascalVOC`(目标检测),`MSCOCO`(实例分割,也可用于目标检测)和`SEG`(语义分割) > `--pics`指定原图所在的目录路径 > `--annotations`指定标注文件所在的目录路径 -> 【备注】由于标注精灵可以标注PascalVOC格式的数据集,所以此处不再支持标注精灵到PascalVOC格式数据集的转换 diff --git a/docs/quick_start.md b/docs/quick_start.md index 5baa679bad17c61b315c21bb421bbbdd55a87bcf..8f4329b9b6194abc6c635660f0d3a2f7caf0ff57 100644 --- a/docs/quick_start.md +++ b/docs/quick_start.md @@ -25,19 +25,19 @@ tar xzvf vegetables_cls.tar.gz **3. 定义训练/验证图像处理流程transforms** -使用PaddleX内置的分类模型训练图像处理流程`ComposedClsTransforms`,点击查看[API文档说明](apis/transforms/classification.html#composedclstransforms)。`ComposedClsTransforms`内置`RandomHorizontalFlip`图像增强,用户也可通过`add_augmenters`函数,为训练过程添加更多数据增强操作,目前分类过程支持多程数据增强操作,详情查阅[数据增强文档](apis/transforms/data_augmentations.md) +由于训练时数据增强操作的加入,因此模型在训练和验证过程中,数据处理流程需要分别进行定义。如下所示,代码在`train_transforms`中加入了[RandomCrop](apis/transforms/cls_transforms.html#RandomCrop)和[RandomHorizontalFlip](apis/transforms/cls_transforms.html#RandomHorizontalFlip)两种数据增强方式, 更多方法可以参考[数据增强文档](apis/transforms/augment.md)。 ``` from paddlex.cls import transforms -train_transforms = transforms.ComposedClsTransforms( - mode='train', - crop_size=[224, 224]) -eval_transforms = transforms.ComposedClsTransforms( - mode='eval', - crop_size=[224, 224]) -``` -通过`add_augmenters`添加更多训练过程中的数据增强操作,例如 -``` -train_transforms.add_augmenters([transforms.RandomDistort()]) +train_transforms = transforms.Compose([ + transforms.RandomCrop(crop_size=224), + transforms.RandomHorizontalFlip(), + transforms.Normalize() +]) +eval_transforms = transforms.Compose([ + transforms.ResizeByShort(short_size=256), + transforms.CenterCrop(crop_size=224), + transforms.Normalize() +]) ``` diff --git a/docs/train/classification.md b/docs/train/classification.md index 6ed0a428afa73d5173542f5acc0f8748f41baf07..061894e1f87c116bc08f46319a8d666f7ddbc65c 100644 --- a/docs/train/classification.md +++ b/docs/train/classification.md @@ -6,18 +6,21 @@ PaddleX共提供了20+的图像分类模型,包括基于大规模数据训练 | 模型 | Top1精度 | 模型大小 | GPU预测速度 | Arm预测速度 | 备注 | | :---------------- | :------- | :------- | :--------- | :--------- | | -| ResNet50_vd_ssld | 97.5% | 22M | 10ms | 200ms | | -| ResNet101_vd_ssld | | | | | | | MobileNetV3_small_ssld | | | | | | -| MobileNetV3_large_ssld | | | | | | | MobileNetV2 | | | | | | | ShuffleNetV2 | | | | | | | AlexNet | | | | | | +| ResNet50_vd_ssld | 97.5% | 22M | 10ms | 200ms | | + +更多图像分类模型,可查阅PaddleX模型库和API使用文档。 + +在选取分类模型时,一般模型大小越大,表示模型的拟合能力越强,但并非越大训练效果越佳。需要用户根据自己的数据集来评估,一般数据样本较少时,MobileNetV3_small_ssld已经可以满足大部分需求。 + -将对应模型的训练代码保存到本地后,即可直接训练,训练代码会自动下载训练数据开始训练,如保存为`resnet50_vd_ssld.py`,如下命令即可开始训练 +点击上述表格模型名,将对应模型的训练代码保存到本地后,即可直接训练,训练代码会自动下载训练数据开始训练,如保存为`mobilenetv3_small_ssld.py`,如下命令即可开始训练 ``` -python resnet50_vd_ssld.py +python mobilenetv3_small_ssld.py ``` - 针对自己的机器环境和数据,调整训练参数?先了解下PaddleX中训练参数。[——>>传送门]() diff --git a/docs/train/prediction.md b/docs/train/prediction.md index 22a7dacabb87b0e8fe23b704bfe099e088c29608..9d08500f3480d4b430966bee34a238de353fbfdb 100644 --- a/docs/train/prediction.md +++ b/docs/train/prediction.md @@ -1,4 +1,4 @@ -# 模型预测可视化 +# 加载模型预测 PaddleX可以使用`load_model`接口加载模型(包括训练过程中保存的模型,导出的部署模型,量化模型以及裁剪的模型)进行预测,同时PaddleX中也内置了一系列的可视化工具函数,帮助用户方便地检查模型的效果。 diff --git a/paddlex/cv/transforms/seg_transforms.py b/paddlex/cv/transforms/seg_transforms.py index f2bfb32ebeed11f84c27ab7f1d8e8920f21699a7..7bffe8481a6df2ab7853693af4a7295e6c4fefb4 100644 --- a/paddlex/cv/transforms/seg_transforms.py +++ b/paddlex/cv/transforms/seg_transforms.py @@ -1102,20 +1102,21 @@ class ArrangeSegmenter(SegTransform): class ComposedSegTransforms(Compose): """ 语义分割模型(UNet/DeepLabv3p)的图像处理流程,具体如下 训练阶段: - 1. 随机对图像以0.5的概率水平翻转 - 2. 按不同的比例随机Resize原图 + 1. 随机对图像以0.5的概率水平翻转,若random_horizontal_flip为False,则跳过此步骤 + 2. 按不同的比例随机Resize原图, 处理方式参考[paddlex.seg.transforms.ResizeRangeScaling](#resizerangescaling)。若min_max_size为None,则跳过此步骤 3. 从原图中随机crop出大小为train_crop_size大小的子图,如若crop出来的图小于train_crop_size,则会将图padding到对应大小 4. 图像归一化 - 预测阶段: - 1. 图像归一化 + 预测阶段: + 1. 将图像的最长边resize至(min_max_size[0] + min_max_size[1])//2, 短边按比例resize。若min_max_size为None,则跳过此步骤 + 2. 图像归一化 Args: - mode(str): 图像处理所处阶段,训练/验证/预测,分别对应'train', 'eval', 'test' - min_max_size(list): 训练过程中,图像的最长边会随机resize至此区间(短边按比例相应resize);预测阶段,图像最长边会resize至此区间中间值,即(min_size+max_size)/2。默认为[400, 600] - train_crop_size(list): 仅在mode为'train`时生效,训练过程中,随机从图像中裁剪出对应大小的子图(如若原图小于此大小,则会padding到此大小),默认为[400, 600] - mean(list): 图像均值 - std(list): 图像方差 - random_horizontal_flip(bool): 数据增强方式,仅在mode为`train`时生效,表示训练过程是否随机水平翻转图像,默认为True + mode(str): Transforms所处的阶段,包括`train', 'eval'或'test' + min_max_size(list): 用于对图像进行resize,具体作用参见上述步骤。 + train_crop_size(list): 训练过程中随机裁剪原图用于训练,具体作用参见上述步骤。此参数仅在mode为`train`时生效。 + mean(list): 图像均值, 默认为[0.485, 0.456, 0.406]。 + std(list): 图像方差,默认为[0.229, 0.224, 0.225]。 + random_horizontal_flip(bool): 数据增强,是否随机水平翻转图像,此参数仅在mode为`train`时生效。 """ def __init__(self, @@ -1127,19 +1128,29 @@ class ComposedSegTransforms(Compose): random_horizontal_flip=True): if mode == 'train': # 训练时的transforms,包含数据增强 - transforms = [ - ResizeRangeScaling( - min_value=min(min_max_size), max_value=max(min_max_size)), - RandomPaddingCrop(crop_size=train_crop_size), Normalize( - mean=mean, std=std) - ] + if min_max_size is None: + transforms = [ + RandomPaddingCrop(crop_size=train_crop_size), Normalize( + mean=mean, std=std) + ] + else: + transforms = [ + ResizeRangeScaling( + min_value=min(min_max_size), + max_value=max(min_max_size)), + RandomPaddingCrop(crop_size=train_crop_size), Normalize( + mean=mean, std=std) + ] if random_horizontal_flip: transforms.insert(0, RandomHorizontalFlip()) else: # 验证/预测时的transforms - long_size = (min(min_max_size) + max(min_max_size)) // 2 - transforms = [ - ResizeByLong(long_size=long_size), Normalize( - mean=mean, std=std) - ] + if min_max_size is None: + transforms = [Normalize(mean=mean, std=std)] + else: + long_size = (min(min_max_size) + max(min_max_size)) // 2 + transforms = [ + ResizeByLong(long_size=long_size), Normalize( + mean=mean, std=std) + ] super(ComposedSegTransforms, self).__init__(transforms) diff --git a/tutorials/train/classification/resnet50.py b/tutorials/train/image_classification/alexnet.py similarity index 59% rename from tutorials/train/classification/resnet50.py rename to tutorials/train/image_classification/alexnet.py index 2e5a9b4820c7e66a83abaca0b13e057b15ceb830..fc4357c5eb61def3932b5489c9271fa5282035ea 100644 --- a/tutorials/train/classification/resnet50.py +++ b/tutorials/train/image_classification/alexnet.py @@ -1,8 +1,4 @@ import os -# 选择使用0号卡 -os.environ['CUDA_VISIBLE_DEVICES'] = '0' - -import paddle.fluid as fluid from paddlex.cls import transforms import paddlex as pdx @@ -11,13 +7,13 @@ veg_dataset = 'https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz' pdx.utils.download_and_decompress(veg_dataset, path='./') # 定义训练和验证时的transforms -train_transforms = transforms.Compose( - [transforms.RandomCrop(crop_size=224), - transforms.Normalize()]) +train_transforms = transforms.Compose([ + transforms.RandomCrop(crop_size=224), transforms.RandomHorizontalFlip(), + transforms.Normalize() +]) eval_transforms = transforms.Compose([ transforms.ResizeByShort(short_size=256), - transforms.CenterCrop(crop_size=224), - transforms.Normalize() + transforms.CenterCrop(crop_size=224), transforms.Normalize() ]) # 定义训练和验证所用的数据集 @@ -33,26 +29,20 @@ eval_dataset = pdx.datasets.ImageNet( label_list='vegetables_cls/labels.txt', transforms=eval_transforms) -# PaddleX支持自定义构建优化器 -step_each_epoch = train_dataset.num_samples // 32 -learning_rate = fluid.layers.cosine_decay( - learning_rate=0.025, step_each_epoch=step_each_epoch, epochs=10) -optimizer = fluid.optimizer.Momentum( - learning_rate=learning_rate, - momentum=0.9, - regularization=fluid.regularizer.L2Decay(4e-5)) - # 初始化模型,并进行训练 # 可使用VisualDL查看训练指标 -# VisualDL启动方式: visualdl --logdir output/resnet50/vdl_log --port 8001 +# VisualDL启动方式: visualdl --logdir output/mobilenetv2/vdl_log --port 8001 # 浏览器打开 https://0.0.0.0:8001即可 # 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP -model = pdx.cls.ResNet50(num_classes=len(train_dataset.labels)) +model = pdx.cls.AlexNet(num_classes=len(train_dataset.labels)) +# AlexNet需要指定确定的input_shape +model.fixed_input_shape = [224, 224] model.train( num_epochs=10, train_dataset=train_dataset, train_batch_size=32, eval_dataset=eval_dataset, - optimizer=optimizer, - save_dir='output/resnet50', + lr_decay_epochs=[4, 6, 8], + learning_rate=0.0025, + save_dir='output/alexnet', use_vdl=True) diff --git a/tutorials/train/classification/mobilenetv2.py b/tutorials/train/image_classification/mobilenetv2.py similarity index 87% rename from tutorials/train/classification/mobilenetv2.py rename to tutorials/train/image_classification/mobilenetv2.py index 3f637125b760de6d992d6a062e4d456bf5038426..bc30dfdaf93558842712ab863655639b6b99ddfb 100644 --- a/tutorials/train/classification/mobilenetv2.py +++ b/tutorials/train/image_classification/mobilenetv2.py @@ -1,7 +1,4 @@ import os -# 选择使用0号卡 -os.environ['CUDA_VISIBLE_DEVICES'] = '0' - from paddlex.cls import transforms import paddlex as pdx @@ -11,14 +8,12 @@ pdx.utils.download_and_decompress(veg_dataset, path='./') # 定义训练和验证时的transforms train_transforms = transforms.Compose([ - transforms.RandomCrop(crop_size=224), - transforms.RandomHorizontalFlip(), + transforms.RandomCrop(crop_size=224), transforms.RandomHorizontalFlip(), transforms.Normalize() ]) eval_transforms = transforms.Compose([ transforms.ResizeByShort(short_size=256), - transforms.CenterCrop(crop_size=224), - transforms.Normalize() + transforms.CenterCrop(crop_size=224), transforms.Normalize() ]) # 定义训练和验证所用的数据集 diff --git a/tutorials/train/image_classification/mobilenetv3_small_ssld.py b/tutorials/train/image_classification/mobilenetv3_small_ssld.py new file mode 100644 index 0000000000000000000000000000000000000000..b8e5e432b1169a76d1d2ba2206fac77aea074525 --- /dev/null +++ b/tutorials/train/image_classification/mobilenetv3_small_ssld.py @@ -0,0 +1,46 @@ +import os +from paddlex.cls import transforms +import paddlex as pdx + +# 下载和解压蔬菜分类数据集 +veg_dataset = 'https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz' +pdx.utils.download_and_decompress(veg_dataset, path='./') + +# 定义训练和验证时的transforms +train_transforms = transforms.Compose([ + transforms.RandomCrop(crop_size=224), transforms.RandomHorizontalFlip(), + transforms.Normalize() +]) +eval_transforms = transforms.Compose([ + transforms.ResizeByShort(short_size=256), + transforms.CenterCrop(crop_size=224), transforms.Normalize() +]) + +# 定义训练和验证所用的数据集 +train_dataset = pdx.datasets.ImageNet( + data_dir='vegetables_cls', + file_list='vegetables_cls/train_list.txt', + label_list='vegetables_cls/labels.txt', + transforms=train_transforms, + shuffle=True) +eval_dataset = pdx.datasets.ImageNet( + data_dir='vegetables_cls', + file_list='vegetables_cls/val_list.txt', + label_list='vegetables_cls/labels.txt', + transforms=eval_transforms) + +# 初始化模型,并进行训练 +# 可使用VisualDL查看训练指标 +# VisualDL启动方式: visualdl --logdir output/mobilenetv2/vdl_log --port 8001 +# 浏览器打开 https://0.0.0.0:8001即可 +# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP +model = pdx.cls.MobileNetV3_small_ssld(num_classes=len(train_dataset.labels)) +model.train( + num_epochs=10, + train_dataset=train_dataset, + train_batch_size=32, + eval_dataset=eval_dataset, + lr_decay_epochs=[4, 6, 8], + learning_rate=0.025, + save_dir='output/mobilenetv3_small_ssld', + use_vdl=True) diff --git a/tutorials/train/image_classification/resnet50_vd_ssld.py b/tutorials/train/image_classification/resnet50_vd_ssld.py new file mode 100644 index 0000000000000000000000000000000000000000..97a2e318426e97427a49d7a4d2f188153b98c0ce --- /dev/null +++ b/tutorials/train/image_classification/resnet50_vd_ssld.py @@ -0,0 +1,46 @@ +import os +from paddlex.cls import transforms +import paddlex as pdx + +# 下载和解压蔬菜分类数据集 +veg_dataset = 'https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz' +pdx.utils.download_and_decompress(veg_dataset, path='./') + +# 定义训练和验证时的transforms +train_transforms = transforms.Compose([ + transforms.RandomCrop(crop_size=224), transforms.RandomHorizontalFlip(), + transforms.Normalize() +]) +eval_transforms = transforms.Compose([ + transforms.ResizeByShort(short_size=256), + transforms.CenterCrop(crop_size=224), transforms.Normalize() +]) + +# 定义训练和验证所用的数据集 +train_dataset = pdx.datasets.ImageNet( + data_dir='vegetables_cls', + file_list='vegetables_cls/train_list.txt', + label_list='vegetables_cls/labels.txt', + transforms=train_transforms, + shuffle=True) +eval_dataset = pdx.datasets.ImageNet( + data_dir='vegetables_cls', + file_list='vegetables_cls/val_list.txt', + label_list='vegetables_cls/labels.txt', + transforms=eval_transforms) + +# 初始化模型,并进行训练 +# 可使用VisualDL查看训练指标 +# VisualDL启动方式: visualdl --logdir output/mobilenetv2/vdl_log --port 8001 +# 浏览器打开 https://0.0.0.0:8001即可 +# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP +model = pdx.cls.ResNet50_vd_ssld(num_classes=len(train_dataset.labels)) +model.train( + num_epochs=10, + train_dataset=train_dataset, + train_batch_size=32, + eval_dataset=eval_dataset, + lr_decay_epochs=[4, 6, 8], + learning_rate=0.025, + save_dir='output/resnet50_vd_ssld', + use_vdl=True) diff --git a/tutorials/train/image_classification/shufflenetv2.py b/tutorials/train/image_classification/shufflenetv2.py new file mode 100644 index 0000000000000000000000000000000000000000..244c43419607c78321c3c8243f2e67ca23d2e3d5 --- /dev/null +++ b/tutorials/train/image_classification/shufflenetv2.py @@ -0,0 +1,46 @@ +import os +from paddlex.cls import transforms +import paddlex as pdx + +# 下载和解压蔬菜分类数据集 +veg_dataset = 'https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz' +pdx.utils.download_and_decompress(veg_dataset, path='./') + +# 定义训练和验证时的transforms +train_transforms = transforms.Compose([ + transforms.RandomCrop(crop_size=224), transforms.RandomHorizontalFlip(), + transforms.Normalize() +]) +eval_transforms = transforms.Compose([ + transforms.ResizeByShort(short_size=256), + transforms.CenterCrop(crop_size=224), transforms.Normalize() +]) + +# 定义训练和验证所用的数据集 +train_dataset = pdx.datasets.ImageNet( + data_dir='vegetables_cls', + file_list='vegetables_cls/train_list.txt', + label_list='vegetables_cls/labels.txt', + transforms=train_transforms, + shuffle=True) +eval_dataset = pdx.datasets.ImageNet( + data_dir='vegetables_cls', + file_list='vegetables_cls/val_list.txt', + label_list='vegetables_cls/labels.txt', + transforms=eval_transforms) + +# 初始化模型,并进行训练 +# 可使用VisualDL查看训练指标 +# VisualDL启动方式: visualdl --logdir output/mobilenetv2/vdl_log --port 8001 +# 浏览器打开 https://0.0.0.0:8001即可 +# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP +model = pdx.cls.ShuffleNetV2(num_classes=len(train_dataset.labels)) +model.train( + num_epochs=10, + train_dataset=train_dataset, + train_batch_size=32, + eval_dataset=eval_dataset, + lr_decay_epochs=[4, 6, 8], + learning_rate=0.025, + save_dir='output/shufflenetv2', + use_vdl=True) diff --git a/tutorials/train/instance_segmentation/mask_rcnn_hrnet_fpn.py b/tutorials/train/instance_segmentation/mask_rcnn_hrnet_fpn.py new file mode 100644 index 0000000000000000000000000000000000000000..920c5f27298d49ad3a5ab7288a0ed7dc9f56d8d9 --- /dev/null +++ b/tutorials/train/instance_segmentation/mask_rcnn_hrnet_fpn.py @@ -0,0 +1,54 @@ +import os +# 选择使用0号卡 +os.environ['CUDA_VISIBLE_DEVICES'] = '0' + +from paddlex.det import transforms +import paddlex as pdx + +# 下载和解压小度熊分拣数据集 +xiaoduxiong_dataset = 'https://bj.bcebos.com/paddlex/datasets/xiaoduxiong_ins_det.tar.gz' +pdx.utils.download_and_decompress(xiaoduxiong_dataset, path='./') + +# 定义训练和验证时的transforms +train_transforms = transforms.Compose([ + transforms.RandomHorizontalFlip(), transforms.Normalize(), + transforms.ResizeByShort( + short_size=800, max_size=1333), transforms.Padding(coarsest_stride=32) +]) + +eval_transforms = transforms.Compose([ + transforms.Normalize(), + transforms.ResizeByShort( + short_size=800, max_size=1333), + transforms.Padding(coarsest_stride=32), +]) + +# 定义训练和验证所用的数据集 +train_dataset = pdx.datasets.CocoDetection( + data_dir='xiaoduxiong_ins_det/JPEGImages', + ann_file='xiaoduxiong_ins_det/train.json', + transforms=train_transforms, + shuffle=True) +eval_dataset = pdx.datasets.CocoDetection( + data_dir='xiaoduxiong_ins_det/JPEGImages', + ann_file='xiaoduxiong_ins_det/val.json', + transforms=eval_transforms) + +# 初始化模型,并进行训练 +# 可使用VisualDL查看训练指标 +# VisualDL启动方式: visualdl --logdir output/mask_rcnn_r50_fpn/vdl_log --port 8001 +# 浏览器打开 https://0.0.0.0:8001即可 +# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP +# num_classes 需要设置为包含背景类的类别数,即: 目标类别数量 + 1 +num_classes = len(train_dataset.labels) + 1 +model = pdx.det.MaskRCNN(num_classes=num_classes, backbone='HRNet_W18') +model.train( + num_epochs=12, + train_dataset=train_dataset, + train_batch_size=1, + eval_dataset=eval_dataset, + learning_rate=0.00125, + warmup_steps=10, + lr_decay_epochs=[8, 11], + save_dir='output/mask_rcnn_hrnet_fpn', + use_vdl=True) diff --git a/tutorials/train/detection/mask_rcnn_r50_fpn.py b/tutorials/train/instance_segmentation/mask_rcnn_r50_fpn.py similarity index 81% rename from tutorials/train/detection/mask_rcnn_r50_fpn.py rename to tutorials/train/instance_segmentation/mask_rcnn_r50_fpn.py index 15a6b840528fe7948c80f4cf605498cf55b5c918..bacbe615d0813040f9a34a70c0dcde31c86a54f9 100644 --- a/tutorials/train/detection/mask_rcnn_r50_fpn.py +++ b/tutorials/train/instance_segmentation/mask_rcnn_r50_fpn.py @@ -11,16 +11,16 @@ pdx.utils.download_and_decompress(xiaoduxiong_dataset, path='./') # 定义训练和验证时的transforms train_transforms = transforms.Compose([ - transforms.RandomHorizontalFlip(), - transforms.Normalize(), - transforms.ResizeByShort(short_size=800, max_size=1333), - transforms.Padding(coarsest_stride=32) + transforms.RandomHorizontalFlip(), transforms.Normalize(), + transforms.ResizeByShort( + short_size=800, max_size=1333), transforms.Padding(coarsest_stride=32) ]) eval_transforms = transforms.Compose([ transforms.Normalize(), - transforms.ResizeByShort(short_size=800, max_size=1333), - transforms.Padding(coarsest_stride=32) + transforms.ResizeByShort( + short_size=800, max_size=1333), + transforms.Padding(coarsest_stride=32), ]) # 定义训练和验证所用的数据集 @@ -41,7 +41,7 @@ eval_dataset = pdx.datasets.CocoDetection( # 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP # num_classes 需要设置为包含背景类的类别数,即: 目标类别数量 + 1 num_classes = len(train_dataset.labels) + 1 -model = pdx.det.MaskRCNN(num_classes=num_classes) +model = pdx.det.MaskRCNN(num_classes=num_classes, backbone='ResNet50_vd') model.train( num_epochs=12, train_dataset=train_dataset, diff --git a/tutorials/train/object_detection/faster_rcnn_hrnet_fpn.py b/tutorials/train/object_detection/faster_rcnn_hrnet_fpn.py new file mode 100644 index 0000000000000000000000000000000000000000..83f9b69c344981fa1de108a9ebe19d2cab5fb686 --- /dev/null +++ b/tutorials/train/object_detection/faster_rcnn_hrnet_fpn.py @@ -0,0 +1,55 @@ +import os +# 选择使用0号卡 +os.environ['CUDA_VISIBLE_DEVICES'] = '0' + +from paddlex.det import transforms +import paddlex as pdx + +# 下载和解压昆虫检测数据集 +insect_dataset = 'https://bj.bcebos.com/paddlex/datasets/insect_det.tar.gz' +pdx.utils.download_and_decompress(insect_dataset, path='./') + +# 定义训练和验证时的transforms +train_transforms = transforms.Compose([ + transforms.RandomHorizontalFlip(), transforms.Normalize(), + transforms.ResizeByShort( + short_size=800, max_size=1333), transforms.Padding(coarsest_stride=32) +]) + +eval_transforms = transforms.Compose([ + transforms.Normalize(), + transforms.ResizeByShort( + short_size=800, max_size=1333), + transforms.Padding(coarsest_stride=32), +]) + +# 定义训练和验证所用的数据集 +train_dataset = pdx.datasets.VOCDetection( + data_dir='insect_det', + file_list='insect_det/train_list.txt', + label_list='insect_det/labels.txt', + transforms=train_transforms, + shuffle=True) +eval_dataset = pdx.datasets.VOCDetection( + data_dir='insect_det', + file_list='insect_det/val_list.txt', + label_list='insect_det/labels.txt', + transforms=eval_transforms) + +# 初始化模型,并进行训练 +# 可使用VisualDL查看训练指标 +# VisualDL启动方式: visualdl --logdir output/faster_rcnn_r50_fpn/vdl_log --port 8001 +# 浏览器打开 https://0.0.0.0:8001即可 +# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP +# num_classes 需要设置为包含背景类的类别数,即: 目标类别数量 + 1 +num_classes = len(train_dataset.labels) + 1 +model = pdx.det.FasterRCNN(num_classes=num_classes, backbone='HRNet_W18') +model.train( + num_epochs=12, + train_dataset=train_dataset, + train_batch_size=2, + eval_dataset=eval_dataset, + learning_rate=0.0025, + lr_decay_epochs=[8, 11], + save_dir='output/faster_rcnn_hrnet_fpn', + use_vdl=True) diff --git a/tutorials/train/detection/faster_rcnn_r50_fpn.py b/tutorials/train/object_detection/faster_rcnn_r50_fpn.py similarity index 81% rename from tutorials/train/detection/faster_rcnn_r50_fpn.py rename to tutorials/train/object_detection/faster_rcnn_r50_fpn.py index cbe6dabe535b5972418349ac31576b344652e69d..6c7987a74f8216b4a448624096aceb0a7db522f8 100644 --- a/tutorials/train/detection/faster_rcnn_r50_fpn.py +++ b/tutorials/train/object_detection/faster_rcnn_r50_fpn.py @@ -1,7 +1,4 @@ import os -# 选择使用0号卡 -os.environ['CUDA_VISIBLE_DEVICES'] = '0' - from paddlex.det import transforms import paddlex as pdx @@ -11,18 +8,17 @@ pdx.utils.download_and_decompress(insect_dataset, path='./') # 定义训练和验证时的transforms train_transforms = transforms.Compose([ - transforms.RandomHorizontalFlip(), - transforms.Normalize(), - transforms.ResizeByShort(short_size=800, max_size=1333), - transforms.Padding(coarsest_stride=32) + transforms.RandomHorizontalFlip(), transforms.Normalize(), + transforms.ResizeByShort( + short_size=800, max_size=1333), transforms.Padding(coarsest_stride=32) ]) eval_transforms = transforms.Compose([ transforms.Normalize(), - transforms.ResizeByShort(short_size=800, max_size=1333), + transforms.ResizeByShort( + short_size=800, max_size=1333), transforms.Padding(coarsest_stride=32), ]) - # 定义训练和验证所用的数据集 train_dataset = pdx.datasets.VOCDetection( data_dir='insect_det', @@ -43,7 +39,7 @@ eval_dataset = pdx.datasets.VOCDetection( # 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP # num_classes 需要设置为包含背景类的类别数,即: 目标类别数量 + 1 num_classes = len(train_dataset.labels) + 1 -model = pdx.det.FasterRCNN(num_classes=num_classes) +model = pdx.det.FasterRCNN(num_classes=num_classes, backbone='ResNet50_vd') model.train( num_epochs=12, train_dataset=train_dataset, diff --git a/tutorials/train/detection/yolov3_darknet53.py b/tutorials/train/object_detection/yolov3_darknet53.py similarity index 90% rename from tutorials/train/detection/yolov3_darknet53.py rename to tutorials/train/object_detection/yolov3_darknet53.py index c38656b04e9a35cd033dc583811c58aa8baafba2..facb3e558b422ac5c73db275eec9efc62de34054 100644 --- a/tutorials/train/detection/yolov3_darknet53.py +++ b/tutorials/train/object_detection/yolov3_darknet53.py @@ -1,7 +1,4 @@ import os -# 选择使用0号卡 -os.environ['CUDA_VISIBLE_DEVICES'] = '0' - from paddlex.det import transforms import paddlex as pdx @@ -15,13 +12,15 @@ train_transforms = transforms.Compose([ transforms.RandomDistort(), transforms.RandomExpand(), transforms.RandomCrop(), - transforms.Resize(target_size=608, interp='RANDOM'), + transforms.Resize( + target_size=608, interp='RANDOM'), transforms.RandomHorizontalFlip(), transforms.Normalize(), ]) eval_transforms = transforms.Compose([ - transforms.Resize(target_size=608, interp='CUBIC'), + transforms.Resize( + target_size=608, interp='CUBIC'), transforms.Normalize(), ]) diff --git a/tutorials/train/object_detection/yolov3_mobilenetv1.py b/tutorials/train/object_detection/yolov3_mobilenetv1.py new file mode 100644 index 0000000000000000000000000000000000000000..c74572640bc0ceb0f0fcf45180bbdc7a038a317d --- /dev/null +++ b/tutorials/train/object_detection/yolov3_mobilenetv1.py @@ -0,0 +1,55 @@ +import os +from paddlex.det import transforms +import paddlex as pdx + +# 下载和解压昆虫检测数据集 +insect_dataset = 'https://bj.bcebos.com/paddlex/datasets/insect_det.tar.gz' +pdx.utils.download_and_decompress(insect_dataset, path='./') + +# 定义训练和验证时的transforms +train_transforms = transforms.Compose([ + transforms.MixupImage(mixup_epoch=250), + transforms.RandomDistort(), + transforms.RandomExpand(), + transforms.RandomCrop(), + transforms.Resize( + target_size=608, interp='RANDOM'), + transforms.RandomHorizontalFlip(), + transforms.Normalize(), +]) + +eval_transforms = transforms.Compose([ + transforms.Resize( + target_size=608, interp='CUBIC'), + transforms.Normalize(), +]) + +# 定义训练和验证所用的数据集 +train_dataset = pdx.datasets.VOCDetection( + data_dir='insect_det', + file_list='insect_det/train_list.txt', + label_list='insect_det/labels.txt', + transforms=train_transforms, + shuffle=True) +eval_dataset = pdx.datasets.VOCDetection( + data_dir='insect_det', + file_list='insect_det/val_list.txt', + label_list='insect_det/labels.txt', + transforms=eval_transforms) + +# 初始化模型,并进行训练 +# 可使用VisualDL查看训练指标 +# VisualDL启动方式: visualdl --logdir output/yolov3_darknet/vdl_log --port 8001 +# 浏览器打开 https://0.0.0.0:8001即可 +# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP +num_classes = len(train_dataset.labels) +model = pdx.det.YOLOv3(num_classes=num_classes, backbone='MobileNetV1') +model.train( + num_epochs=270, + train_dataset=train_dataset, + train_batch_size=8, + eval_dataset=eval_dataset, + learning_rate=0.000125, + lr_decay_epochs=[210, 240], + save_dir='output/yolov3_mobilenetv1', + use_vdl=True) diff --git a/tutorials/train/object_detection/yolov3_mobilenetv3.py b/tutorials/train/object_detection/yolov3_mobilenetv3.py new file mode 100644 index 0000000000000000000000000000000000000000..3fab5255b9f3a1a8ce537fa5b202916b147f380e --- /dev/null +++ b/tutorials/train/object_detection/yolov3_mobilenetv3.py @@ -0,0 +1,55 @@ +import os +from paddlex.det import transforms +import paddlex as pdx + +# 下载和解压昆虫检测数据集 +insect_dataset = 'https://bj.bcebos.com/paddlex/datasets/insect_det.tar.gz' +pdx.utils.download_and_decompress(insect_dataset, path='./') + +# 定义训练和验证时的transforms +train_transforms = transforms.Compose([ + transforms.MixupImage(mixup_epoch=250), + transforms.RandomDistort(), + transforms.RandomExpand(), + transforms.RandomCrop(), + transforms.Resize( + target_size=608, interp='RANDOM'), + transforms.RandomHorizontalFlip(), + transforms.Normalize(), +]) + +eval_transforms = transforms.Compose([ + transforms.Resize( + target_size=608, interp='CUBIC'), + transforms.Normalize(), +]) + +# 定义训练和验证所用的数据集 +train_dataset = pdx.datasets.VOCDetection( + data_dir='insect_det', + file_list='insect_det/train_list.txt', + label_list='insect_det/labels.txt', + transforms=train_transforms, + shuffle=True) +eval_dataset = pdx.datasets.VOCDetection( + data_dir='insect_det', + file_list='insect_det/val_list.txt', + label_list='insect_det/labels.txt', + transforms=eval_transforms) + +# 初始化模型,并进行训练 +# 可使用VisualDL查看训练指标 +# VisualDL启动方式: visualdl --logdir output/yolov3_darknet/vdl_log --port 8001 +# 浏览器打开 https://0.0.0.0:8001即可 +# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP +num_classes = len(train_dataset.labels) +model = pdx.det.YOLOv3(num_classes=num_classes, backbone='MobileNetV3_large') +model.train( + num_epochs=270, + train_dataset=train_dataset, + train_batch_size=8, + eval_dataset=eval_dataset, + learning_rate=0.000125, + lr_decay_epochs=[210, 240], + save_dir='output/yolov3_mobilenetv3', + use_vdl=True) diff --git a/tutorials/train/segmentation/deeplabv3p.py b/tutorials/train/semantic_segmentation/deeplabv3p_mobilenetv2.py similarity index 81% rename from tutorials/train/segmentation/deeplabv3p.py rename to tutorials/train/semantic_segmentation/deeplabv3p_mobilenetv2.py index 346a229a358a76830112acfd596740c070822874..9e3a7d5d438373d4d58c0301ab9329847b450980 100644 --- a/tutorials/train/segmentation/deeplabv3p.py +++ b/tutorials/train/semantic_segmentation/deeplabv3p_mobilenetv2.py @@ -11,14 +11,14 @@ pdx.utils.download_and_decompress(optic_dataset, path='./') # 定义训练和验证时的transforms train_transforms = transforms.Compose([ - transforms.RandomHorizontalFlip(), - transforms.Resize(target_size=512), - transforms.RandomPaddingCrop(crop_size=500), - transforms.Normalize() + transforms.RandomHorizontalFlip(), transforms.ResizeRangeScaling(), + transforms.RandomPaddingCrop(crop_size=512), transforms.Normalize() ]) -eval_transforms = transforms.Compose( - [transforms.Resize(512), transforms.Normalize()]) +eval_transforms = transforms.Compose([ + transforms.ResizeByLong(long_size=512), transforms.Padding(target_size=512), + transforms.Normalize() +]) # 定义训练和验证所用的数据集 train_dataset = pdx.datasets.SegDataset( @@ -46,5 +46,5 @@ model.train( train_batch_size=4, eval_dataset=eval_dataset, learning_rate=0.01, - save_dir='output/deeplab', + save_dir='output/deeplabv3p_mobilenetv2', use_vdl=True) diff --git a/tutorials/train/segmentation/fast_scnn.py b/tutorials/train/semantic_segmentation/fast_scnn.py similarity index 83% rename from tutorials/train/segmentation/fast_scnn.py rename to tutorials/train/semantic_segmentation/fast_scnn.py index 9c48d31eda7b612243e65df124b51722c4ea59e4..a2fdfa40dd94e145c6142b215908e731ec40d3c3 100644 --- a/tutorials/train/segmentation/fast_scnn.py +++ b/tutorials/train/semantic_segmentation/fast_scnn.py @@ -11,9 +11,15 @@ pdx.utils.download_and_decompress(optic_dataset, path='./') # 定义训练和验证时的transforms # API说明: https://paddlex.readthedocs.io/zh_CN/latest/apis/transforms/seg_transforms.html#composedsegtransforms -train_transforms = transforms.ComposedSegTransforms( - mode='train', train_crop_size=[769, 769]) -eval_transforms = transforms.ComposedSegTransforms(mode='eval') +train_transforms = transforms.Compose([ + transforms.RandomHorizontalFlip(), transforms.ResizeRangeScaling(), + transforms.RandomPaddingCrop(crop_size=512), transforms.Normalize() +]) + +eval_transforms = transforms.Compose([ + transforms.ResizeByLong(long_size=512), transforms.Padding(target_size=512), + transforms.Normalize() +]) # 定义训练和验证所用的数据集 # API说明: https://paddlex.readthedocs.io/zh_CN/latest/apis/datasets/semantic_segmentation.html#segdataset diff --git a/tutorials/train/segmentation/hrnet.py b/tutorials/train/semantic_segmentation/hrnet.py similarity index 93% rename from tutorials/train/segmentation/hrnet.py rename to tutorials/train/semantic_segmentation/hrnet.py index f887b78c3ae16ae66235f1965ada8bd2355d62c6..682ce82da4495c80cf504d17477d9ef9e750b963 100644 --- a/tutorials/train/segmentation/hrnet.py +++ b/tutorials/train/semantic_segmentation/hrnet.py @@ -16,8 +16,8 @@ train_transforms = transforms.Compose([ ]) eval_transforms = transforms.Compose([ - transforms.ResizeByLong(long_size=512), - transforms.Padding(target_size=512), transforms.Normalize() + transforms.ResizeByLong(long_size=512), transforms.Padding(target_size=512), + transforms.Normalize() ]) # 定义训练和验证所用的数据集 diff --git a/tutorials/train/segmentation/unet.py b/tutorials/train/semantic_segmentation/unet.py similarity index 86% rename from tutorials/train/segmentation/unet.py rename to tutorials/train/semantic_segmentation/unet.py index a683af98322eacb9d0775b3a5256d900f5743bb2..327a6ce648c14604fe2861be20af23c4d59089e9 100644 --- a/tutorials/train/segmentation/unet.py +++ b/tutorials/train/semantic_segmentation/unet.py @@ -11,15 +11,12 @@ pdx.utils.download_and_decompress(optic_dataset, path='./') # 定义训练和验证时的transforms train_transforms = transforms.Compose([ - transforms.RandomHorizontalFlip(), - transforms.ResizeRangeScaling(), - transforms.RandomPaddingCrop(crop_size=512), - transforms.Normalize() + transforms.RandomHorizontalFlip(), transforms.ResizeRangeScaling(), + transforms.RandomPaddingCrop(crop_size=512), transforms.Normalize() ]) eval_transforms = transforms.Compose([ - transforms.ResizeByLong(long_size=512), - transforms.Padding(target_size=512), + transforms.ResizeByLong(long_size=512), transforms.Padding(target_size=512), transforms.Normalize() ])