본문 바로가기

Deep Learning

Logistic Classification의 HCG

H : 가설

C : cost 함수

G : Gradient descent, 미니멀 알고리즘

 

Classification도 Linear Regression과 매우 유사하다.

Binary Classification은 둘 중의 한개를 고르는 것으로 ML에서 많이 활용된다.

 

[예시]

Spam Detection : spam(1) or ham(0)

Facebook feed : show(1) or hide(0)

Credit Card Fraudulent Transaction detection : legitimate(0) /fraud(1)

주식 시장에서 살까 말까 : 산다(1), 안산다(0)

시험 공부 : Pass(1), Fail(0)

 

Linear Regression을 이용해 Binary Classification을 구현할 수 있다.

 

 

x축이 공부한 시간, y축이 시험 결과(Pass/Fail)을 linear regression으로 나타낸다고 하면 위 그래프처럼 나타낼 수 있다.

이 때 두 가지 문제가 발생한다.

 

1) 한 학생이 50시간 이상 공부한 경우 - 그래프의 기울기가 변화하여 실제로 Pass한 사람도 fail로 예측할 수 있다.

2) H(x) = Wx + b 형태이기 때문에, Y가 0과 1로 떨어지지 않는다.

 

이 문제를 해결하기 위해 sigmoid 함수를 사용할 수 있다.

 

 

sigmoid 공식은 g(z) = 1 / (1 + e^-z) 이다.

위 그래프 모양과 같이 z가 아무리 커도 g(z)는 1을 넘지 않고, z가 아무리 작아도 g(z)가 0 이하가 되지 않는다.

 

따라서 Logistic Hypothesis H(x)를 아래처럼 구할 수 있다.

 

 

H(가설)을 구했으니 C(Cost function)을 구해보자.

Regression과 같이 gradient descent 알고리즘을 사용한다고 하면, 아래의 그림처럼 굴곡진 그래프가 나와서 제대로 된 최소값을 측정하지 못하게 된다.

 

 

c(H(x),y) = y가 1일 때 : -log(H(x))

              = y가 0일 때 : -log(1 - H(x)) 

 

이렇게 나누는 이유는 log 그래프를 보면 알 수 있다.

 

 

 

위는 g(z) = -log(z) 그래프이다.

y = 1이고, 실제 값이 1이었을 때 cost값 g(z) = 0에 수렴하고,

y = 0이고, 실제 값이 1이었을 때 cost값 g(z) = 무한대에 수렴한다.

따라서 값이 일치하지 않을 때 cost function의 결과가 커질 수 있다.

 

 

반면에 g(z) = log(z) 그래프는

y = 0이고, 실제 값이 0이었을 때 cost = 0

y = 1이고, 실제 값이 0이었을 때 cost = 무한대

라는 결과를 만들 수 있다.

 

* 이 두 경우를 합치면 gradient descent와 같이 밥그릇 모양의 결과를 만들 수 있다.

 

따라서, cost function은 다음과 같은 식으로 구성된다.

 

 

어려워 보이지만 y가 1일 경우 식 뒷부분은 자동으로 0이 되어 앞부분만 계산하면 된다.

y가 0일 때는 식의 뒷부분만 계산하면 되므로, 이 식을 사용하면 y가 0인지 1인지 체크하는 if문이 없어도 된다.

 

C까지 구했으므로, G를 구해보자.

 

Regression과 마찬가지로, 위 cost식을 미분하여 기울기를 구할 수 있다.

 

프로그래밍할 때는 GradientDescentOptimizer라는 이미 정의된 클래스를 사용하면 된다.

 

다음은 이를 실습한 코드이다.

 

import tensorflow as tf

x_data = [[1,2], [2,3], [3,1], [4,3], [5,3], [6,2]]
y_data = [[0], [0], [0], [1], [1], [1]]

# placeholders for a tensor that will be always fed.

X = tf.placeholder(tf.float32, shape=[None,2])
Y = tf.placeholder(tf.float32, shape=[None,1])

W = tf.Variable(tf.random_normal([2,1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')

# Hypothesis using sigmoid : tf.div(1., 1. + tf.exp(tf.matmul(X,W)+b))

hypothesis = tf.sigmoid(tf.matmul(X,W) + b)

# cost / loss function
cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1-hypothesis))

train = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(cost)

# Accuracy computation
# True if hypothesis > 0.5 else False
predicted = tf.cast(hypothesis > 0.5, dtype = tf.float32)
# True = 1.0, False = 0.0으로 cast됨
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype = tf.float32))

with tf.Session() as sess :
    sess.run(tf.global_variables_initializer())
    
    for step in range(10001):
        cost_val, _ = sess.run([cost, train], feed_dict={X:x_data, Y:y_data})
        if step % 200 == 0 :
            print(step, cost_val)
            
    h, c, a = sess.run([hypothesis, predicted, accuracy],
                      feed_dict={X:x_data, Y:y_data})
    print("\nHypothesis: ",h,"\nCorrect (Y): ",c,"\nAccuracy: ", a)

 

결과는 다음과 같다.

 

0 3.9143817
200 0.7535921
400 0.54512507
600 0.46096754
...
...
9200 0.15186875
9400 0.14958338
9600 0.14736608
9800 0.14521383
10000 0.14312391

Hypothesis:  [[0.02810644]
 [0.15511759]
 [0.29200247]
 [0.7873213 ]
 [0.943256  ]
 [0.98141104]] 
Correct (Y):  [[0.]
 [0.]
 [0.]
 [1.]
 [1.]
 [1.]] 
Accuracy:  1.0

 

y^hat이 실제 값 y와 100% 일치하는 결과를 확인할 수 있다.

 

※ inflearn 모두를 위한 딥러닝 강좌를 듣고 정리한 내용입니다.