背景
在进行目标识别的过程中,获取大量的数据是一件比较困难的事,但好的模型往往是基于大的数据集训练而来的。数据量较少时,模型性能难以达到理想的状态。尤其是在做项目的过程中,用户上传的测试数据与我们用于训练的数据之间的差异难以把控,可能会因为一些不相干的因素(角度不同,模糊度不同,目标大小不同等)的干扰而导致识别的效果不够理想。因此,需要进一步的丰富训练数据的表现,从而提高模型的鲁棒性,达到更好的识别目标的目的。
核心技术与架构图
针对不同的数据,应根据数据和待识别目标的特点对数据集进行扩充,目前大多数目标识别框架都做了相关的数据扩充,但这些数据扩充的方式不一定适合自己的训练数据,因此要结合自己数据,避免重复和无意义的操作。
技术优势
相较于原始数据,扩充后的数据在形态和细节上更加丰富,重要特征更加明显,可避免不相干特征对重要特征的干扰。尤其是当待识别的目标较小,模糊不清时,通过相关的扩充技术,可让训练出的模型参数更优。即使待识别的图像存在一些缺陷,也能够准确的识别出目标。
技术实现
以识别手机中的固定标志为例:
下图为一张手机图片,上边有四个固定的标志,我们的目的是识别出这四个标志。由于根据原始数据训练出的模型的识别效果较差,因此对原始数据进行多种变换,将数据集进行扩充。
1
旋转
random_angle = np.random.randint(1, 360)
img_rote = image.rotate(random_angle, mode)
2
翻转(水平/垂直)
image = image.transpose(Image.FLIP_LEFT_RIGHT)
3
随机裁剪
crop_win_size = np.random.randint(250, 360)
random_region = ((image_width - crop_win_size) >>1, (image_height - crop_win_size) >>1, (image_width + crop_win_size) >>1, (image_height + crop_win_size) >>1)
4
缩放
image = image.resize((nw, nh), Image.BICUBIC)
new_image = Image.new('RGB', target_size, (128, 128, 128))
new_image.paste(image, ((w - nw) // 2, (h - nh) // 2))
5
随机色彩抖动
random_factor = np.random.randint(0, 31) / 10.
img_color = ImageEnhance.Color(image).enhance(random_factor) # 调整图像的饱和度
img_brightness = ImageEnhance.Brightness(color_image).enhance(random_factor)# 调整图像的亮度
img_contrast = ImageEnhance.Contrast(brightness_image).enhance(random_factor)# 调整图像的对比度
img_sharpness = ImageEnhance.Sharpness(contrast_image).enhance(random_factor)# 调整图像锐化度
6
模糊化
img_blur = cv2.GaussianBlur(image, kernel_size, sigma)
7
透明化
b_channel, g_channel, r_channel = cv2.split(image)
alpha_channel = np.ones(b_channel.shape, dtype=b_channel.dtype) * 255
alpha_channel[:, :int(b_channel.shape[0])] = 180
img_BGRA = cv2.merge((b_channel, g_channel, r_channel, alpha_channel))
分块
img_block = image[int(h*1 / 9):int(h*1 / 2), :int(w *9/ 24), :]
效果展示
下图分别展示了未经数据扩充和数据扩充后训练出模型对两张新的图像的测试效果,可看出,后者对目标的识别精准度明显得到了提升,尤其是在模糊的小目标的识别上表现更好。
总结
数据扩充已被证明是一种有效的提高模型鲁棒性的方法,扩充的方法也有很多,但需要结合自己的数据和目标的特征进行具体分析,选择合适的方法,才能有效的提升模型的性能。