이번 게시물은 logistic_regression에서도 Binary Classification 이다.
먼저 logitistic regression에 대해서 살펴보자
logistic regression은 선들로 인해 구역을 구분지어놔서, 실제 데이터가 어디에 속하는지 classification을 쓸 수 있다.
예제로 binary classification을 이용하여 (0, 1)을 이용하여 학습, 악성종양인지 양성종양인지 진단가능하다.
우리가 실제 데이터를 다루다보면, 실수를 논하기 때문에 값들이 커지게 된다.
그래서 sigmoid, (1/ (1+e^x)) 함수를 쓰니 0~1로 수렴하면서 데이터들간의 간격이 줄었고,
hypothesis를 0-1로 맞추기위해 sigmoid를 쓴다.
import tensorflow as tf
tf.set_random_seed(777) # for reproducibility, 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.
# weight의 shape를 항상 신경써야한다.
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)))
hypothesis = tf.sigmoid(tf.matmul(X, W) + b)
tf.set_random_seed(777)은 내가 Tensorflow에 W,b를 임의로 넣을 때, 그 넣는 난수의 처음 값을 항상 일정하게 준다. 저 seed를 지정하지 않으면, 내가 python 파일을 실행할 때마다 cost, W, b 값들은 항상 변할 것이다.
X, Y를 똑같이 placeholder로 정의하였다. 여기서 우리는 앞으로 data의 형태를 알 것이며, 입력받는 data의 format을 알기 때문에, shape를 [None, 2],[None, 1] 로 해두었다. (항상 X, Y, W, b의 shape는 신경쓰기!!!)
Hypothesis 는 tf.sigmoid를 써서 연산하였다.
# cost/loss function
cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis))
우리는 여기서 sigmoid 함수의 cost 함수가 달라짐을 알 수 있다. cost함수를 기존의 cost함수로 적용한다면, 단계가 거듭하면 할수록 cost함수에 변곡점이 많이 존재한다. 그렇다면 cost함수를 미분했을 때 0으로 수렴하는 값들이 많이 존재하며, 제대로 된 cost의 최솟값을 가리킬때의 weight를 조정할 수가 없다.
따라서 변곡점이 많은 함수일 때는, log를 취해주면 변곡점이 사라지고 완만한 곡선이 된다.
- 만약 y = 1인 경우는 -log(H(x))이며 , Hypothesis가 1로 수렴할 때 cost 값이 0으로 수렴한다.
- 만약 y = 0인 경우는 -log(1-H(x))이며, Hypothesis가 0으로 수렴할 때 cost 값이 0으로 수렴한다.
우리는 y = 1, y = 0인지 binary classification을 하는 것이기에! cost함수를 위와 같이 이렇게 정의한다.
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)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))
print('predicted : ', predicted)
# Launch graph
with tf.Session() as sess:
# Initialize TensorFlow variables
sess.run(tf.global_variables_initializer())
for step in range(100001):
# train은 값 안넣어도 무방
# def run(self, fetches, feed_dict=None, options=None, run_metadata=None)
# sess.run은 fetches가 딕셔너리, 튜플, 리스트, numpy 스타일로 들어오게 된다.
# fetches에서 train이 빠지면 학습이 되지 않기 때문에 값이 일정하게 된다.
cost_val, train_val = sess.run([cost, train], feed_dict={X: x_data, Y: y_data})
if step % 2000 == 0:
print(step, "cost_val : ",cost_val)
# print(step, "train_val : ", type(train_val))
# Accuracy report
h, c, a = sess.run([hypothesis, predicted, accuracy],
feed_dict={X: x_data, Y: y_data})
print("\nHypothesis: ", h, "\nCorrect (Y): ", c, "\nAccuracy: ", a)
predicted를 tf.cast를 썼다. tf.cast는 안에 조건문이 True 이면 1, 아니면 0을 도출해낸다. dtype은 tf.float32이다.
accuracy 는 predicted와 Y가 같다면 True를 반환하고 tf.cast에 의해서 1을 반환한다. 이를 다 더하여 실제 accuracy 를 측정한다.
여기서 제일 중요한 포인트는!
- Sigmoid 라는 함수! 그리고 왜 쓰는지 (sigmoid를 대신해서 나온 함수들이 굉장히 많다. ex) ReLu,,,, 등등)
- Sigmoid의 cost function이 왜 log로 이루어져있고, y=0 or y=1일때 함수가 다른지
이 가정들이 굉장히 중요하다.
'AI' 카테고리의 다른 글
ML07-4-MNIST-data (실제 data 분석) (0) | 2019.10.24 |
---|---|
ML07-4-MNIST-data (0) | 2019.10.24 |
ML06-2-logistic-regression : multiple-classification(softmax-classifier) (0) | 2019.10.23 |
ML04-1-linear-regression(Tensorflow basic) (0) | 2019.10.23 |
Tensorflow : background (6) | 2019.10.23 |
댓글