UOMOP

성능 향상 using Batch_normalization 본문

Ai/DL

성능 향상 using Batch_normalization

Happy PinGu 2022. 2. 7. 17:25
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.layers import Input, Conv2D, Activation, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization
from tensorflow.keras.optimizers import Adam, RMSprop

# label 번호 순으로 target값 나열해주기
NAMES = np.array(["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"])
 
# Scaling
def make_zero_to_one(images, labels) :
    
    images = np.array(images/255., dtype = np.float32)
    labels = np.array(labels, dtype = np.float32)
    
    return images, labels

# 테스트 셋, 검증 셋의 정확도 비교
def compare_acc(result) :
    
    plt.plot(result.history["accuracy"], label = "tr_acc")
    plt.plot(result.history["val_accuracy"], label = "val_acc")
    plt.xlabel("epochs")
    plt.ylabel("accuracy")
    plt.title("compare acc")
    plt.legend()
    plt.show()
    
    
(train_images, train_labels), (test_images, test_labels) = cifar10.load_data()

train_images, train_labels = make_zero_to_one(train_images, train_labels)
test_images, test_labels   = make_zero_to_one(test_images, test_labels)

input_size = (train_images.shape[1])
input_tensor = Input(shape = (input_size, input_size, 3)) 
# input data는 항상 배치 크기를 제외한 3차원이고, RGB기에 channel은 3

x = Conv2D(filters = 32, kernel_size = (3, 3), padding = "same")(input_tensor)
# x = BatchNormalization()(x)
x = Activation("relu")(x)

x = Conv2D(filters = 32, kernel_size = (3, 3), padding = "same")(x)
# x = BatchNormalization()(x)
x = Activation("relu")(x)
x = MaxPooling2D(pool_size = (2, 2))(x)

x = Conv2D(filters = 64, kernel_size = (3, 3), padding = "same")(x)
# x = BatchNormalization()(x)
x = Activation("relu")(x)

x = Conv2D(filters = 64, kernel_size = (3, 3), padding = "same")(x)
# x = BatchNormalization()(x)
x = Activation("relu")(x)
x = MaxPooling2D(pool_size = (2, 2))(x)

x = Conv2D(filters = 128, kernel_size = (3, 3), padding = "same")(x)
# x = BatchNormalization()(x)
x = Activation("relu")(x)

x = Conv2D(filters = 128, kernel_size = (3, 3), padding = "same")(x)
# x = BatchNormalization()(x)
x = Activation("relu")(x)
x = MaxPooling2D(pool_size = (2, 2))(x)

x = Flatten(name = "flatten")(x)
x = Dropout(rate = 0.5)(x)
x = Dense(300, activation = "relu", name = "fc1")(x)
x = Dropout(rate = 0.3)(x)
output = Dense(10, activation = "softmax", name = "output")(x)


model = Model(inputs = input_tensor, outputs = output)

model.compile(optimizer = Adam(), loss = "sparse_categorical_crossentropy", metrics = ["accuracy"])

result_1 = model.fit(train_images, train_labels, batch_size = 64, epochs = 30, validation_split = 0.15)

이후, BatchNormalization 코드의 주석을 해제한 후 다른 model에 저장하여 성능을 저장한다.

fis, axs = plt.subplots(nrows = 1, ncols = 2, figsize = (22, 6))

axs[0].plot(result_1.history["accuracy"], label = "tr_acc_before_BN")
axs[0].plot(result_2.history["accuracy"], label = "tr_acc_after_BN")
axs[0].set_title("tr_acc")
axs[0].set_xlabel("epochs")
axs[0].set_ylabel("acc")
axs[0].legend()

axs[1].plot(result_1.history["val_accuracy"], label = "val_acc_before_BN")
axs[1].plot(result_2.history["val_accuracy"], label = "val_acc_after_BN")
axs[1].set_title("val_acc")
axs[1].set_xlabel("epochs")
axs[1].set_ylabel("acc")
axs[1].legend()

plt.show()

Batch Normalization을 적용시켰을 때, 더 좋은 성능을 보여주는 것을 확인할 수 있다. 

weight들의 가중합이 activation을 거치기 직전의 정규화시키는 과정이다. Batch의 weight와 값이 모두 다르기 때문에 가중합의 크기가 매번 들쑥날쑥할 수 있다. 신경망 내부의 각 층을 통과할 때마다 입력 데이터의 분포가 조금씩 달라지게 되는 것이다. 이러한 데이터를 이용해서 가중치를 업데이트하면 비교적 부정확한 결과가 도출될 수 있기 때문에 Conv Layer 이후에 Batch Normalization을 적용한 후, 활성화 함수를 거치도록 한다.

 

 

 

 

 

'Ai > DL' 카테고리의 다른 글

성능 향상 using batch size  (0) 2022.02.09
성능 향상 using shuffle  (0) 2022.02.09
feature map size 계산  (0) 2022.02.07
CNN model 생성  (0) 2022.02.06
Functional API  (0) 2022.02.06
Comments