PaddlePaddle / PaddleX

All-in-One Development Tool based on PaddlePaddle(飞桨低代码开发工具)
Apache License 2.0
4.9k stars 958 forks source link

如何使用开源图像分割数据集训练自己的抠图模型 #368

Open yanchaoguo opened 4 years ago

yanchaoguo commented 4 years ago

我在对模型进行图像分隔训练时报如下错误: File "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddlex/cv/transforms/imgaug_support.py", line 26, in execute_imgaug aug_im = augmenter.augment(image=aug_im).astype('float32') AttributeError: 'ArrangeSegmenter' object has no attribute 'augment'

代码: model = pdx.seg.FastSCNN(num_classes=num_classes)

model.train( num_epochs=12, train_dataset=train_dataset, train_batch_size=1, eval_dataset=eval_dataset, learning_rate=0.00125, save_interval_epochs=1, save_dir= 'data/rcnn', pretrain_weights='NONE' )

jiangjiajun commented 4 years ago

你好,麻烦贴一下你的transforms定义的代码部分, 我这边测试如下代码,可以正常训练(imgaug v0.4.0)

import paddlex as pdx
from paddlex.seg import transforms

optic_dataset = 'https://bj.bcebos.com/paddlex/datasets/optic_disc_seg.tar.gz'
pdx.utils.download_and_decompress(optic_dataset, path='./')

import imgaug.augmenters as iaa
train_transforms = transforms.Compose([
    iaa.blur.GaussianBlur(sigma=(0.0, 3.0)),
    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()
])

train_dataset = pdx.datasets.SegDataset(
    data_dir='optic_disc_seg',
    file_list='optic_disc_seg/train_list.txt',
    label_list='optic_disc_seg/labels.txt',
    transforms=train_transforms,
    shuffle=True)
eval_dataset = pdx.datasets.SegDataset(
    data_dir='optic_disc_seg',
    file_list='optic_disc_seg/val_list.txt',
    label_list='optic_disc_seg/labels.txt',
    transforms=eval_transforms)

num_classes = len(train_dataset.labels)
model = pdx.seg.FastSCNN(num_classes=num_classes)
model.train(
    num_epochs=20,
    train_dataset=train_dataset,
    train_batch_size=4,
    eval_dataset=eval_dataset,
    learning_rate=0.01,
    save_dir='output/fastscnn',
    use_vdl=True)
yanchaoguo commented 4 years ago

你好,麻烦贴一下你的transforms定义的代码部分, 我这边测试如下代码,可以正常训练(imgaug v0.4.0)

import paddlex as pdx
from paddlex.seg import transforms

optic_dataset = 'https://bj.bcebos.com/paddlex/datasets/optic_disc_seg.tar.gz'
pdx.utils.download_and_decompress(optic_dataset, path='./')

import imgaug.augmenters as iaa
train_transforms = transforms.Compose([
    iaa.blur.GaussianBlur(sigma=(0.0, 3.0)),
    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()
])

train_dataset = pdx.datasets.SegDataset(
    data_dir='optic_disc_seg',
    file_list='optic_disc_seg/train_list.txt',
    label_list='optic_disc_seg/labels.txt',
    transforms=train_transforms,
    shuffle=True)
eval_dataset = pdx.datasets.SegDataset(
    data_dir='optic_disc_seg',
    file_list='optic_disc_seg/val_list.txt',
    label_list='optic_disc_seg/labels.txt',
    transforms=eval_transforms)

num_classes = len(train_dataset.labels)
model = pdx.seg.FastSCNN(num_classes=num_classes)
model.train(
    num_epochs=20,
    train_dataset=train_dataset,
    train_batch_size=4,
    eval_dataset=eval_dataset,
    learning_rate=0.01,
    save_dir='output/fastscnn',
    use_vdl=True)

from paddlex.det import 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) ])

jiangjiajun commented 4 years ago

你好,麻烦贴一下你的transforms定义的代码部分, 我这边测试如下代码,可以正常训练(imgaug v0.4.0)

import paddlex as pdx
from paddlex.seg import transforms

optic_dataset = 'https://bj.bcebos.com/paddlex/datasets/optic_disc_seg.tar.gz'
pdx.utils.download_and_decompress(optic_dataset, path='./')

import imgaug.augmenters as iaa
train_transforms = transforms.Compose([
    iaa.blur.GaussianBlur(sigma=(0.0, 3.0)),
    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()
])

train_dataset = pdx.datasets.SegDataset(
    data_dir='optic_disc_seg',
    file_list='optic_disc_seg/train_list.txt',
    label_list='optic_disc_seg/labels.txt',
    transforms=train_transforms,
    shuffle=True)
eval_dataset = pdx.datasets.SegDataset(
    data_dir='optic_disc_seg',
    file_list='optic_disc_seg/val_list.txt',
    label_list='optic_disc_seg/labels.txt',
    transforms=eval_transforms)

num_classes = len(train_dataset.labels)
model = pdx.seg.FastSCNN(num_classes=num_classes)
model.train(
    num_epochs=20,
    train_dataset=train_dataset,
    train_batch_size=4,
    eval_dataset=eval_dataset,
    learning_rate=0.01,
    save_dir='output/fastscnn',
    use_vdl=True)

from paddlex.det import 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) ])

你上面这个贴的是用于训练FasterRCNN目标检测模型的代码

训练FasterRCNN目标检测模型代码参考 https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/object_detection/faster_rcnn_r50_fpn.py

训练FastSCNN语义分割模型代码参考 https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/semantic_segmentation/fast_scnn.py

yanchaoguo commented 4 years ago

调整之后报如下错误 File "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddlex/cv/transforms/seg_transforms.py", line 121, in decode_image "The height or width of the image is not same as the label") Exception: The height or width of the image is not same as the label

transform部分: from paddlex.seg import transforms

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() ])

jiangjiajun commented 4 years ago

确认一下你的图像文件,与你对应的标注图像,shape是一致的。

可以查下你的train_list.txt和val_list.txt两个文件中,里面的原图和标注文件是否对应正确了

yanchaoguo commented 4 years ago

是的 标注数据与原数据大小不一致 这种如何解决呢 ? 加了一个:transforms.Resize(target_size=600) 又报读取错误

数据集来自: https://aistudio.baidu.com/aistudio/datasetdetail/23199

jiangjiajun commented 4 years ago

语义分割任务训练要求 标注的信息图 与 原图 必须同样的大小Shape,否则无法训练, 你这里的数据集并不是一个标注的语义分割数据集

yanchaoguo commented 4 years ago

语义分割任务训练要求 标注的信息图 与 原图 必须同样的大小Shape,否则无法训练, 你这里的数据集并不是一个标注的语义分割数据集

上面数据集来自百度大脑的公开语义分割数据集, 我使用cv2重新将数据集和标注集resize到相同(600*600)大小后 ,报下面错误

File "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddlex/cv/transforms/seg_transforms.py", line 118, in decode_image label_height, label_width = label.shape ValueError: too many values to unpack (expected 2)

jiangjiajun commented 4 years ago

语义分割数据集的要求可参考这里 https://paddlex.readthedocs.io/zh_CN/develop/data/format/segmentation.html

其中对于标注的信息图片,要求是单通道图像,上面你这里处理后的label图像应该是三通道的,因此会出现如上的错误

yanchaoguo commented 4 years ago

语义分割数据集的要求可参考这里 https://paddlex.readthedocs.io/zh_CN/develop/data/format/segmentation.html

其中对于标注的信息图片,要求是单通道图像,上面你这里处理后的label图像应该是三通道的,因此会出现如上的错误

我看语义分割例子中用到的optic_disc_seg,其中标注集也是3通道的 : image

我是不是转成单通道的就可以了

jiangjiajun commented 4 years ago

语义分割数据集的要求可参考这里 https://paddlex.readthedocs.io/zh_CN/develop/data/format/segmentation.html 其中对于标注的信息图片,要求是单通道图像,上面你这里处理后的label图像应该是三通道的,因此会出现如上的错误

我看语义分割例子中用到的optic_disc_seg,其中标注集也是3通道的 : image

我是不是转成单通道的就可以了

使用cv2读取的单通道图像会自动转成3通道, 使用PIL读取图像才能读取单通道

from PIL import Image import numpy as np

I = Image.open('./cc_1.png')

yanchaoguo commented 4 years ago

from PIL import Image import numpy as np

I = Image.open('./cc_1.png')

将所有的标注数据转成灰度图 并且原图和标注数据都是400*400了 怎么还是报错呢

/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/scipy/sparse/coo.py in _check(self) 283 if self.nnz > 0: 284 if self.row.max() >= self.shape[0]: --> 285 raise ValueError('row index exceeds matrix dimensions') 286 if self.col.max() >= self.shape[1]: 287 raise ValueError('column index exceeds matrix dimensions') ValueError: row index exceeds matrix dimensions

jiangjiajun commented 4 years ago

要不分享下你的项目AIStudio链接吧,我看下

yanchaoguo commented 4 years ago

from PIL import Image import numpy as np I = Image.open('./cc_1.png')

将所有的标注数据转成灰度图 并且原图和标注数据都是400*400了 怎么还是报错呢 /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/scipy/sparse/coo.py in _check(self) 283 if self.nnz > 0: 284 if self.row.max() >= self.shape[0]: --> 285 raise ValueError('row index exceeds matrix dimensions') 286 if self.col.max() >= self.shape[1]: 287 raise ValueError('column index exceeds matrix dimensions') ValueError: row index exceeds matrix dimensions

要不分享下你的项目AIStudio链接吧,我看下

好的 ,我先把标注图的背景设置为0,前景设置为1 再试试 aistudio: https://aistudio.baidu.com/aistudio/projectdetail/1161289

yanchaoguo commented 4 years ago

要不分享下你的项目AIStudio链接吧,我看下

非常感谢 如你所说 问题已经被解决了,但效果不是很好

jiangjiajun commented 4 years ago

要不分享下你的项目AIStudio链接吧,我看下

非常感谢 如你所说 问题已经被解决了,但效果不是很好

https://aistudio.baidu.com/aistudio/projectdetail/1163973 使用这个吧,训练了两个epoch, 最终预测效果如图

image

yanchaoguo commented 4 years ago

两个epoch

image 如果是用训练数据来测试的话 效果也还可以 我这里有一个网上找到ma ;边缘处理的就不怎么好 image image

jiangjiajun commented 4 years ago

这个标注数据本身质量并不高,可以看到标注的图像中还存在周围的很多噪点 image

另外,fastscnn模型本身是一个轻量级的分割模型,如果想得到更优的模型,建议使用UNet模型,训练示例代码参考 https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/semantic_segmentation/unet.py

yanchaoguo commented 4 years ago

这个标注数据本身质量并不高,可以看到标注的图像中还存在周围的很多噪点 image

另外,fastscnn模型本身是一个轻量级的分割模型,如果想得到更优的模型,建议使用UNet模型,训练示例代码参考 https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/semantic_segmentation/unet.py

你把 lb[lb>1] = 1 调整为>90的 噪声点几乎可屏蔽掉

yanchaoguo commented 4 years ago

这个标注数据本身质量并不高,可以看到标注的图像中还存在周围的很多噪点 image 另外,fastscnn模型本身是一个轻量级的分割模型,如果想得到更优的模型,建议使用UNet模型,训练示例代码参考 https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/semantic_segmentation/unet.py

你把 lb[lb>1] = 1 调整为>90的 噪声点几乎可屏蔽掉

把之前代码中FastSCNN替换为UNet模型,训练之后之前的问题依然存在; 请问预测标注出的图片如何移除背景呢(只保留标注部分)

jiangjiajun commented 4 years ago

https://paddlex.readthedocs.io/zh_CN/develop/apis/visualize.html#paddlex-seg-visualize 参考此接口文档,将weight设为0.0即可

yanchaoguo commented 4 years ago

https://paddlex.readthedocs.io/zh_CN/develop/apis/visualize.html#paddlex-seg-visualize 参考此接口文档,将weight设为0.0即可

paddle是一个很好的产品 ,社区很活跃,工程师们也很热情,我的问题已经解决了 ,基本实现抠图效果了 image image

jiangjiajun commented 4 years ago

多谢支持,欢迎点star支持PaddleX的工程师哈😁

yanchaoguo commented 4 years ago

多谢支持,欢迎点star支持PaddleX的工程师哈😁

请问 语义分割标注时,出现多人时 如何标注 labels 怎么写

linhandev commented 3 years ago

语义分割不分实例,一类目标都标一样的类型 @yanchaoguo