1.蝴蝶图像分类
思路一:数据增强
图像增强之numpy格式
1)图像缩放
def resize_img(img, target_size):
img = cv2.resize(img, (target_size, target_size))
return img
2)图片中央剪切
def center_crop_img(img, target_size):
w, h = img.shape[0], img.shape[1]
tw, th = target_size, target_size
assert (w >= target_size) and (h >= target_size), \
"image width({}) and height({}) should be larger than crop size".format(w, h, target_size)
x1 = int(round((w - tw) / 2.))
y1 = int(round((h - th) / 2.))
img = img[x1:x1+tw, y1:y1+th]
return img
3)随机剪切
def random_crop_img(img, target_size, scale=[0.08, 1.0], ratio=[3. / 4., 4. / 3.]):
aspect_ratio = math.sqrt(np.random.uniform(*ratio))
w = 1. * aspect_ratio
h = 1. / aspect_ratio
bound = min((float(img.shape[1]) / img.shape[0]) / (w**2),
(float(img.shape[0]) / img.shape[1]) / (h**2))
scale_max = min(scale[1], bound)
scale_min = min(scale[0], bound)
target_area = img.shape[1] * img.shape[0] * np.random.uniform(scale_min,
scale_max)
target_size = math.sqrt(target_area)
w = int(target_size * w)
h = int(target_size * h)
i = np.random.randint(0, img.shape[1] - w + 1)
j = np.random.randint(0, img.shape[0] - h + 1)
img = img[i:i+w, j:j+h]
img = cv2.resize(img, (int(target_size), int(target_size)))
return img
4)随机旋转
def rotate_image(img):
# 将图片随机旋转-14到15之间的某一个角度
angle = np.random.randint(-14, 15)
#获取图像的尺寸
#旋转中心
h, w = img.shape[0], img.shape[1]
cx,cy = w/2,h/2
#设置旋转矩阵
M = cv2.getRotationMatrix2D((cx,cy),-angle,1.0)
cos = np.abs(M[0,0])
sin = np.abs(M[0,1])
# 计算图像旋转后的新边界
nW = int((h*sin)+(w*cos))
nH = int((h*cos)+(w*sin))
# 调整旋转矩阵的移动距离(t_{x}, t_{y})
M[0,2] += (nW/2) - cx
M[1,2] += (nH/2) - cy
return cv2.warpAffine(img,M,(nW,nH))
5)随机左右翻转
def flip_image(img):
# 将图片随机左右翻转, 根据需要也可以设置随机上下翻转
v = random.random()
if v < 0.5:
img = cv2.flip(img, 1)
return img
6)亮度,饱和度,色度随机调整
def distort_image(img):
# 随机数据增强
v = random.random()
# 顺序可以自己随意调整
if v < 0.35:
img = bright_image(img)
img = saturation_image(img)
img = hue_image(img)
elif v < 0.7:
img = bright_image(img)
img = saturation_image(img)
img = hue_image(img)
return img
7)Cutout
Cutout 可以理解为 Dropout 的一种扩展操作,不同的是 Dropout 是对图像经过网络后生成的特征进行遮挡,而 Cutout 是直接对输入的图像进行遮挡,相对于Dropout对噪声的鲁棒性更好。PaddleClas中已有该方法的实现。这里将其改写为Paddle2.0中的自定义数据增强类。
import numpy as np
class Cutout(paddle.vision.transforms.BaseTransform):
def __init__(self, n_holes=1, length=112, prob=0.5, keys=None):
super(Cutout, self).__init__(keys)
self.prob = prob
self.n_holes = n_holes
self.length = length
def _get_params(self, inputs):
image = inputs[self.keys.index('image')]
params = {}
params['cutout'] = np.random.random() < self.prob
# params['size'] = _get_image_size(image)
return params
def _apply_image(self, img):
""" cutout_image """
if self.params['cutout']:
h, w = img.shape[:2] ## input image, with shape of (H, W, C)
mask = np.ones((h, w), np.float32)
for n in range(self.n_holes):
y = np.random.randint(h)
x = np.random.randint(w)
y1 = np.clip(y - self.length // 2, 0, h)
y2 = np.clip(y + self.length // 2, 0, h)
x1 = np.clip(x - self.length // 2, 0, w)
x2 = np.clip(x + self.length // 2, 0, w)
img[y1:y2, x1:x2] = 0
return img
else:
return img
思路二:优化模型
尝试换了模型,模型能力太强,有时会导致预测准确率不高。
小结:通过思路一的数据增强方法后,将蝴蝶图像分类准确率提高到了85%以上。若想将准确率提高至90%须考虑优化模型。
蝴蝶图像分类项目:https://aistudio.baidu.com/aistudio/projectdetail/1618006
参考文档:https://aistudio.baidu.com/aistudio/projectdetail/699878
https://aistudio.baidu.com/aistudio/projectdetail/1357939