Random Erasing Data Augmentation

아래의 논문을 참고로 Random Erasing Data Augmentation을 구현해 보았습니다.

Zhun Zhong, et al. (2017) Random Erasing Data Augmentation

이런 장소에서 논문을 인용하는 것은 처음이므로, 방법이 이상하거나 저작권에 걸려있는 등 있으면 가르쳐 주시면 감사하겠습니다.

Data Augmentation의 일종으로, 이미지의 클래스 분류, 물체 검출, 인물 조합에 있어서 유효하다고 합니다.
(정밀도를 측정하는 곳까지 하고 싶었습니다만, 난간의 기사이므로 거기까지 하고 있지 않습니다...죄송합니다)

알고리즘


*Input*  
  Input image: I;  
  Image size: W * H;  
  Area of images: S;  
  Erasing probability: p;  
  Erasing area ratio range: (s_l, s_h);  
  Erasing aspect ratio range: (r1, r2);  

*Output*  
  Erased Image: I_erased;  


*Initialization*  
  p1 <- rand(0, 1);  

*Algorithm*  
  if p1 > p then  
    I_erased <- I;  
    return I_erased.  
  else 
    while True do  
      S_e <- rand(s_l, s_h) * S;  
      r_e <- rand(r1, r2);  

      H_e <- sqrt(S_e * r_e);  
      W_e <- sqrt(S_e / r_e);  

      x_e <- rand(0, W);  
      y_e <- rand(0, H);  

      if x_e + W_e <+ W and y_e + H_e <= H then
        I_e <- (x_e, y_e, x_e + W_e, y_e + H_e);  
        I(I_e) <- Rand(0, 255);  
        I_erased <- I;  
        return I_erased.  
      end
    end  
  end

코드


%matplotlib inline

# 無駄なimportがあるかもしれません
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

from sklearn.utils import shuffle
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split

from keras.datasets import cifar10

rng = np.random.RandomState(1234)
random_state = 42

(cifar_X_1, cifar_y_1), (cifar_X_2, cifar_y_2) = cifar10.load_data()  # 一つ目がtrain, 二つ目がtest

cifar_X = np.r_[cifar_X_1, cifar_X_2]
cifar_y = np.r_[cifar_y_1, cifar_y_2]

cifar_X = cifar_X.astype('float32') / 255
cifar_y = np.eye(10)[cifar_y.astype('int32').flatten()]

train_X, test_X, train_y, test_y = train_test_split(cifar_X, cifar_y, test_size=10000, random_state=random_state)
train_X, valid_X, train_y, valid_y = train_test_split(train_X, train_y, test_size=10000, random_state=random_state)


# 表示しやすいように関数にしています
def show_cifar10_images(dataset):
    fig = plt.figure(figsize=(9, 15))
    fig.subplots_adjust(left=0, right=1, bottom=0, top=0.5, hspace=0.05,
                        wspace=0.05)
    for i in range(81):
        ax = fig.add_subplot(9, 9, i + 1, xticks=[], yticks=[])
        ax.imshow(dataset[i])


# ここが今回のコード
# パラメタは論文に書いてある通りにしました。
def random_erasing(img, p = 0.5, s_l = 0.02, s_h = 0.4, r1 = 0.3, r2 = 1. / 0.3):
    p1 = np.random.uniform(0,1)
    if p1 < p:
        return img
    else:
        H = img.shape[0]
        W = img.shape[1]
        S = H * W
        while True:
            S_e = S * np.random.uniform(low=s_l, high=s_h)
            r_e = np.random.uniform(low=r1, high=r2)

            H_e = np.sqrt(S_e * r_e)
            W_e = np.sqrt(S_e / r_e)

            x_e = np.random.randint(0, W)
            y_e = np.random.randint(0, H)

            if x_e + W_e <= W and y_e + H_e <= H:
                img_erased = np.copy(img)
                img_erased[y_e:int(y_e + H_e + 1), x_e:int(x_e + W_e + 1), :] = np.random.uniform(0, 1)
                return img_erased


# 表示してみる
train_X_erased = np.copy(train_X)
for i in range(train_X_erased.shape[0]):
    train_X_erased[i] = random_erasing(train_X_erased[i])

show_cifar10_images(train_X_erased)

결과





잘 일부가 지워집니다.

좋은 웹페이지 즐겨찾기