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 모두를 위한 딥러닝 강좌를 듣고 정리한 내용입니다.
'Deep Learning' 카테고리의 다른 글
ML의 실용과 몇가지 팁 (0) | 2019.04.21 |
---|---|
Multinomial의 개념과 Softmax Classification 구현 (0) | 2019.04.21 |
TensorFlow로 파일에서 데이터 읽어오기 (0) | 2019.04.21 |
여러 feature의 linear regression (0) | 2019.04.15 |
Linear Regression의 cost 최소화 알고리즘의 원리 (0) | 2019.04.14 |