当前位置:   article > 正文

【语义分割项目实战】Augmentor数据增强与U-Net的综合应用

语义分割项目实战

之前已经介绍过了数据增强工具Augmentor的使用 

【语义分割项目实战】基于Augmentor工具的语义分割中常见几种数据增强方式(一)_Bill~QAQ~的博客-CSDN博客

以及简单的复现U-Net网络

【语义分割项目实战】制作语义分割数据集,并使用U-Net进行实战检测_Bill~QAQ~的博客-CSDN博客_unet医学图像分割实战

现在我们需要将两者综合运用起来,其中还是有不少问题需要微调的

1.进行格式转换

 首先按照要求,我们需要制作好自己的VOC格式数据集 ,也就是原图的图片(一般是jpg)和与其一一对应的掩膜图像(一般是png)

要想使用Augmentor进行数据增强,我们需要确保所有的图片都是jpg格式,因此需要进行格式转换,把imgs文件夹下的jpg原图转换成png

  1. import os
  2. import string
  3. dirName = ".\imgs\\" #改成自己的路径,最后要加双斜杠
  4. li=os.listdir(dirName)
  5. for filename in li:
  6. newname = filename
  7. newname = newname.split(".")
  8. if newname[-1]=="jpg":
  9. newname[-1]="png"
  10. newname = str.join(".",newname) #这里要用str.join
  11. filename = dirName+filename
  12. newname = dirName+newname
  13. os.rename(filename,newname)
  14. print(newname,"updated successfully")

2.进行增强 

随后就可以把图片进行数据增强了,下面是我使用的方法,均来自Augmentor的功能库

  1. import Augmentor
  2. #原图的路径
  3. p=Augmentor.Pipeline(".\imgs")
  4. #掩膜图像的路径
  5. p.ground_truth(".\jsons")
  6. p.rotate(probability=1,max_left_rotation=25,max_right_rotation=25)
  7. p.flip_left_right(probability=1)
  8. p.flip_top_bottom(probability=1)
  9. p.scale(probability=1,scale_factor=1.25)
  10. # #缩小
  11. # p.zoom_random(probability=1,percentage_area=0.4)
  12. # #从中心裁剪
  13. # p.crop_centre(probability=1,percentage_area=0.6)
  14. # #按大小裁剪
  15. # p.crop_by_size(probability=1,width=100,height=100)
  16. #垂直形变
  17. p.skew_tilt(probability=1,magnitude=1)
  18. #斜四角形变
  19. p.skew_corner(probability=1,magnitude=1)
  20. # #弹性扭曲
  21. # p.random_distortion(probability=1,grid_height=5,grid_width=16,magnitude=8)
  22. #错切变换
  23. p.shear(probability=1,max_shear_left=25,max_shear_right=25)
  24. # #生成的原图+掩膜图像的总数目,建议是偶数
  25. p.sample(700)

生成的结果如下,因为数据太多了所以我只截取部分进行展示

3.格式统一

可以明显的看到,得到的所有图片文件的命名都发生了改变,这样使得我们的原图在网络中不能找到与其一一对应的掩膜图像,同时所有的掩膜图像和原图都放在output文件夹下面,不利于我们的网络进行图片的读取,因此我们需要一些脚本作为辅助。

首先是将原图和掩膜图像分别存在不同的文件夹中,我这里是单独将掩膜图像划分到另一个文件夹下

  1. import os
  2. # 文件夹筛选器
  3. formFilter = lambda form :\
  4. lambda f : True if f[-len(form):] == form else False
  5. # 只对文件名称中有mark的进行操作
  6. markFilter = lambda mark:\
  7. lambda f : True if mark in f else False
  8. # 输入文件夹,返回文件夹下所有dType类型数据
  9. getAllFiles = lambda path,dType : \
  10. list(filter(formFilter(dType),os.listdir(path))) #筛选文件
  11. # 新建文件夹
  12. def mkDir(path):
  13. if not os.path.exists(path):
  14. os.mkdir(path)
  15. def splitFolder(path=r'imgs/output',mark="groundtruth"):
  16. if path[-1]!='\\':
  17. path += "\\"
  18. files = getAllFiles(path,"png")
  19. files = list(filter(markFilter(mark),files))
  20. for f in files:
  21. try:
  22. folder = f.split(mark)[0]
  23. newName = f[len(folder)+1:]
  24. mkDir(path+folder)
  25. os.rename(path+f,path+folder+'\\'+newName)
  26. except:
  27. print(f)
  28. if __name__ == "__main__":
  29. splitFolder()

可以看到所有的掩膜图像都被存到了一个名为-的文件夹中

然后我们就需要对原图和掩膜图像都进行改名,需要知道的是,操作系统对于图片的读取是有一定规律的,比如我有若干个命名分别为1,2,10,20,3,30的文件,那么系统读取图片的顺序是:1,10,2,20,3,30,先看第一位数字再看第二位数字。

这也就说明。虽然在读取原图和掩膜图像的过程中,会使得原有的存放顺序发生改变,但是如果这种改变是有规律的,且相同的,那么就说明得到的结果原图和掩膜图像还是会保持一一对应的关系,不信我们就测试一下

  1. import os
  2. class BatchRename():
  3. def __init__(self):
  4. self.path = 'imgs/output/_'#改成自己的路径,分别对掩膜和原图进行改名,就是要运行两次
  5. def rename(self):
  6. filelist = os.listdir(self.path)
  7. filelist.sort()
  8. total_num = len(filelist)
  9. i = 0
  10. for item in filelist:
  11. if item.endswith('.png'):
  12. src = os.path.join(os.path.abspath(self.path), item)
  13. s = str(i)
  14. s = s.zfill(6)
  15. dst = os.path.join(os.path.abspath(self.path), s + '.png')
  16. try:
  17. os.rename(src, dst)
  18. print('converting %s to %s ...' % (src, dst))
  19. i = i + 1
  20. except:
  21. continue
  22. print('total %d to rename & converted %d jpgs' % (total_num, i))
  23. if __name__ == '__main__':
  24. demo = BatchRename()
  25. demo.rename()

 我们可以直接用肉眼比较一下生成的结果,很明显可以看出他们仍然是一一对应的

随后我们将结果放入U-Net下的data文件夹中,进行训练即可,具体的参数(epoch,batch-size,learning rate)根据自身需求和硬件条件自行调整

__________________________________________________________________________

记录两个改错记录,希望对大家有所帮助

第一个:

 我遇到这个错误是在将batch-size从1调大到3的时候遇到的,意思是读入图像的大小不一致

修改方法:在Augmentor进行数据增强的时候使用resize方法把图像大小都调成一样的

  1. #修改图像的大小
  2. p.resize(probability=1,width=500,height=500)

第二个:

RuntimeError: Trying to resize storage that is not resizable

修改方法:在train.py的第45行,num_workers数量改为0

  1. #把num_workers改为0
  2. loader_args = dict(batch_size=batch_size, num_workers=0, pin_memory=True)

这是调参之后的结果,调参的目的是为了train loss收敛的更快更低,同时提高validation dice

使用predict.py进行一下测试

 

 

 简单说一下调参的过程

1.首先控制batch-size不变,从1e-3开始调learning-rate,每次除以2,我大概调到1e-5是最优

2.保持learning-rate不变,增大或者减少batch-size

除此之外,还有以下参数可以调整:

Epoch:一个epoch代表遍历了一次训练集中的所有样本

Batch-size:批大小,会影响训练速度,建议设置为2n2^n

Optimizer:优化器,包括SGDAdamRMSprop

Learning-rate:学习率,要根据优化器和batch-size进行调整

Weight_decay:正则化系数(权重衰减系数),防止过拟合

Momentum:动量,用于优化器中

Load:是否预加载模型

Validation:验证集的比例

Class:需要分割的类数目(包括背景)

Scale:图像放入网络时缩放的比例

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/359679
推荐阅读
相关标签
  

闽ICP备14008679号