提交 421266a7 编写于 作者: J jiangjiajun

add BasicTransforms

上级 7acf4f36
...@@ -23,6 +23,7 @@ import random ...@@ -23,6 +23,7 @@ import random
import platform import platform
import chardet import chardet
import paddlex.utils.logging as logging import paddlex.utils.logging as logging
from paddlex.cv.transforms.template import TemplateTransforms
class EndSignal(): class EndSignal():
...@@ -209,8 +210,8 @@ def GenerateMiniBatch(batch_data): ...@@ -209,8 +210,8 @@ def GenerateMiniBatch(batch_data):
padding_batch = [] padding_batch = []
for data in batch_data: for data in batch_data:
im_c, im_h, im_w = data[0].shape[:] im_c, im_h, im_w = data[0].shape[:]
padding_im = np.zeros((im_c, max_shape[1], max_shape[2]), padding_im = np.zeros(
dtype=np.float32) (im_c, max_shape[1], max_shape[2]), dtype=np.float32)
padding_im[:, :im_h, :im_w] = data[0] padding_im[:, :im_h, :im_w] = data[0]
padding_batch.append((padding_im, ) + data[1:]) padding_batch.append((padding_im, ) + data[1:])
return padding_batch return padding_batch
...@@ -226,12 +227,14 @@ class Dataset: ...@@ -226,12 +227,14 @@ class Dataset:
if num_workers == 'auto': if num_workers == 'auto':
import multiprocessing as mp import multiprocessing as mp
num_workers = mp.cpu_count() // 2 if mp.cpu_count() // 2 < 8 else 8 num_workers = mp.cpu_count() // 2 if mp.cpu_count() // 2 < 8 else 8
if platform.platform().startswith( if platform.platform().startswith("Darwin") or platform.platform(
"Darwin") or platform.platform().startswith("Windows"): ).startswith("Windows"):
parallel_method = 'thread' parallel_method = 'thread'
if transforms is None: if transforms is None:
raise Exception("transform should be defined.") raise Exception("transform should be defined.")
self.transforms = transforms self.transforms = transforms
if isinstance(transforms, TemplateTransforms):
self.transforms = transforms.transforms
self.num_workers = num_workers self.num_workers = num_workers
self.buffer_size = buffer_size self.buffer_size = buffer_size
self.parallel_method = parallel_method self.parallel_method = parallel_method
......
...@@ -15,3 +15,4 @@ ...@@ -15,3 +15,4 @@
from . import cls_transforms from . import cls_transforms
from . import det_transforms from . import det_transforms
from . import seg_transforms from . import seg_transforms
from . import template
...@@ -18,6 +18,7 @@ import random ...@@ -18,6 +18,7 @@ import random
import os.path as osp import os.path as osp
import numpy as np import numpy as np
from PIL import Image, ImageEnhance from PIL import Image, ImageEnhance
from .template import TemplateTransforms
class ClsTransform: class ClsTransform:
...@@ -461,3 +462,55 @@ class ArrangeClassifier(ClsTransform): ...@@ -461,3 +462,55 @@ class ArrangeClassifier(ClsTransform):
else: else:
outputs = (im, ) outputs = (im, )
return outputs return outputs
class BasicClsTransforms(TemplateTransforms):
""" 分类模型的基础Transforms流程,具体如下
训练阶段:
1. 随机从图像中crop一块子图,并resize成crop_size大小
2. 将1的输出按0.5的概率随机进行水平翻转
3. 将图像进行归一化
验证/预测阶段:
1. 将图像按比例Resize,使得最小边长度为crop_size[0] * 1.14
2. 从图像中心crop出一个大小为crop_size的图像
3. 将图像进行归一化
Args:
mode(str): 图像处理流程所处阶段,训练/验证/预测,分别对应'train', 'eval', 'test'
crop_size(int|list): 输入模型里的图像大小
mean(list): 图像均值
std(list): 图像方差
"""
def __init__(self,
mode,
crop_size=[224, 224],
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]):
super(TemplateClsTransforms, self).__init__(mode=mode)
width = crop_size
if isinstance(crop_size, list):
if shape[0] != shape[1]:
raise Exception(
"In classifier model, width and height should be equal")
width = crop_size[0]
if width % 32 != 0:
raise Exception(
"In classifier model, width and height should be multiple of 32, e.g 224、256、320...."
)
if self.mode == 'train':
# 训练时的transforms,包含数据增强
self.transforms = transforms.Compose([
transforms.RandomCrop(crop_size=width),
transforms.RandomHorizontalFlip(prob=0.5),
transforms.Normalize(
mean=mean, std=std)
])
else:
# 验证/预测时的transforms
self.transforms = transforms.Compose([
transforms.ReiszeByShort(short_size=int(width * 1.14)),
transforms.CenterCrop(crop_size=width), transforms.Normalize(
mean=mean, std=std)
])
...@@ -27,6 +27,7 @@ from PIL import Image, ImageEnhance ...@@ -27,6 +27,7 @@ from PIL import Image, ImageEnhance
from .imgaug_support import execute_imgaug from .imgaug_support import execute_imgaug
from .ops import * from .ops import *
from .box_utils import * from .box_utils import *
from .template import TemplateTransforms
class DetTransform: class DetTransform:
...@@ -1227,3 +1228,109 @@ class ArrangeYOLOv3(DetTransform): ...@@ -1227,3 +1228,109 @@ class ArrangeYOLOv3(DetTransform):
im_shape = im_info['image_shape'] im_shape = im_info['image_shape']
outputs = (im, im_shape) outputs = (im, im_shape)
return outputs return outputs
class BasicRCNNTransforms(TemplateTransforms):
""" RCNN模型(faster-rcnn/mask-rcnn)图像处理流程,具体如下,
训练阶段:
1. 随机以0.5的概率将图像水平翻转
2. 图像归一化
3. 图像按比例Resize,scale计算方式如下
scale = min_max_size[0] / short_size_of_image
if max_size_of_image * scale > min_max_size[1]:
scale = min_max_size[1] / max_size_of_image
4. 将3步骤的长宽进行padding,使得长宽为32的倍数
验证阶段:
1. 图像归一化
2. 图像按比例Resize,scale计算方式同上训练阶段
3. 将2步骤的长宽进行padding,使得长宽为32的倍数
Args:
mode(str): 图像处理流程所处阶段,训练/验证/预测,分别对应'train', 'eval', 'test'
min_max_size(list): 图像在缩放时,最小边和最大边的约束条件
mean(list): 图像均值
std(list): 图像方差
"""
def __init__(self,
mode,
min_max_size=[800, 1333],
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]):
super(RCNNTransforms, self).__init__(mode=mode)
if self.mode == 'train':
# 训练时的transforms,包含数据增强
self.transforms = transforms.Compose([
transforms.RandomHorizontalFlip(prob=0.5),
transforms.Normalize(
mean=mean, std=std), transforms.ResizeByShort(
short_size=min_max_size[0], max_size=min_max_size[1]),
transforms.Padding(coarsest_stride=32)
])
else:
# 验证/预测时的transforms
self.transforms = transforms.Compose([
transforms.Normalize(
mean=mean, std=std), transforms.ResizeByShort(
short_size=min_max_size[0], max_size=min_max_size[1]),
transforms.Padding(coarsest_stride=32)
])
class BasicYOLOTransforms(TemplateTransforms):
"""YOLOv3模型的图像预处理流程,具体如下,
训练阶段:
1. 在前mixup_epoch轮迭代中,使用MixupImage策略,见https://paddlex.readthedocs.io/zh_CN/latest/apis/transforms/det_transforms.html#mixupimage
2. 对图像进行随机扰动,包括亮度,对比度,饱和度和色调
3. 随机扩充图像,见https://paddlex.readthedocs.io/zh_CN/latest/apis/transforms/det_transforms.html#randomexpand
4. 随机裁剪图像
5. 将4步骤的输出图像Resize成shape参数的大小
6. 随机0.5的概率水平翻转图像
7. 图像归一化
验证/预测阶段:
1. 将图像Resize成shape参数大小
2. 图像归一化
Args:
mode(str): 图像处理流程所处阶段,训练/验证/预测,分别对应'train', 'eval', 'test'
shape(list): 输入模型中图像的大小,输入模型的图像会被Resize成此大小
mixup_epoch(int): 模型训练过程中,前mixup_epoch会使用mixup策略
mean(list): 图像均值
std(list): 图像方差
"""
def __init__(self,
mode,
shape=[608, 608],
mixup_epoch=250,
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]):
super(YOLOTransforms, self).__init__(mode=mode)
width = shape
if isinstance(shape, list):
if shape[0] != shape[1]:
raise Exception(
"In YOLOv3 model, width and height should be equal")
width = shape[0]
if width % 32 != 0:
raise Exception(
"In YOLOv3 model, width and height should be multiple of 32, e.g 224、256、320...."
)
if self.mode == 'train':
# 训练时的transforms,包含数据增强
self.transforms = transforms.Compose([
transforms.MixupImage(mixup_epoch=mixup_epoch),
transforms.RandomDistort(), transforms.RandomExpand(),
transforms.RandomCrop(), transforms.Resize(
target_size=width, interp='RANDOM'),
transforms.RandomHorizontalFlip(), transforms.Normalize(
mean=mean, std=std)
])
else:
# 验证/预测时的transforms
self.transforms = transforms.Compose([
transforms.Resize(
target_size=width, interp='CUBIC'), transforms.Normalize(
mean=mean, std=std)
])
...@@ -21,6 +21,7 @@ import numpy as np ...@@ -21,6 +21,7 @@ import numpy as np
from PIL import Image from PIL import Image
import cv2 import cv2
from collections import OrderedDict from collections import OrderedDict
from .template import TemplateTransforms
class SegTransform: class SegTransform:
...@@ -1088,3 +1089,42 @@ class ArrangeSegmenter(SegTransform): ...@@ -1088,3 +1089,42 @@ class ArrangeSegmenter(SegTransform):
return (im, im_info) return (im, im_info)
else: else:
return (im, ) return (im, )
class BasicSegTransforms(TemplateTransforms):
""" 语义分割模型(UNet/DeepLabv3p)的图像处理流程,具体如下
训练阶段:
1. 随机对图像以0.5的概率水平翻转
2. 按不同的比例随机Resize原图
3. 从原图中随机crop出大小为train_crop_size大小的子图,如若crop出来的图小于train_crop_size,则会将图padding到对应大小
4. 图像归一化
预测阶段:
1. 图像归一化
Args:
mode(str): 图像处理所处阶段,训练/验证/预测,分别对应'train', 'eval', 'test'
train_crop_size(list): 模型训练阶段,随机从原图crop的大小
mean(list): 图像均值
std(list): 图像方差
"""
def __init__(self,
mode,
train_crop_size=[769, 769],
mean=[0.5, 0.5, 0.5],
std=[0.5, 0.5, 0.5]):
super(TemplateSegTransforms, self).__init__(mode=mode)
if self.mode == 'train':
# 训练时的transforms,包含数据增强
self.transforms = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.ResizeStepScaling(),
transforms.RandomPaddingCrop(crop_size=train_crop_size),
transforms.Normalize(
mean=mean, std=std)
])
else:
# 验证/预测时的transforms
self.transforms = transforms.Compose(
[transforms.Normalize(
mean=mean, std=std)])
# copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# 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.
class TemplateTransforms:
def __init__(self, mode):
assert mode in [
'train', 'eval', 'test'
], "Parameter mode in TemplateTransforms should be one of ['train', 'eval', 'test']"
self.mode = mode
def add_augmenters(self, augmenters):
if not isinstance(augmenters, list):
raise Exception(
"augmenters should be list type in func add_augmenters()")
assert mode == 'train', "There should be exists augmenters while on train mode"
self.transforms = augmenters + self.transforms.transforms
...@@ -97,8 +97,6 @@ class Predictor: ...@@ -97,8 +97,6 @@ class Predictor:
config.disable_glog_info() config.disable_glog_info()
if memory_optimize: if memory_optimize:
config.enable_memory_optim() config.enable_memory_optim()
else:
config.diable_memory_optim()
# 开启计算图分析优化,包括OP融合等 # 开启计算图分析优化,包括OP融合等
config.switch_ir_optim(True) config.switch_ir_optim(True)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册