본문 바로가기

KT AIVLE SCHOOL

[5주차] 딥러닝

목차

1. 활성화 함수

2. 기본 모델 구조

3. 배치정규화와 드롭아웃

4. EarlyStopping과 val_loss

5. 모델 사용 예시

 

 

 

1. 활성화 함수

시그모이드(sigmoid) 함수 (activation = 'sigmoid')

$$ f(x)=\frac{1}{1+e^{-x}} $$

값의 범위가 0에서 1사이

이진 분류 문제의 출력층에서 주로 사용

단점 : 그래디언트 소실 문제(Vanishing Gradient Problem)가 발생할 수 있음

 

 

하이퍼볼릭 탄젠트(tanh) 함수 (activation = 'tanh')

$$ f(x)=\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}} $$

값의 범위가 -1에서 1사이

시그모이드 함수보다 그래디언트 소실 문제가 덜 함

단점 : 그래디언트 소실 문제 여전히 존재

 

 

렐루(ReLU) 함수 (activation = 'relu')

$$ f(x)=max(0,x) $$

모든 양수를 그대로 반환하고, 0이하의 값은 0으로 반환

컴퓨팅 리소스가 적게 들고, 수렴 속도가 빠름

단점 : 음수 값에 대해 출력이 0이므로, 뉴런이 죽을 수 있음(Dead ReLU)

 

 

리키 렐루(leakyReLU) 함수 (activation = 'leaky_relu')

$$ f(x)=max(\alpha x,x) $$

음수 값에 대해 작은 기울기를 가지며, 뉴런이 죽는 문제를 해결하려고 함

알파는 작은 양수(예: 0.01)

 

 

스위시(Swish) 함수 (activation = 'swish')

$$ f(x)=x\cdot \sigma (x) $$

ReLU와 비슷한 특성을 가지면서도, 그래디언트 소실 문제를 완화

다양한 문제에 대해 좋은 성능을 보임

 

 

소프트맥스(Softmax) 함수 (activation = 'softmax')

$$ P(y_{i})=\frac{e^{y_{i}}}{\sum_{j-1}^{K}e^{y_{j}}} $$

다중 클래스 분류 문제의 출력층에서 사용

각 클래스에 대한 확률을 계산

식에서 P(y_i)는 i번째 클래스가 정답일 확률, y_i는 i번째 클래스에 대한 모델의 출력값, K는 클래스의 개수

 

 

Maxout 함수

$$ maxout(z_{1},z_{2},\cdots,z_{k})=max(z_{1},z_{2},\cdots,z_{k}) $$

입력 중 최댓값을 취하는 방식으로 작동

이 함수는 여러 개의 선형 입력 중에서 최대값을 선택하여 비선형 특성을 가짐

다양한 함수 형태를 근사할 수 있어서, 신경망의 표현력을 향상시키는데 도움이 됨

model.add(tf.keras.layers.Dense(units))
model.add(tf.keras.layers.Maxout(num_units)) 와 같이 레이어를 추가하는 방식으로 사용

 

 

ELU (Exponential Linear Unit) 함수 (activation = 'elu')

$$ ELU(x)=\begin{cases} x & \text{ if }\; x>0 \\ \alpha (e^{x}-1) & \text{ if }\: x\leq 0 \end{cases} $$

ReLU와 비슷하지만, 음수 입력에 대해서는 알파에 비례한 음수 값을 출력

따라서 ELU는 음수 입력에 대해서도 그래디언트를 가질 수 있으며, 학습 중에 뉴런이 '죽는'현상 완화

식에서 알파는 사용자가 정의하는 하이퍼파라미터

 

 

SELU (Scaled Exponential Linear Unit) 함수 (activation = 'selu')

$$ SELU(x)=\lambda \begin{cases} x & \text{ if }\; x>0 \\ \alpha (e^{x}-1) & \text{ if }\: x\leq 0 \end{cases} $$

자기 정규화 활성화 함수

네트워크의 각 층에서 출력의 평균과 분산이 일정한 값을 유지할 수 있어 그래디언트 소실 문제 완화

식에서 람다와 알파는 스케일과 알파 파라미터

 

 

Softplus 함수 (activation = 'softplus')

$$ Softplus(x)=log(1+e^{x}) $$

ReLU 함수의 부드러운 버전

ReLU와 유사한 특성을 가지면서 입력이 0 주변일 때 기울기가 0이 되지 않아 그래디언트 소실 문제를 완화

 

 

Softsign 함수 (activation = 'softsign')

$$ Softsign(x)=\frac{x}{1+|x|} $$

하이퍼볼릭 탄젠트 (tahn)함수의 변형

입력값을 입력값의 절댓값과 1의 합으로 나누어 부드럽게 만듦

 

 

 

2. 기본 모델 구조

출처 : https://www.freshworks.com/ko/freshdesk/kblogs/deep-learning/

 

# 텐서플로우로 작성
X = tf.keras.Input(shape=[1])
Y = tf.keras.layers.Dense(1)(X)
model = tf.keras.Model(X, Y)

# class로 작성
class MyModel(tf.keras.Model):
    def __init__(self, **kwargs):
        super(MyModel, self).__init__(**kwargs)
        self.dense = tf.keras.layers.Dense(1)
        
    def call(self, inputs):
        return self.dense(inputs)
model = MyModel()

# 모델 컴파일
model.compile(loss='mse')

# 모델 학습
model.fit(독립, 종속, epochs=100)

 

# 히든레이어 추가
X = tf.keras.Input(shape=[1])
H = tf.keras.layers.Dense(2, activation='swish')(X)
Y = tf.keras.layers.Dense(1)(H)
model = tf.keras.Model(X, Y)

# class로 작성
class MyModel(tf.keras.Model): # 상속받을 부모클래스를 괄호안에 넣음
    def __init__(self, **kwargs):
        super(MyModel, self).__init__(**kwargs)
        self.dense1 = tf.keras.layers.Dense(2, activation='swish') # self.dense1과 self.dense2에 함수를 넣음
        self.dense2 = tf.keras.layers.Dense(1)

    def call(self, X):  # 위 모델준비 주석과 같은 구조 (데이터가 들어오면 실행)
        H = self.dense1(X)
        Y = self.dense2(H)
        return Y
model = MyModel()

 

 

 

3. 배치 정규화와 드롭 아웃

3.1 배치 정규화(Batch Normalization)

배치 정규화(Batch Normalization, BatchNorm)는 딥러닝 모델의 학습 과정에서 각 층의 입력을 정규화(평균0,분산1)하는 방법이다. 이를 통해 학습의 안정성과 속도를 향상시킬 수 있다.

내부 공변량 변화(Internal Covariate Shift)를 줄이는데 사용된다. 내부 공변량 변화란 학습과정에서 각 층의 입력 분포가 변하는 현상을 말한다.

각 층에서 활성화 함수의 입력이 너무 크거나 작은 값을 가지면, 그래디언트 소실 또는 그래디언트 폭발 문제가 발생하므로 배치 정규화를 통해 이러한 문제를 완화하고 학습을 빠르게 진행할 수 있다.

 

X = tf.keras.Input(shape=[4])
H = tf.keras.layers.Dense(64, activation='swish')(X)
H = tf.keras.layers.BatchNormalization()(H)          # Dense 다음에 넣으면 성능 높아짐 (Normalization 기법중 자주 사용되는 BatchNormalization)
H = tf.keras.layers.Dense(64, activation='swish')(H)
H = tf.keras.layers.BatchNormalization()(H)          # 위와 동일
Y = tf.keras.layers.Dense(3,activation='softmax')(H)

위의 코드와 같이 Dense 다음에 H = tf.keras.layers.BatchNormalization()(H) 를 넣어 정규화 시키면 된다.

 

 

3.2 드롭 아웃(Dropout)

딥러닝 학습에서 과적합(Overfitting)을 방지하기 위한 정규화 기법으로 학습 과정 중에서 무작위로 일부 뉴런을 선택하여 그 뉴런들을 비활성화시키는 방법.

신경망이 특정 뉴런에 의존하지 않게 되어, 일반화(generalization) 성능이 향상

X = tf.keras.Input(shape=[784])

H = tf.keras.layers.Dense(128)(X)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation('swish')(H)  # Dense에서 activation하지말고 batchnormalization 한 후 activation 해야 성능이 좋음('swish'가 음수를 전부 없애기 때문)

H = tf.keras.layers.Dropout(0.5)(H)         # 드랍아웃은 앙상블 효과로 오버피팅을 해결한다. => 일부 특징을 0으로 만들어 해당 특징 없어도 유추해 찾기 위함 (학습을 못하게 방해하므로 학습을 못해도 최종 성능은 좋음)
H = tf.keras.layers.Dense(64)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation('swish')(H)

H = tf.keras.layers.Dropout(0.5)(H)
H = tf.keras.layers.Dense(32)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation('swish')(H)

H = tf.keras.layers.Dropout(0.3)(H)         # Dropout(0.3) : 각 뉴런이 30%의 확률로 학습과정에서 비활성화, 같은 방법으로 드롭아웃 비율을 설정 가능
Y = tf.keras.layers.Dense(10, activation='softmax')(H)

위의 코드와 같이 Dense 이전에 H = tf.keras.layers.Dropout(비율)(H)를 넣으면 성능이 좋다.

 

 

 

4. EarlyStopping과 val_loss

4.1 EarlyStopping

딥러닝 모델을 훈련할 때 사용하는 콜백 함수로, 특정 조건이 충족되면 모델의 훈련을 조기에 중단하는 기능을 수행

이를 통해 모델이 과적합되는 것을 방지하고 훈련 시간을 단축할 수 있다.

주요 파라미터는 'monitor', 'patience', 'restore_best_weights'가 있다.

monitor : 조기 중단의 기준이 되는 성능 지표를 지정(디폴트는 monitor='val_loss')

patience : 성능 개선이 지정된 에포크 동안 이루어지지 않을 경우 훈련이 중단 

restore_best_weights=True : 멈춘 후, 최적이었던 값으로 모델의 파라미터 값들을 되돌리라는 뜻

 

4.2 val_loss

검증 데이터셋(validation dataset)에 대한 모델의 손실 함수 값

손실 함수(loss function)는 모델의 예측 값과 실제 타깃 값의 차이를 수치화하는 함수로, 이 값이 작을수록 모델의 성능이 좋다고 판단, 따라서 loss만 가지고 판단하지 않고 따로 빼놓은 검증 데이터셋의 loss인 val_loss도 같이 판단

# 제일 loss와 val_loss가 낮은 epoch 기준으로 10개동안 더 낮은 epoch가 안나오면 멈춤, monitor='val_loss'가 디폴트
early = tf.keras.callbacks.EarlyStopping(patience=10, restore_best_weights=True)
result = model.fit(x_train,y_train,epochs=100000000, batch_size=128,
         validation_split=0.2,
        callbacks=[early]) # callbaks.EarlyStopping 사용

위의 코드를 통해 earlystopping을 콜백 할 수 있다.

 

model.evaluate(x_test, y_test)

evaluate를 통해 학습한 모델의 성능을 확인해 보자.

 

 

 

5. 모델 사용 예시

전체 코드를 통해 딥러닝 사용 방법에 대해 학습하자.

X = tf.keras.Input(shape=[32, 32, 3])
H = tf.keras.layers.Flatten()(X)

H = tf.keras.layers.Dropout(0.7)(H)
H = tf.keras.layers.Dense(128)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation('swish')(H)

H = tf.keras.layers.Dropout(0.6)(H)
H = tf.keras.layers.Dense(128)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation('swish')(H)

H = tf.keras.layers.Dropout(0.6)(H)
H = tf.keras.layers.Dense(128)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation('swish')(H)

H = tf.keras.layers.Dropout(0.6)(H)
H = tf.keras.layers.Dense(128)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation('swish')(H)

H = tf.keras.layers.Dropout(0.3)(H)
Y = tf.keras.layers.Dense(10, activation=tf.keras.activations.softmax)(H)
model = tf.keras.Model(X, Y)
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.00001),
              loss=tf.keras.losses.SparseCategoricalCrossentropy(),
              metrics=tf.keras.metrics.SparseCategoricalAccuracy())
model.summary()

early = tf.keras.callbacks.EarlyStopping(patience=10, restore_best_weights=True)
result = model.fit(x_train,y_train,epochs=100000000, batch_size=128,
         validation_split=0.2,
        callbacks=[early])
        
model.evaluate(x_test,y_test)