본문 바로가기

AI

Activation function과 Weight initialization

Activation Functions


많은 레이어의 연결

 Deep learning시 여러개의 레이어를 연결하여서 깊게 구조를 구현하게 되는데 이때, 너무 깊게 레이어를 구성하게 되면 gradient vanishing 문제에 의해서 이전레이어로 전달되어야할 미분값이 사라져 전달되지 않게 된다. 

이를 해결하기 위해서 activation function에 변화를 주어야했다. 기존에는 sigmoid를 activation function으로 많이 사용했었는데 sigmoid는 output이 0~1사이의 값만을 가지게 되므로 BackPropagation 과정에서 1 이하의 값만이 연속적으로 곱해지게 되어 미분값이 점점 사라지게 된다.(0으로 수렴하게 된다).

결국 sigmoid 말고 다른 activation function을 사용하게 되며 gradient vanishing 문제의 돌파구를 찾을 수 있게 되었다. 대표적인 것이 relu 함수이다. relu 함수의 경우 0~1 사이의 값을 가지는 것이 아니라 인풋이 0보다 큰 경우 해당 인풋값을 그대로 반환하므로 시그모이드에 비해 훨씬 gradient vanishing 문제에 대해서 강건한 효과를 보인다.

 

비교를 해보자


Activation function으로 sigmoid를 적용한 경우

tf.model = tf.keras.Sequential([
    tf.keras.layers.Dense(units=10, input_dim=2, activation='sigmoid'),
    tf.keras.layers.Dense(units=10, activation='sigmoid'),
    tf.keras.layers.Dense(units=10, activation='sigmoid'),
    tf.keras.layers.Dense(units=10, activation='sigmoid'),
    tf.keras.layers.Dense(units=10, activation='sigmoid'),
    tf.keras.layers.Dense(units=10, activation='sigmoid'),
    tf.keras.layers.Dense(units=10, activation='sigmoid'),
    tf.keras.layers.Dense(units=10, activation='sigmoid'),
    tf.keras.layers.Dense(units=1, activation='sigmoid'),
])

 

결과

1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 98ms/step - accuracy: 0.7500 - loss: 0.4778
Accuracy:  0.75

 

 이 문제는 사실 위와 같이 많은 레이어가 필요하지도 않다. 두개 정도의 레이어만 있어도 충분히 100%의 accuracy를 보일수 있다. 하지만 오히려 레이어를 여러개 추가하고 activation function으로 sigmoid를 적용했더니 gradient vanishing 문제가 발생하여서 오히려 학습이 제대로 되지 않은 모습이다.

 

Activation function으로 relu를 적용한 경우

tf.model = tf.keras.Sequential([
    tf.keras.layers.Dense(units=10, input_dim=2, activation='relu'),
    tf.keras.layers.Dense(units=10, activation='relu'),
    tf.keras.layers.Dense(units=10, activation='relu'),
    tf.keras.layers.Dense(units=10, activation='relu'),
    tf.keras.layers.Dense(units=10, activation='relu'),
    tf.keras.layers.Dense(units=10, activation='relu'),
    tf.keras.layers.Dense(units=10, activation='relu'),
    tf.keras.layers.Dense(units=10, activation='relu'),
    tf.keras.layers.Dense(units=1, activation='relu'),
])

 

결과

이번에는 sigmoid에서 relu로 activation function만 바꿔서 학습을 진행했다.

1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 101ms/step - accuracy: 1.0000 - loss: 1.1921e-07
Accuracy:  1.0

 loss와 정확도 모두 크게 개선된 모습을 볼 수 있다. 확실히 relu가 sigmoid에 비해서 gradient vanishing 문제에 대해서 강건하기 때문에 효과적으로 학습이 진행이 되었음을 알 수 있다.

효과적인 weight 초기화

 동일한 코드를 실행해서 학습을 시켜보더라도 매번 실행 결과가 조금씩 다른 것을 확인 할 수 있다. 예를 들어 첫번째 학습에서는 좀더 학습이 잘되서 빠르게 cost가 낮은 값으로 수렴하게 되고, 두번째 실행에서는 첫번째에 비해서 좀 더 늦게 수렴을 하게된다. 이는 왜 그럴까?
바로 실행시마다 서로 다른 weight 값을 사용하기 때문이다. 초기에 사용하는 weight 값이 달라지니 매번 그 수행 결과가 달라지게 되는 것이다.

 그렇다면 이러한 질문이 생기게 된다. 그렇다면 최적의 weight 값을 구해서 최적의 값으로 학습을 시키면 되지 않을까? 그렇다면 최적의 weight를 어떻게 찾을 수 있을까?

 

 일단 weight를 0으로 초기화해서는 안된다. 왜냐하면 back propagation 과정에서 w가 0이 되어있는 경우 gradient가 0이 되어 제대로 gradient가 전달되지 않는 문제가 발생하기 때문이다.

RBM

 최적의 weight를 찾기위한 방법 중 하나로 RBM(Restricted Boatman Machine)을 사용한다.

RBM은 인접한 두개 레이어 사이의 weight를 최적화하는 방법론이다. forward 과정에서 이전레이어의 값을 기존의 weight로 계산한 후 다음 레이어로 값을 넘겨준다. backward 과정에서는 다음 레이어의 노드들의 값을 weight로 다시 계산하여 이전 레이어의 노드로 값을 넘겨주는데, 이때 forward 과정에 이전 레이어에 있던 노드의 원래 값과 backward 과정에서 계산된 값의 차가 최소가 되게 weight를 계산하게 된다.

 여러개의 레이어로 구성된 네트워크의 경우 인접한 레이어들끼리 RBM을 반복적으로 수행하면 된다.

Xavier intialization

 RBM은 좀 복잡하다. 때문에 다른 방법을 사용한다.

w = np.random.randn(fan_in. fan_out)/np.sqrt(fan_in)

위 식이 바로 xavier initialization이다. 기존 rbm과는 달리 단지 input, output의 개수로만 w를 지정하게 되어 굉장히 단순하게 계산이 가능하다.

He initailization

w = np.random.randn(fan_in. fan_out)/np.sqrt(fan_in/2)

He initialization의 경우 Xavier와 유사하나 fan_in / 2로 변경되었다는 차이가 존재한다.


Tensorflow에서의 initializer는 아래의 링크를 참조하자.

Module: tf.keras.initializers  |  TensorFlow v2.16.1

 

적용방식은 레이어에 kernel_initializer 매개변수에 initializer값을 넣어주면 된다.

tf.model = tf.keras.Sequential()
tf.model.add(tf.keras.layers.Dense(input_dim=784, units=256, kernel_initializer='glorot_normal', activation='relu'))

'AI' 카테고리의 다른 글

RNN  (0) 2024.08.25
CNN  (0) 2024.08.25
Overfitting 방지  (0) 2024.08.20
Multinomial Classification  (0) 2024.08.20
Logistic Regression  (0) 2024.08.19