DL图像数据增广
数据增广
计算机视觉有七类分类问题:
不同的视角,不同的大小,物体的形变问题,物体的遮挡问题,光照条件,背景复杂的问题,每一类中有多种形态的问题。
而数据增广的思路也就是解决这个问题。数据增广如何增广就要从实际的问题出发,比如医学的图片基本上拍摄的时候视角是固定的,所以就不需要不同视角的增广。木纹检测中视角是不固定的,就需要不同的视角,不同的大小的增广,还需要应不同的光照条件对数据进行增广。
在不改变图像类别的情况下,增加数据量,能提高模型的泛化能力
自然图像的数据增广方式包括很多,如常用的水平翻转(horizontally flipping),一定程度的位移或者裁剪和颜色抖动(color jittering)。此外还可以尝试多种操作的组合, 例如同时做旋转和随机尺度变换,此外还可以把每个patch中所有像素在HSV颜色空间中的饱和度和明度提升0.25-4次幂方,乘以0.7-1.4之间的一个因子,再加一个-0.1-0.1之间的值。同样你可以在色调通道(H)对每张图片或patch的所有像素增加一个-0.1-0.1之间的值。
数据增广很重要,好的数据增广可以提高2-3个百分点,但是要注意方式,比如在我服装检测问题上没有必要对图像上下反转。深度学习框架一般能够提供的图像增广方法很有限,需要使用额外的库进行,推荐imgaug,神器
增广代码_来自博客:
def customizedImgAug(input_img): rarely = lambda aug: iaa.Sometimes(0.1, aug) sometimes = lambda aug: iaa.Sometimes(0.25, aug) often = lambda aug: iaa.Sometimes(0.5, aug) seq = iaa.Sequential([ iaa.Fliplr(0.5), often(iaa.Affine( scale={"x": (0.9, 1.1), "y": (0.9, 1.1)}, translate_percent={"x": (-0.1, 0.1), "y": (-0.12, 0)}, rotate=(-10, 10), shear=(-8, 8), order=[0, 1], cval=(0, 255), )), iaa.SomeOf((0, 4), [ rarely( iaa.Superpixels( p_replace=(0, 0.3), n_segments=(20, 200) ) ), iaa.OneOf([ iaa.GaussianBlur((0, 2.0)), iaa.AverageBlur(k=(2, 4)), iaa.MedianBlur(k=(3, 5)), ]), iaa.Sharpen(alpha=(0, 0.3), lightness=(0.75, 1.5)), iaa.Emboss(alpha=(0, 1.0), strength=(0, 0.5)), rarely(iaa.OneOf([ iaa.EdgeDetect(alpha=(0, 0.3)), iaa.DirectedEdgeDetect( alpha=(0, 0.7), direction=(0.0, 1.0) ), ])), iaa.AdditiveGaussianNoise( loc=0, scale=(0.0, 0.05 * 255), per_channel=0.5 ), iaa.OneOf([ iaa.Dropout((0.0, 0.05), per_channel=0.5), iaa.CoarseDropout( (0.03, 0.05), size_percent=(0.01, 0.05), per_channel=0.2 ), ]), rarely(iaa.Invert(0.05, per_channel=True)), often(iaa.Add((-40, 40), per_channel=0.5)), iaa.Multiply((0.7, 1.3), per_channel=0.5), iaa.ContrastNormalization((0.5, 2.0), per_channel=0.5), iaa.Grayscale(alpha=(0.0, 1.0)), sometimes(iaa.PiecewiseAffine(scale=(0.01, 0.03))), sometimes( iaa.ElasticTransformation(alpha=(0.5, 1.5), sigma=0.25) ), ], random_order=True), iaa.Fliplr(0.5), iaa.AddToHueAndSaturation(value=(-10, 10), per_channel=True) ], random_order=True) # apply augmenters in random order output_img = seq.augment_image(input_img) return output_img
还可做一些其他处理:
2、shuffle,打乱数据进行训练是必须的,防止相邻样本有较强相关性。
3、图像标准化,计算数据集的std与mean,而不是直接使用imagenet的std与mean
4、增大图像的输入尺寸可获得客观的提升,本例最终使用了480*480的输入尺寸
4、选择合适的迁移学习方式,本例进行全局finetune比只训练最后1层或几层好很多
5、可以先用Adam快速收敛,后面阶段用SGD慢慢调
6、模型融合,举办方在复赛限制最多只能用两个模型是明智的,初赛都有队伍用接近10个模型进行融合,如此刷分就没意义了
7、对测试集图片进行增强,比如镜像,旋转,再预测并取平均。可以得到更鲁棒的结果。这里没有用到tencrop,因为样本有些特征在顶部或者底部,tencrop会将特征截走,导致成绩降低。
参考样例:
addpath
(
'test'
);
addpath
(
'train'
);
fid =
fopen
(
'C:\Users\Byte\Desktop\data.txt'
,
'wt'
)
file_path = 'C:\Users\Byte\Desktop\test_label\';
%图像文件夹路径
save_path = 'C:\Users\Byte\Desktop\cc_test\';
%图像文件夹路径
% img_path_list = dir(strcat(file_path,'*.jpg')); %获取文件夹中所有jpg格式图像
img_path_list =
dir
(
strcat
(file_path,
'*.png'
));
img_num =
length
(img_path_list);
%获取总数
if
img_num > 0
for
j
= 1 : img_num
img_name = img_path_list(
j
).name;
image
=
imread
(
strcat
(file_path,img_name));
img_name_core = img_name(1:
end
-4);
%除去后缀名
fprintf
(
'%d %d %s\n'
,
i
,
j
,
strcat
(file_path,img_name));
fprintf
(
'%s\n'
,
strcat
(file_path,img_name(1:
end
-4)));
%图像增广
%翻转flipdim
img_u =
flipdim
(
image
,1);
img_r =
flipdim
(
image
,2);
img_ur =
flipdim
(img_r,1);
imwrite
(img_u,
strcat
(save_path,img_name_core,
'_u.png'
));
imwrite
(img_r,
strcat
(save_path,img_name_core,
'_r.png'
));
imwrite
(img_ur,
strcat
(save_path,img_name_core,
'_ur.png'
));
%亮度调节
%img_bright = imadjust(image,[0,1],[0,1],0.5);
img_dark = imadjust(
image
,[0,1],[0,1],1.5);
%imwrite(img_bright,strcat(save_path,img_name_core,'_b.jpg'));
imwrite
(img_dark,
strcat
(save_path,img_name_core,
'_d.png'
));
%img_ub = imadjust(img_u,[0,1],[0,1],0.5);
img_ud = imadjust(img_u,[0,1],[0,1],1.5);
%imwrite(img_ub,strcat(save_path,img_name_core,'_ub.jpg'));
imwrite
(img_ud,
strcat
(save_path,img_name_core,
'_ud.png'
));
%img_rb = imadjust(img_r,[0,1],[0,1],0.5);
img_rd = imadjust(img_r,[0,1],[0,1],1.5);
%imwrite(img_rb,strcat(save_path,img_name_core,'_rb.jpg'));
imwrite
(img_rd,
strcat
(save_path,img_name_core,
'_rd.png'
));
%img_urb = imadjust(img_ur,[0,1],[0,1],0.5);
img_urd = imadjust(img_ur,[0,1],[0,1],1.5);
%imwrite(img_urb,strcat(save_path,img_name_core,'_urb.jpg'));
imwrite
(img_urd,
strcat
(save_path,img_name_core,
'_urd.png'
));
%旋转
for
k = 1:5
img_u = imrotate(img_u,72,
'bilinear'
,
'loose'
);
img_u = imcrop(img_u,[67 67 511 511]);
imwrite
(img_u,
strcat
(save_path,img_name_core,
'_'
,
num2str
(k),
'_u.png'
));
img_ur = imrotate(img_ur,72,
'bilinear'
,
'loose'
);
img_ur = imcrop(img_ur,[67 67 511 511]);
imwrite
(img_ur,
strcat
(save_path,img_name_core,
'_'
,
num2str
(k),
'_ur.png'
));
img_r = imrotate(img_r,72,
'bilinear'
,
'loose'
);
img_r = imcrop(img_r,[67 67 511 511]);
imwrite
(img_r,
strcat
(save_path,img_name_core,
'_'
,
num2str
(k),
'_r.png'
));
image
= imrotate(
image
,72,
'bilinear'
,
'loose'
);
image
= imcrop(
image
,[67 67 511 511]);
imwrite
(
image
,
strcat
(save_path,img_name_core,
'_'
,
num2str
(k),
'.png'
));
end
end
end