Data Augmentation 적용해보겠습니다. Data Augmentation 어떻게 Overfitting 방지하면서 분류 정확도를 높일 있는지 확인해보겠습니다.  새 파일을 열고 이름을 minivggnet_flowers17_data_aug.py 지정한 다음 작업을 시작해 보겠습니다.

 

필요한 라이브러리를 로드합니다.

from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from libs.nn.conv.minivggnet import MiniVGGNet
from preprocessing.aspectawarepreprocessor import AspectAwarePreprocessor
from preprocessing.imagetoarraypreprocessor import ImageToArrayPreprocessor
from preprocessing.simpledatasetloader import SimpleDatasetLoader
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import SGD
import matplotlib.pyplot as plt
import argparse
from imutils import paths
import numpy as np
import os

 

필요한 argument를 세팅합니다.

다음으로 명령 인수를 기준으로 이미지 경로에서 클래스 이름을 추출해 보겠습니다.

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True, help="path to input dataset")
args = vars(ap.parse_args())

# grab the list of images that we'll be describing, then extract
# the class label names from the image paths
print("[INFO] loading images...")
imagePaths = list(paths.list_images(args["dataset"]))
classNames = [pt.split(os.path.sep)[-2] for pt in imagePaths]
classNames = [str(x) for x in np.unique(classNames)]

 

디스크에서 데이터 세트를로드하고, 훈련 / 테스트 분할을 구성하고, 레이블을 인코딩합니다.

# initialize the image preprocessors
aap = AspectAwarePreprocessor(64, 64)
iap = ImageToArrayPreprocessor()

# load the dataset from disk then scale the raw pixel intensities
# to the range [0, 1]
sdl = SimpleDatasetLoader(preprocessors=[aap, iap])
(data, labels) = sdl.load(imagePaths, verbose=500)
data = data.astype("float") / 255.0

# partition the data into training and testing splits using 75% of
# the data for training and the remaining 25% for testing
(trainX, testX, trainY, testY) = train_test_split(
    data, labels, test_size=0.25, random_state=42
)

# convert the labels from integers to vectors
trainY = LabelBinarizer().fit_transform(trainY)
testY = LabelBinarizer().fit_transform(testY)

 

다음 코드 블록은 ImageDataGenerator 초기화하므로 매우 중요합니다.

aug = ImageDataGenerator(
    rotation_range=30,
    width_shift_range=0.1,
    height_shift_range=0.1,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode="nearest",
)

 

여기에서 이미지는 다음과 같습니다.

 

1. 무작위로 ± 30도 회전

2. 0.1의 비율로 수평 및 수직 이동

3. 0.2만큼 전단

4. [0.8, 1.2] 범위에서 균일하게 샘플링하여 확대

5. 무작위로 수평으로 플리핑 정확한 데이터 세트에 따라 이러한 데이터 증가 값을 조정하고 싶을 것입니다.

응용 프로그램에 따라 [10,30] 사이의 회전 범위를 보는 것이 일반적입니다. 수평 및 수직 이동은 일반적으로 [0.1, 0.2] 범위에 속합니다 (확대 / 축소 값도 동일). 이미지를 수평으로 훑어 보는 것이 클래스 레이블을 변경하지 않는 한, 항상 수평 훑어보기도 포함해야합니다.

 

# initialize the optimizer and model
print("[INFO] compiling model...")
opt = SGD(lr=0.05)
model = MiniVGGNet.build(width=64, height=64, depth=3, classes=len(classNames))
model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])

 

그러나 네트워크를 훈련시키는 사용되는 코드는 현재 이미지 생성기를 사용하고 있으므로 약간 변경해야합니다.

# train the network
print("[INFO] training network...")
H = model.fit(
    aug.flow(trainX, trainY, batch_size=32),
    validation_data=(testX, testY),
    steps_per_epoch=len(trainX) // 32,
    epochs=100,
    verbose=1,
)

모델의 .fit 메서드를 호출하는 합니다. 이제 첫 번째 매개 변수는 학습 데이터에서 새로운 학습 샘플을 생성하는 데 사용되는 데이터 증가 함수 인 aug.flow입니다. aug.flow에서는 학습 데이터와 해당 레이블을 전달해야합니다. 또한 생성기가 네트워크를 훈련 할 때 적절한 배치를 구성 할 수 있도록 배치 크기를 제공해야합니다.

 

그런 다음 validation_data를 (testX, testY)의 튜플로 제공합니다.이 데이터는 모든 generation이 끝날 때까지 유효성 검사에 사용됩니다. steps_per_epoch 매개 변수는 epoch 당 배치 수를 제어합니다. 총 훈련 샘플 수를 배치 크기로 나누고 정수로 변환하여 적절한 steps_per_epoch 값을 프로그래밍 방식으로 결정할 수 있습니다. 마지막으로 epochs는 네트워크가 훈련되어야하는 총 epoch 수를 제어합니다 (이 경우 100 epoch).

 

네트워크를 훈련 평가하고 해당 정확도 / 손실 플롯을 플로팅합니다.

# evaluate the network
print("[INFO] evaluating network...")
predictions = model.predict(testX, batch_size=32)
print(
    classification_report(
        testY.argmax(axis=1), predictions.argmax(axis=1), target_names=classNames
    )
)

# plot the training loss and accuracy
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, 100), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, 100), H.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, 100), H.history["accuracy"], label="train_acc")
plt.plot(np.arange(0, 100), H.history["val_accuracy"], label="val_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend()
plt.show()

 

위코드는 아래 명령어로 실행시킬 수 있습니다.

 python minivggnet_flowers17_data_aug.py --dataset dataset/flowers17/images/

 

Data Augmentation을 통한 Flower-17 학습과정 및 loss&accuracy plot

Data Augmentation는 훈련 데이터에서 사용하는 정규화 기술의 한 유형입니다. 이름에서 알 수 있듯이 Data Augmentation은 일련의 무작위 변환, 회전, 전단 등을 적용하여 훈련 데이터를 무작위로 생성합니다. 이러한 단순 변환을 적용해도 입력 이미지의 클래스 레이블은 변경되지 않습니다. 그러나 각 증강 이미지는 학습 알고리즘이 이전에 보지 못한 "새로운"이미지로 간주 될 수 있습니다. 따라서 우리의 훈련 알고리즘은 새로운 훈련 샘플과 함께 지속적으로 제공되어 더 강력하고 차별적인 패턴을 학습 할 수 있습니다.

 

"자연스러운"교육 샘플을 수집하는 것이 항상 더 좋지만, 데이터 확대는 작은 데이터 세트 제한을 극복하는 데 사용할 수 있습니다. 자체 훈련의 경우 실행하는 거의 모든 실험에 데이터 증가를 적용해야합니다. CPU가 이제 입력을 무작위로 변환하는 책임이 있기 때문에 약간의 성능 저하를 가져야합니다. 그러나 이러한 성능 저하는 스레드를 사용하고 네트워크 훈련을 담당하는 스레드로 전달되기 전에 백그라운드에서 데이터를 보강하여 완화됩니다.

 

Data_Augmenation.tar.gz
0.44MB

'keras > 1.Data Augmentation' 카테고리의 다른 글

2. Flower-17  (0) 2020.08.20
1. Data Augmentation  (0) 2020.08.20

+ Recent posts