본문 바로가기

개인공부

tensorflow를 이용해서 binary 값 데이터 학습하기

반응형

 

오랜만에 포스팅하네요. 오늘은 카글이라는 사이트에서 대량의 데이터를 가져와서 tensorflow를 활용해 학습시키고

학습시킨 데이터가 얼마나 정확한지 확인해 보도록 하겠습니다.

https://www.kaggle.com/

Kaggle: Your Home for Data Science

www.kaggle.com

저는 당뇨병 환자의 수치에따른 값을 들고 왔어요~

파일형식은 csv 파일 형식이고 M이면 악성 B이면 양성입니다.

파일을 float32형식으로 열려고하니깐 오류가 뜨더라고요

 

 

 

 

파싱하는것보단 B값과 M값을 숫자로 바꿔서 다루기 쉽게 접근해 보도록 하겠습니다.

 

numpy 함수에 loadtxt라는 녀석을 이용해서불러온후 x_data y_data를 저장해줍니다

 

x_data = xy[:,2:]
y_data = xy[:, [1]]

 

x값은 1행부터~끝까지 3번째 열부터 시작하기때문에 2: 로해주고

y값도 모든행인데 2번째열이 y값 데이터이므로 이렇게 설정해줍니다

 

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

 

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

 

 

placeholder는 텐서플로우의 값을 넘겨주는 방식입니다 None인 이유는 우리는 얼마나 많은 행을 받을지 모르기 때문이죠 x값은

x1 x2 ...... x30 까지 잇으므로 이렇게 설정해주고 마찬가지로 y는 하나의 값을 가지므로 설정해줍니다

 

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

 

마찬가지로 w값도 w1... w30 까지이므로 설정해줍니다 b는 bias 값이므로 상수값 하나를 가집니다.

 

우리가 추측할값은 0또는 1인 binary 값입니다 근데 수많은 w1 w2 w3를 어떻게 0과 1로 근접하게 할가요 답은 익스포텐셜 e 함수를 이용 하는겁니다.

추측값 H(X)는 1~0 값이 나옵니다.(WX+b값이 무한으로가면 1로 마이너스 무한으로 가면 0으로 수렴하는걸 알수있다.) 하지만 기존의 cost 구하는 방식을 사용한다면

경사가 일정하지 않아서 cost값이 중구난방이 된다.

따라서 우리는 cost를 바꿔줘야한다 바로 log함수를 이용하는것

 

hypothesis = tf.sigmoid(tf.matmul(X, W) + b) #wide of value is 0~1

 

텐서플로우의 simoid라는 함수를 이용해서 익스포텐셜 함수를 표현하엿다.

y과 1일때와 y=0 일때를 나눠서 cost값을 결정할수있다.

 

cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis))

 

Y값이 1 인 경우와 0인경우를 텐서플로우를 이용하여 cost를 한번에 표현하였다 cost값은 추측값과 실제값이 가까워질수록

0에 가까워진다. 맞는지 확인해보자

 

predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))

추측된값은 0~1의 아날로그한 값들이다 이값을 디털값으로 바꿔준다

import tensorflow as tf
import numpy as np
tf.set_random_seed(777)

xy = np.loadtxt('work1.csv', delimiter=',', dtype=np.float32) #M=1 악성 B=0 양성
x_data = xy[:,2:]
y_data = xy[:, [1]]

print(x_data)
print(y_data)
print(x_data.shape, y_data.shape)

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

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

hypothesis = tf.sigmoid(tf.matmul(X, W) + b) #wide of value is 0~1

cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) *
                       tf.log(1 - hypothesis))


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

predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))


#Launch graph
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)

 

소스를 돌려보니 cost 값이 nan 값이 나온다 ...... nan은 무한대의값을 표현할때 나오기도하는데 즉 learning_rate비율이 너무 커서 overshooting 할때 나오는것. 제어공학할때 흔히들 보는 0.01값이 너무커서 발산하게된것이다.

아마 x1 x2 x3 .... x30 에 들어있는값들이 소숫점 5째자리수도잇고 정수 세자리수도 잇는게 원인인듯하다. 그래서 python에서

제공하는 가장 작은 소수를 넣어보도록하겠다.

 

결과는 python 부동소수점으로는 overshooting이 해결하지 못했다.. 이번예제는 약간의 변형을 해서 다시적용 시켜보겠다ㅜㅜ..

 

학습시킬값들에서 차이가 많이나는 부분을 수정시킨호 rate=0.1과 10만번을 학습시키자 기존의 데이터와 일치확률이 93%까지 올라가는 모습을 볼수있었다.

 

반응형