이번 포스팅은 imgaug 패키지를 이용하여 classify 모델의 성능을 증가시킬 수 있는
imgaug를 소개하고자 한다.
imgaug는 파이썬 패키지 형태로 배포되었기 때문에 설치가 매우매우 간단하다.
pip3 install imgaug
하지만, imgaug를 pip3 로 설치할 경우 opencv 등 의존성 패키지들이 같이 설치되어 가지고 있던 패키지들의 version이 변경되게 된다. 그런 경우를 방지하고자 한다면 다음을 참고하여 설치
imgaug dependencies
- six
- numpy
- scipy
- Pillow
- matplotlib
- scikit-image
- opencv-python
- imageio
위 목록들 중에 본인이 이미 설치가 되어있고, version을 망치고 싶지 않다면,
의존성 패키지를 따로 설치해준 뒤에 다음 명령어로 imgaug를 설치하면 된다.
pip install --no-dependencies imgaug
imgaug 패키지에는 classify를 위한 이미지부터 heatmap, Segments, Keypoints, Bounding Box, Polygons 등
다양한 형태의 데이터 증강을 지원한다.
본 포스팅에서는 이미지 데이터 증강의 예제 사용을 소개한다.
가장 먼저, imgaug github 및 docs에 있는 예제를 클래스 형태로 작성해 주었다.
#-- filename : img_aug.py --
import numpy as np
import imgaug as ia
import imgaug.augmenters as iaa
# random example images
images = np.random.randint(0, 255, (16, 128, 128, 3), dtype=np.uint8)
class Img_aug :
def __init__(self) :
# Sometimes(0.5, ...) applies the given augmenter in 50% of all cases,
# e.g. Sometimes(0.5, GaussianBlur(0.3)) would blur roughly every second image.
self.sometimes = lambda aug: iaa.Sometimes(0.5, aug)
# Define our sequence of augmentation steps that will be applied to every image
# All augmenters with per_channel=0.5 will sample one value _per image_
# in 50% of all cases. In all other cases they will sample new values
# _per channel_.
self.seq = iaa.Sequential(
[
# apply the following augmenters to most images
iaa.Fliplr(0.5), # horizontally flip 50% of all images
iaa.Flipud(0.2), # vertically flip 20% of all images
# crop images by -5% to 10% of their height/width
self.sometimes(iaa.CropAndPad(
percent=(-0.05, 0.1),
pad_mode=ia.ALL,
pad_cval=(0, 255)
)),
self.sometimes(iaa.Affine(
scale={"x": (0.8, 1.2), "y": (0.8, 1.2)}, # scale images to 80-120% of their size, individually per axis
translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)}, # translate by -20 to +20 percent (per axis)
rotate=(-45, 45), # rotate by -45 to +45 degrees
shear=(-16, 16), # shear by -16 to +16 degrees
order=[0, 1], # use nearest neighbour or bilinear interpolation (fast)
cval=(0, 255), # if mode is constant, use a cval between 0 and 255
mode=ia.ALL # use any of scikit-image's warping modes (see 2nd image from the top for examples)
)),
# execute 0 to 5 of the following (less important) augmenters per image
# don't execute all of them, as that would often be way too strong
iaa.SomeOf((0, 5),
[
self.sometimes(iaa.Superpixels(p_replace=(0, 1.0), n_segments=(20, 200))), # convert images into their superpixel representation
iaa.OneOf([
iaa.GaussianBlur((0, 3.0)), # blur images with a sigma between 0 and 3.0
iaa.AverageBlur(k=(2, 7)), # blur image using local means with kernel sizes between 2 and 7
iaa.MedianBlur(k=(3, 11)), # blur image using local medians with kernel sizes between 2 and 7
]),
iaa.Sharpen(alpha=(0, 1.0), lightness=(0.75, 1.5)), # sharpen images
iaa.Emboss(alpha=(0, 1.0), strength=(0, 2.0)), # emboss images
# search either for all edges or for directed edges,
# blend the result with the original image using a blobby mask
iaa.SimplexNoiseAlpha(iaa.OneOf([
iaa.EdgeDetect(alpha=(0.5, 1.0)),
iaa.DirectedEdgeDetect(alpha=(0.5, 1.0), direction=(0.0, 1.0)),
])),
iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.05*255), per_channel=0.5), # add gaussian noise to images
iaa.OneOf([
iaa.Dropout((0.01, 0.1), per_channel=0.5), # randomly remove up to 10% of the pixels
iaa.CoarseDropout((0.03, 0.15), size_percent=(0.02, 0.05), per_channel=0.2),
]),
iaa.Invert(0.05, per_channel=True), # invert color channels
iaa.Add((-10, 10), per_channel=0.5), # change brightness of images (by -10 to 10 of original value)
iaa.AddToHueAndSaturation((-20, 20)), # change hue and saturation
# either change the brightness of the whole image (self.sometimes
# per channel) or change the brightness of subareas
iaa.OneOf([
iaa.Multiply((0.5, 1.5), per_channel=0.5),
iaa.FrequencyNoiseAlpha(
exponent=(-4, 0),
first=iaa.Multiply((0.5, 1.5), per_channel=True),
second=iaa.ContrastNormalization((0.5, 2.0))
)
]),
iaa.ContrastNormalization((0.5, 2.0), per_channel=0.5), # improve or worsen the contrast
iaa.Grayscale(alpha=(0.0, 1.0)),
self.sometimes(iaa.ElasticTransformation(alpha=(0.5, 3.5), sigma=0.25)), # move pixels locally around (with random strengths)
self.sometimes(iaa.PiecewiseAffine(scale=(0.01, 0.05))), # self.sometimes move parts of the image around
self.sometimes(iaa.PerspectiveTransform(scale=(0.01, 0.1)))
],
random_order=True
)
],
random_order=True
)
매우매우 길기에 우리 코드에 넣어서 그냥 사용하기에는 부담스럽기 때문에 클래스로 따로 선언하여 스크립트를 작성했다.
코드 내용을 보면 imgaug패키지의 다양한 증강기법이 사용된 것을 확인해 볼 수 있다.
heatmap, Segments, Keypoints, Bounding Box, Polygons 등 같은 방식으로 docs에서 사용하려고 하는 함수명을 확인한 후에 Sequential 안에 선언해주어서 사용이 가능하다.
안쪽의 파라미터들은 docs를 보면서 직접 확인해보고, 사용해보면서 변경해주면 된다.
본 포스팅에서는 예제 그대로 사용하여 데이터를 증강시켜 주었다.
class로 선언하였기 때문에 사용하고자 하는 python 스크립트에서는 간단하게 쓸 수 있다.
(위와 같은 방법으로 본인만의 데이터 증강 모듈을 만들 수 있다.)
#-- filename : main.py --
import cv2
import numpy as np
from img_aug import Img_aug #데이터 증강 class를 불러옴
aug = Img_aug() #데이터 증강 class 선언
augment_num = 40 #증강결과로 출력되는 이미지의 갯수 선언
save_path = 'augment/'
img = cv2.imread('pizza.jpg')
images_aug = aug.seq.augment_images([img for i in range(augment_num)])
for num,aug_img in enumerate(images_aug) :
cv2.imwrite(save_path+'pizza_{}.jpg'.format(num),aug_img)
print('Complete augmenting images')
피자 이미지의 데이터 증강이 잘 되었는지 확인해보자.
피자이미지가 정말 다양하게 증강된 것을 확인할 수 있다.
예제를 그냥 그대로 사용하기 보다는 본인이 원하는 증강기법을 선택하여 random 으로 데이터 증강을 시킨다면,
classify의 성능이 매우 올라갈 것이다.
(물론, 데이터 증강만이 성능개선의 정답은 아니다.)
본 포스팅에서는 증강기법 패키지를 소개하고, 이미지를 직접 확인하기 위해 저장하는 방법을 작성하였지만,
실제 훈련시에는 images_aug = aug.seq.augment_images([img for i in range(augment_num)])
이 부분을 batch에 이미지와 함께 입력하여 훈련시키고자 하는 network에 삽입하여 주면 된다.
본 포스팅에서는 소개의 목적으로 정~말 간단하게 풀어내었지만, 사용용도에 따라 다양하게 사용하면 좋을듯하다.
https://github.com/aleju/imgaug
https://imgaug.readthedocs.io/en/latest/index.html
'Computer Vision > Classification' 카테고리의 다른 글
개와 고양이 분류하기 - 2 (0) | 2020.06.23 |
---|---|
개와 고양이 분류하기 - 1 (0) | 2020.06.18 |
개와 고양이 분류하기 - 0 (0) | 2020.06.18 |