数据增广
计算机视觉有七类分类问题:
不同的视角,不同的大小,物体的形变问题,物体的遮挡问题,光照条件,背景复杂的问题,每一类中有多种形态的问题。
而数据增广的思路也就是解决这个问题。数据增广如何增广就要从实际的问题出发,比如医学的图片基本上拍摄的时候视角是固定的,所以就不需要不同视角的增广。木纹检测中视角是不固定的,就需要不同的视角,不同的大小的增广,还需要应不同的光照条件对数据进行增广。\
在不改变图像类别的情况下,增加数据量,能提高模型的泛化能力
自然图像的数据增广方式包括很多,如常用的水平翻转(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
\
\
\
\
\
\
\
\
\
\