TigerCow.Door


안녕하세요. 문범우입니다.

오늘은 ReLU(Rectified Linear Unit)에 대해서 알아보겠습니다.


* 해당 포스트의 모든 내용은 김성훈 교수님의 '모두를 위한 딥러닝'을 바탕으로 제작되었습니다.

관련한 상세 내용은 아래 링크를 참고해주세요.

https://hunkim.github.io/ml/




1. NN for XOR


우리가 지난 시간에 XOR문제를 위와 같은 모델로 하여 풀이를 진행해보았습니다.

실제로 텐서플로우를 이용하여 구현해보기도 하였습니다.

그때 각 유닛의 결과에 우리가 Sigmoid 함수를 붙여서 결과값이 0~1이내로 출력되게 했었습니다.



이러한 Sigmoid함수를 activation function 이라고 합니다.

각 모델들에게 어떤 값을 보내게 될 때 일정값 이상이면 active되게 하고 그렇지 않으면 active하지 않게 하기 때문에 주로 그렇게 불린다고 합니다.


그리고 우리는 아래와 같이 각각의 W, b를 만들고 layer를 이용하여 2단의 네트워크를 만들었습니다.


그럼 3단을 가진 네트워크는 어떻게 할까요?

당연히 2단때와 같이, 쉽게 구현할 수 있습니다.

이때, 제일 처음이 layer를 input layer라고 부르며, 가장 바깥쪽(마지막)에 있는 layer를 output layer라고 부릅니다. 그리고 그 사이에 있는 layer들을 hidden layer라고 합니다.


그럼 더 깊게 한번 만들어볼까요?

hidden layer가 9단이 되게끔 구현해보도록 하겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
W0 = tf.Variable(tf.random_uniform([2,5], -1.01.0), name = 'weight0')
 
W1 = tf.Variable(tf.random_uniform([5,5], -1.01.0), name = 'weight1')
W2 = tf.Variable(tf.random_uniform([5,5], -1.01.0), name = 'weight2')
W3 = tf.Variable(tf.random_uniform([5,5], -1.01.0), name = 'weight3')
W4 = tf.Variable(tf.random_uniform([5,5], -1.01.0), name = 'weight4')
W5 = tf.Variable(tf.random_uniform([5,5], -1.01.0), name = 'weight5')
W6 = tf.Variable(tf.random_uniform([5,5], -1.01.0), name = 'weight6')
W7 = tf.Variable(tf.random_uniform([5,5], -1.01.0), name = 'weight7')
W8 = tf.Variable(tf.random_uniform([5,5], -1.01.0), name = 'weight8')
W9 = tf.Variable(tf.random_uniform([5,5], -1.01.0), name = 'weight9')
 
W10 = tf.Variable(tf.random_uniform([5,1], -1.01.0), name = 'weight10')
 
b0 = tf.Variable(tf.zeros([5]), name = 'bias0')
 
b1 = tf.Variable(tf.zeros([5]), name = 'bias1')
b2 = tf.Variable(tf.zeros([5]), name = 'bias2')
b3 = tf.Variable(tf.zeros([5]), name = 'bias3')
b4 = tf.Variable(tf.zeros([5]), name = 'bias4')
b5 = tf.Variable(tf.zeros([5]), name = 'bias5')
b6 = tf.Variable(tf.zeros([5]), name = 'bias6')
b7 = tf.Variable(tf.zeros([5]), name = 'bias7')
b8 = tf.Variable(tf.zeros([5]), name = 'bias8')
b9 = tf.Variable(tf.zeros([5]), name = 'bias9')
 
b10 = tf.Variable(tf.zeros([5]), name = 'bias10')
 
L1 = tf.sigmoid(tf.matmul(X, W0) + b0)
L2 = tf.sigmoid(tf.matmul(L1, W1) + b1)
L3 = tf.sigmoid(tf.matmul(L2, W2) + b2)
L4 = tf.sigmoid(tf.matmul(L3, W3) + b3)
L5 = tf.sigmoid(tf.matmul(L4, W4) + b4)
L6 = tf.sigmoid(tf.matmul(L5, W5) + b5)
L7 = tf.sigmoid(tf.matmul(L6, W6) + b6)
L8 = tf.sigmoid(tf.matmul(L7, W7) + b7)
L9 = tf.sigmoid(tf.matmul(L8, W8) + b8)
L10 = tf.sigmoid(tf.matmul(L9, W9) + b9)
 
hypothesis = tf.sigmoid(tf.matmul(L10, W10) + b10)
cs


위와 같이 hidden layer가 총 9단이 되도록 구현해보았습니다.

그리고 텐서보드를 이용하기 위해서는 추가적으로 name_scope를 사용하면 됩니다.


그리고 이러한 모델을 실제로 훈련시키고 결과를 확인해보면 다음과 같습니다.

Accuracy 가 0.5가 나왔습니다.

왜그럴까요?

우리가 지난번에 했을때보다 더 깊고, 더 넓게 훈련을 시켰는데 오히려 더 좋지 않은 결과가 나와버렸습니다.



2. Vanishing Gradient


우리가 지난 시간에 알아본, backpropagation에 대해서 다시한번 살펴보도록 하겠습니다.


우리가 위와 같은 구조를 공부했었는데, 이때 backpropagation에서 chain rule을 사용한다고 했었습니다.

지난 포스트에서 알아본것에 따르면, 빨간 동그라미, dg/dx = y의 값을 갖게되고 이에 따라 df/dx = df/dg * dg/dx = df/dg * y 가 됩니다.

근데 이때 y가 어떤 값을 가질지 한번 살펴볼까요?

y가 input layer가 아니었다면, 다른 유닛에 통과하고 sigmoid 함수를 통과했을 것입니다. 그럼 우리가 정확한 y의 값을 알지는 못해도 sigmoid 함수의 특성때문에 0~1사이의 값을 갖는다고 생각할 수 있습니다.

그럼 이때 y의 값이 예를 들어 0.01정도라고 생각해보겠습니다.

이렇게 된다면, 다시 올라가서 df/dx = df/dg * 0.01 이 됩니다.


이렇게 되는 것의 단점이 무엇이냐면, 결국에 값들이 sigmoid 함수를 지나게 되면서 그 값이 1보다 작게 되며 경우에 따라서는 굉장히 0에 가까운 값들이 계속 곱해지게 됩니다.

그러면 결국적으로 굉장히 작은 값을 갖게 됩니다.


즉, 그렇게 되면 결과 단에서 점점 깊어질 수록 그 영향을 찾기 힘들다, 예측하기 힘들다라는 결론을 가져오게 됩니다.

이런 현상을 Vanishing gradient 라고 합니다.



3. Rectified Linear Unit, ReLU


그리고 Hilton 교수님은, 이러한 현상에 있어서 sigmoid가 잘못되었다라는 것을 찾게되었습니다.

sigmoid함수 때문에 1보다 큰 값을 가지지 못하게 되었고, 이로 인해 layer가 깊어지면서 오히려 그 값이 작아져 영향을 찾기 힘들어지기 때문입니다.

그리고 새롭게 생각한 함수가 ReLu, Rectified Linear Unit 입니다


ReLU 함수는 단순합니다. 입력값이 0보다 작을 때는 아예 non-activate로 꺼버리고, 0보다 클때에는 그 값을 그대로 반환합니다.


이러한 ReLU를 사용하는 방법도 매우 간단합니다.

단순히 우리가 sigmoid를 사용하던 곳에 대신 ReLU를 사용하면 됩니다.

물론 텐서플로우에서도 위와 같이 매우 간단하게 사용할 수 있습니다.


실제로 우리가 위에서 제대로 값을 얻지못한 9단 hidden layer를 가진 모델에서 sigmoid 대신 ReLU를 사용하면 다음과 같은 cost를 가지게 됩니다.


ReLU를 여러번 돌리면서 약간의 차이는 존재하지만, sigmoid에 비해서는 훨씬 더 올바른 학습을 가지는 것을 볼 수 있습니다.

물론, layer에서 제일 마지막에선 sigmoid함수를 사용하여 결과 값이 0~1 사이로 나오게끔 해야합니다.


오늘 우리가 알아본 ReLU 이외에도 아래와 같이 다양한 activation function이 있습니다.



블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요


안녕하세요.

이번 포스팅에서는 Logistic (regression) Classification 에 대해서 알아보도록 하겠습니다.


* 해당 포스트의 모든 내용은 김성훈 교수님의 '모두를 위한 딥러닝'을 바탕으로 제작되었습니다.

관련한 상세 내용은 아래 링크를 참고해주세요.

https://hunkim.github.io/ml/



1. Logistic Classification


오늘 살펴볼 Logistic Classfication은 여러 classification 알고리즘 중에서도 굉장히 정확도가 높다고 알려져 있습니다.

따라서 우리가 정확히 학습하고 이해한다면 이러한 알고리즘을 실전문제에 바로 적용해 볼 수 있을 것 입니다.

추후 우리가 알아볼 내용에 있어서도 굉장히 중요한 요소가 되니 확실히 이해해야 합니다.


먼저, 우리가 전에 학습했던 Linear Regression에 대해서 잠깐 살펴보겠습니다.



위의 사진에서 나오듯, 선형적인 Hypothesis 식을 두고, 이러한 우리의 가설과 실제 값의 차이를 나타내는 Cost 함수를 세웠습니다. 그리고 그러한 Cost 함수를 통해 Cost를 최소로 하는 것을 알아보았습니다.

Cost 함수를 살펴보면 위의 사진에서와 같이 2차 함수꼴로 그래프가 그려지는 것을 알 수 있고, 이를 통해 우리는 그래프에서 기울기를 확인하며 그 최저점, cost가 최소화 되는 값을 찾도록 하였습니다.

그리고 이를 Gradient decent 함수를 통해 cost의 최저점을 찾아내었습니다.


즉, 위에서 나오는 3가지, Hypothesis, Cost, Gradient decent 를 통해서 Linear Regression을 직접 구현할 수 있습니다.


그리고 우리가 앞으로 살펴볼 Classification도 매우 유사합니다.

그전의 것들은 단순히 숫자를 예측하는 것이었다면, 오늘 우리가 살펴볼 것은 Binary Classification으로써 두가지 중 하나를 고르는 알고리즘 입니다.



이러한 알고리즘은 Spam Email Detection이나 Facebook feed 등에서 사용됩니다.

즉 이러한 것들은 0이나 1로 encoding 됨으로써 e-mail이 spam인지 ham인지 분류됩니다.

또한 최근에는 뇌과학이나, 주식시장 등에서도 새롭게 사용되고 있습니다.



그럼 오늘 우리는 보다 쉬운 예제로 시작을 해보도록 하겠습니다.

오늘 다루게 될 모델로는, 학생이 몇시간을 공부했을때 시험이 통과하는지 떨어지는지를 예측해보는 모델입니다.



예를 들어 2시간, 3시간 한 친구는 시험에서 떨어지고, 6시간, 7시간 한 친구는 시험에 통과한다고 볼 수 있습니다.

그런데 이것을 Linear Regression으로는 예측하지 못할까요?

이것에 대해서는 두가지 문제점이 있습니다.


먼저, 아래 그래프에서 그려진 것을 살펴봅니다.


위의 문제를 Linear Regression으로 푼다고 생각해 보았을 때, 우리가 위의 그래프에서 빨간점들과 같은 데이터를 통해 학습하여 빨간색 그래프를 얻었다고 가정합니다. 그럼 대략적으로 파란색 선과 같은 기준으로 시험에 대해 pass 인지 fail 인지 예측한다고 생각할 수 있습니다.

하지만 hours 가 매우 큰 x 데이터를 추가적으로 학습한다면 그래프는 아래와 같이 변하게 될 수 있습니다.




즉 우리가 처음에 학습하여 확인한 어떠한 기준점(그림에서는 검정색 점선)과 새롭게 학습한 그래프와 함께 생각하면 합격임에도 불구하고 떨어진 것으로 인식되는 데이터가 있을 수 있습니다.


또한 두번째 문제로는, 우리가 다루고자 하는 Classification에서는 0이나 1로 답이 나와야합니다.

하지만 Linear Regression에서는 그보다 큰 값이 나올 수 있습니다.

예를 들어 W = 0.5, b = 0으로 두고 가정을 했다고 합시다.

그리고 x가 1, 2, 5, 10이라는 값을 가진 모델을 통해 학습을 하였는데 갑자기 x에 100이라는 값이 들어왔을때 x에 W(=0.5)를 곱하게 되면 매우 큰 값이 나오게 됩니다.



이러한 점들때문에 사람들은 Linear Regression에서 사용하면 Hypothesis 함수에서 입력값에 상관 없이 0 또는 1사이의 값을 만들어주는 함수가 없는지 찾아보게 됩니다.


그렇게 해서 찾게된 함수가 아래사진입니다.



위와 같은 그래프는

sigmoid function(시그모이드 함수)

또는 Logistic function(로지스틱 함수)라고 합니다.


이러한 그래프를 만들어 내는 함수를 통해 우리는 Logistic Hypothesis 식을 아래와 같이 세우게 됩니다.



이렇게 Logistic Classification에 대해 알아보았습니다.

이제 다음 포스팅에선 우리가 Linear Regression을 학습할 때 했던 것처럼, Cost 함수에 대해서도 알아보고 그러한 Cost를 최소화 하는 방법에 대해서도 알아보겠습니다.





블로그 이미지

Tigercow.Door

Back-end / Python / Database / AI / Algorithm / DeepLearning / etc

댓글을 달아 주세요