语义分割的数据处理与训练过程

一、数据处理

拿到数据之后,不应该直接进行模型的训练,首先进行如下几步:

  1. 数据清洗
    这时候一定要查看数据和标签,对于比赛来讲,拿到数据之后很有可能数据本身就是有问题的,比的不仅是对模型的训练,更是对数据的处理,所以第一步是剔除有问题的数据和标签,所以也叫做数据清洗
  2. 数据增强
    对于深度学习来讲,数据量的大小决定了模型的学习能力,一般而言,数据量越大,模型学习的越好;所以,拿到有限的数据后,可以先做数据增强,扩充数据量
    这里给出一些参考:
    知乎:使用Python+OpenCV进行数据增广方法综述(附代码演练)
  3. 超参实验
    这里的为什么会有超参实验?主要是因为数据中存在正负样本/难易样本

关于这几种样本(对于分类):

  • 正样本:我们想要正确分类出的类别所对应的样本,例如,我们需要对一张图片分类,确定是否属于猫,那么在训练的时候,猫的图片就是正样本。
  • 负样本:根据上面的例子,不是猫的其他所有的图片都是负样本
  • 难分正样本(hard positives):错分成负样本的正样本,也可以是训练过程中损失最高的正样本
  • 难分负样本(hard negatives):错分成正样本的负样本,也可以是训练过程中损失最高的负样本
  • 易分正样本(easy positive):容易正确分类的正样本,该类的概率最高。也可以是训练过程中损失最低的正样本
  • 易分负样本(easy negatives):容易正确分类的负样本,该类的概率最高。也可以是训练过程中损失最低的负样本。
    参考:
    知乎:深度学习难分样本挖掘(Hard Mining)
    这里补充一下OHEM,很多比赛或者文章提到了,可以借鉴;其次是训练方法,首先可以进行实验找到不同的难易样本的比例,在此基础上进行训练策略的调整,例如找到loss特别低的样本,进行标记,或者在训练一段时间后再加入困难样本,进行针对性训练(这里未实际操作)。

(对于语义分割):

这里挖个坑,之后填

  1. 训练时增强
    主要有transform一系列的crop,注意这里的一些crop会产生5张或者10张图片,本来[b,c,h,w]变成了[b,k,c,h,w]这里k为crop之后图片的张树,有5或者10,需要进行reshape[-1,c,h,w],实际上相当于将裁剪出来的图片都堆在了batch上面
    参考:
    知乎:PyTorch 学习笔记(三):transforms的二十二个方法

  2. 重要!
    知乎:强调语义分割数据增强的技巧
    因为之前数据增强做了很多,也看到了很大的提升,但是依旧卡在了一个瓶颈期,为探究其原因,上网查看了一些资料,发现了这篇知乎的文章,打算试一下!

  3. 脏数据?
    数据集存在问题

二、训练过程

  1. 图片读取处理保存
    首先参考一篇(推荐下文链接的知乎问题):
    Python 中各种imread函数的区别与联系

一些个人理解:

  • PIL库是python的原生库,兼容性比较强,需要安装对应的包 pip install pillow
    但是要记住PIL读取出来是image格式,需要转化numpy;支持单通道及多通道Uint8 TIFF图像读取,读取单通道Uint16 TIFF图像转为Uint8处理,直接读取Uint16 TIFF多通道图像出错

  • matplotlib本身只能读取PNG,所以会有局限性

  • opencv读取出来直接是numpy,但是通道和shape不一样,这里不需要在意,因为在ToTensor()时,pytorch会将其通道纠正,所以其实也很方便,最主要是其功能较多,比较权威

  1. pytorch的dataset
    (1)为什么dataset返回的数据形状需要保持一致?
    因为pytorch的dataloader默认的collate_fn会使用torch.stack合并多张图片成为batch,形状不同的tensor不能stack
    (2)如果非要加载不同形状的样本怎么办?
    要么另外写一个collate_fn,进行单独处理;要么在dataset类中对图片做padding,使得图片的size一样,可以直接stack

  2. transform.normalization()
    公式随处可见,此处不赘述。
    作用:就是可以使(0, 1)变为(-1, 1)

原因:模型初始化时bias=0,但是实际的bias可能会比较大,这样的初始化就会导致神经网络收敛比较慢,经过Normalize后,可以加快模型的收敛速度。实验结果证明了,在多次周期迭代之后,我们的网络在使用归一化数据时有更高的准确性。有时被称为网络的快速收敛。
需要注意的是,并不总是归一化的数据更好。一个好的经验法则是在有疑问的时候,两种方式都要尝试。

目前很多网络都在用batch normalization,批量归一化或批量规范化就是在网络的各层输出激活上,在网络的各层里面进行的这个同样的过程,具有很多优点,所以就不加transform.normalization()了,并且如果数据量较小,训练集和测试集的normalization的指标差距较大,可能效果不是很好。
挖坑:

SyncBatchNorm和Normalization的差别

  1. 损失函数
    参考:
    pytorch交叉熵使用方法
    这里需要注意:
    (1)BCE loss需要将标签进行one hot,比较麻烦,但是CE loss不需要
    (2)CE loss 中predict的dtype应当为float并且要softmax,而gt的dtype应当为long,否则会出错

那么关键问题是,网络输出[b,num_class,h,w],num_class为对应类别(几分类就是几),gt为单通道的图片,怎样处理可以使其可以进行loss的计算?
例如:语义分割的图片输入是224×224×3经过神经网络之后输出是224×224×21而label值是224×224×1那么这两个值怎么转换才能构建损失函数呢?
参考:
知乎:语义分割的loss值怎么定义?

最后说一下语义分割的几个loss,最近也没少看,但是实验结果并没有告诉我这几个的优劣性:
训练更倾向于挖掘前景区域,正负样本不平衡的情况就是前景占比较小。而ce loss会公平处理正负样本,当出现正样本占比较小时,就会被更多的负样本淹没。dice loss对正负样本严重不平衡的场景有着不错的性能,训练过程中更侧重对前景区域的挖掘。但训练loss容易不稳定,尤其是小目标的情况下,另外极端情况会导致梯度饱和现象。因此有一些改进操作,主要是结合ce loss等改进,比如: dice + ce loss,dice + focal loss等。

  1. 多尺度训练——
    多尺度训练(Multi Scale Training, MST)通常是指设置几种不同的图片输入尺度,训练时从多个尺度中随机选取一种尺度,将输入图片缩放到该尺度并送入网络中,是一种简单又有效的提升多尺度物体检测的方法。

简书:深度学习中的多尺度训练
在tensorflow,pytorch中就可直接进图片的resize,进行多尺度的训练。
训练时,预先定义几个固定的尺度,每个epoch随机选择一个尺度进行训练。

三、可视化

  1. 训练中保存图像
    pytorch拼接与保存图片

  2. 请问注意力机制中生成的类似热力图或者柱状图是如何生成的?

  3. 万字长文:特征可视化技术(CAM)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值