상세 컨텐츠

본문 제목

데이타 증강(Data Augmentation)

AI

by cepiloth 2021. 5. 7. 10:08

본문

728x90
반응형

Data Augmentation 등장의 이유?

 전통적 특징점(Keypoint/Feature) 기반의 접근과 함께 머신 러닝, 딥 러닝 방법의 방법론이 늘어 갔다. 하지만 데이터 부족의 문제는 야기되고 있으며 계속해서 함께 따라다니고 있다. 이를 보완하는 측면에서 소량의 데이터를 가지고 인위적으로 학습 데이터를 재 생성하여 확장하는 방법이 사용되고 있다. 여기서 중요한 점은 Data의 의미이다.

빅 데이터의 4V 설명
가치(Value) 구슬의 서 말이라도 꿰어야 보배라는 속담이 있듯이 빅 데이터의 가치라는 속성을 잘 설명해준다. 데이터 자체가 중요한 것이 아니라 의사결정에 유용한 '정보(Information)' '지식(Knowledge)'으로 축적 되어야 한다.
다양성(Variety) 데이터베이스에 차곡차곡 쌓던 기존의 정형화된 데이터의 형태가 아니라, 사진과 이미지, 영상 등의 다양한 비정형 데이터가 전체 데이터의 90%를 차지하고 있습니다.
속도(Velocity) 대용량의 데이터를 빠르게 처리하고 분석할 수 있는 속성입니다. 융복합 환경에서 디지털 데이터는 매우 빠른 속도로 생산되므로 이를 실시간으로 저장, 유통, 수집, 분석 처리할 수 있는 성능을 의미합니다.
크기(Volume) 수십 테라바이트 혹은 페타파이트 이상 규모의 데이터 속성인데, 큰 규모의 기준이 정확이 무엇이냐? 라고 하면 단정 짓기는 어렵다 확실한 건 오늘보다 내일의 데이터가 더 많다는 것이다.

빅 데이터의 4V 분류의 기준으로 볼 때 분석 가치가 있는 데이터의 정의가 중요하다는 것을 알 수 있다.

 

Data Augmentation 종류

데이터 확장(augmentation) 방법은 크게 기하적 변환과 태스크 기반(task-specific 또는 guided) 확장으로 나뉜다.

기하적 변환

기하적 변환은 크기 조절, 반전, 자르기, 회전, 이동, 윈도우 분할 등이 있다.

태스크 기반 확장

 태스크 기반 확장은 데이터를 합성 시 분류에 대한 척도를 고려하여 학습을 수행한다. 물체 인식에 대해서 자르기(crop)와 반전(flip)만을 사용하여 다양한 CNN 네트워크에 대해서 성능 비 교를 한 연구가 있다. 자르기와 색 조절은 학습 데이터 확장에, 크기 변환과 다각도 관점 변환은 테스트 데이터 확장에 사용하여 성능 향상을 보인 논문도 있다.

 기하적 변환 외에 GAN을 이용한 태스크 기반의 데이터 확장도 시도되고 있다. 이들 모두가 물체 인식 분야에서의 데이터 확장 문제들 로서, 물체와 특성이 다른 표면 결함에 대해서는 아직 분석이 미 비한 편이다. 표면 결함의 종류는 스크래치(scratch), 찍힘(stamped), 짙은 얼룩(stain) 등이 존재한다.

 이들 결함에 따라서 적용 가능한 데 이터 확장 방법이 다를 수 있으며, 효과도 상이할 수 있다. 즉, 물체 인식과 결함 인식의 차이가 존재하므로, 대상 문제에 따른 데이터 확장 방법도 유효성이 다를 수 있다. 지금까지 이에 대한 분석이나 체계적인 접근이 시도되지 않고 있다.

 

Data Augmentation Library

 keras에서 제공하는 tf.image 등 Keras 전처리 레이어를 사용하는 방법과 https://github.com/aleju/imgaug으로 이미지에 대해서 데이터 증강을 할 수 있다. 아래의 이미지 한 장으로 Data Augmentation을 활용할 수 있다.

Data Augmentation 예시

아래 그림은 imgaug github의 README.MD 에 있는 예시이다.

 

 

Black Survival의 Luke라는 캐릭터를 Data Augmentation을 수행해 보았다.

원본 그림은 아래와 같다.

Data Augmentation 수행하였다.

<기하적 변환과 태스크 기반 확장을 모두 적용한 모습>

 

전체 소스 코드

import cv2;
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) :
        self.sometimes = lambda aug: iaa.Sometimes(0.5, aug)
        self.seq = iaa.Sequential(
            [
                iaa.Fliplr(0.5), # horizontally flip 50% of all images
                iaa.Flipud(0.2), # vertically flip 20% of all images
                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)
                    )),
                     
                    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
    )

 

 이번 포스팅은 Data Augmentation의 등장 이유와 imgaug라는 파이선 라이브러리를 사용하여서 Data Augmentation을 실습해 보았다. Keras에 제공하는 것도 쓸만하다. 해당 포스팅에서 사용한 코드와 이미지는 아래 Github 에 모두 업로드 하였습니다.

Github - github.com/cepiloth/blacksurvival_face

728x90
반응형

관련글 더보기

댓글 영역