零基础入门语义分割-Task2 数据扩增
作者:互联网
零基础入门语义分割-Task2 数据扩增
目的
顾名思义,数据扩增的原因是原始数据量不足,希望通过扩增达到
- 增加训练样本
- 有效缓解过拟合
- 赋予模型更强的泛化能力
其根本目的是使得训练数据尽可能地接近测试数据,从而提高预测精度,增加鲁棒性
常用方法
基于几何变换
Flipping
- 水平变换多于竖直变换
- 字符型图像数据不适用
Cropping
- 常用
- 通用
Rotation
MNIST 在-20°到20°之间没问题 加大旋转角可能会影响标签
Translation
平移变换 (上下左右)可以避免数据中的位置偏差
当原始图像被平移后造成的空白区域,可以用一个常数值填充,如 0 或 255 ,也可以用随机或高斯噪声填充。这种填充可以保留图像增强后的空间尺寸。
Noise Injection
增加高斯噪声是比较常用的操作,增加噪声可以帮助 CNNs 学习到更 robust feature。
对于训练数据中存在的位置偏差,几何变换是非常好的解决方案。有许多潜在的偏差来源,可以将训练数据与测试数据的分布分开。如果存在位置偏差,例如在人脸识别数据集中,每个人脸都是完全居中的,几何变换是一个很好的解决方案。除了克服位置偏差的强大能力之外,几何变换也很有用,因为它们很容易实现。有很多成像处理库,可以让水平翻转和旋转等操作轻松上手。几何变换的一些缺点包括额外的内存、变换计算成本和额外的训练时间。一些几何变换,如平移或随机裁剪等几何变换必须手动观察,以确保它们没有改变图像的标签。最后,在所涉及的许多应用领域,如医学图像分析,训练数据与测试数据之间的偏差比位置偏差和平移偏差更复杂。因此,几何变换也不一定总是能带来明显的效果。
颜色变换
- 对过亮或过暗的图像进行快速处理的方法是在图像中进行循环,并将像素值减少或增加一个恒定值。
另一种快速的色彩空间处理方法是拼接出单个RGB颜色矩阵。
另一种变换包括将像素值限制在一定的最小值或最大值。数字图像中颜色的内在表现形式,使其可以用于许多增强策略。 通道分离 亮度 对比度 饱和度
基于直方图 灰度图 转换为灰度图后,计算量减少,但是精度通常会有所降低,有人在 ImageNet 上对比 RGB 和
灰度图,发现灰度图的精度下降大约 3%。
Kernel filters
- 模糊
- 锐化
Mixing
- 对小的数据集明显
- 两幅图每个像素取平均
- 两幅图线性叠加
- 从两幅图或者多幅图中裁剪一个局部,然后拼接
Random Erasing
类似于dropout,但random erasing 是在输入数据空间进行,而非是在网络结构中。这种方法也可以看着是在模拟遮挡的情况,以保证网络关注整个图像,而不是只关注其中的一个子集。
通常 earsing 的区域直接填充随机值效果更好。使用的时候需要注意是否标签安全,可能需要人为的加入一些限制,以保证标签的正确性。
OpenCV的数据扩增
# 首先读取原始图片
img = cv2.imread(train_mask['name'].iloc[0])
mask = rle_decode(train_mask['mask'].iloc[0])
plt.figure(figsize=(16, 8))
plt.subplot(1, 2, 1)
plt.imshow(img)
plt.subplot(1, 2, 2)
plt.imshow(mask)
# 垂直翻转
plt.figure(figsize=(16, 8))
plt.subplot(1, 2, 1)
plt.imshow(cv2.flip(img, 0))
plt.subplot(1, 2, 2)
plt.imshow(cv2.flip(mask, 0))
# 水平翻转
plt.figure(figsize=(16, 8))
plt.subplot(1, 2, 1)
plt.imshow(cv2.flip(img, 0))
plt.subplot(1, 2, 2)
plt.imshow(cv2.flip(mask, 0))
# 随机裁剪
x, y = np.random.randint(0, 256), np.random.randint(0, 256)
plt.figure(figsize=(16, 8))
plt.subplot(1, 2, 1)
plt.imshow(img[x:x+256, y:y+256])
plt.subplot(1, 2, 2)
plt.imshow(mask[x:x+256, y:y+256])
albumentations数据扩增
- 基于OpenCV定制
- 支持操作更多,使用更加方便
- 可以与dl框架配合使用(Pytorch,Keras等)
import albumentations as A
# 水平翻转
augments = A.HorizontalFlip(p=1)(image=img, mask=mask)
img_aug, mask_aug = augments['image'], augments['mask']
# 随机裁剪
augments = A.RandomCrop(p=1, height=256, width=256)(image=img, mask=mask)
img_aug, mask_aug = augments['image'], augments['mask']
# 旋转
augments = A.ShiftScaleRotate(p=1)(image=img, mask=mask)
img_aug, mask_aug = augments['image'], augments['mask']
trfm = A.Compose([
A.Resize(256, 256),
A.HorizontalFlip(p=0.5),
A.VerticalFlip(p=0.5),
A.RandomRotate90(),
])
augments = trfm(image=img, mask=mask)
img_aug, mask_aug = augments['image'], augments['mask']
plt.figure(figsize=(16, 8))
plt.subplot(1, 2, 1)
plt.imshow(augments['image'])
plt.subplot(1, 2, 2)
plt.imshow(augments['mask'])aug
Pytorch 处理
首先要定义Dataset和Dataloder
import torch.utils.data as D
class TianChiDataset(D.Dataset):
def __init__(self, paths, rles, transform):
self.paths = paths
self.rles = rles
self.transform = transform
self.len = len(paths)
def __getitem__(self, index):
img = cv2.imread(self.paths[index])
mask = rle_decode(self.rles[index])
augments = self.transform(image=img, mask=mask)
return self.as_tensor(augments['image']), augments['mask'][None]
def __len__(self):
return self.len
实例化Dataset
trfm = A.Compose([
A.Resize(IMAGE_SIZE, IMAGE_SIZE),
A.HorizontalFlip(p=0.5),
A.VerticalFlip(p=0.5),
A.RandomRotate90(),
])
dataset = TianChiDataset(
train_mask['name'].values,
train_mask['mask'].fillna('').values,
trfm
)
标签:Task2,plt,img,扩增,语义,self,mask,augments,image 来源: https://blog.csdn.net/weixin_43057279/article/details/113984553