본문 바로가기
AI

ML04-1-linear-regression(Tensorflow basic)

by 월곡동로봇팔 2019. 10. 23.
 
import tensorflow as tf

x1_data = [73., 93., 89., 96., 73.]
x2_data = [80., 88., 91., 98., 66.]
x3_data = [75., 93., 90., 100., 70.]
y_data = [152., 185., 180., 196., 142.]

linear-regression 한 예제 코드이다.

 

이번 예제코드는 실제로 임의로 x1,x2,x3,y data를 부여하고 이들의 상관관계를 알아보려한다.

 
# placeholder 지정
x1 = tf.compat.v1.placeholder(tf.float32)
x2 = tf.compat.v1.placeholder(tf.float32)
x3 = tf.compat.v1.placeholder(tf.float32)

Y = tf.compat.v1.placeholder(tf.float32)

 각각의 데이터(tensor)를 담는 placeholder를 정의해준다. 여기서 placeholder를 정의하고 입력파라미터로 tf.float32를 넣어준다. 이는 각각의 placeholder에 담기는 수들의 type을 float의 32bit로 정해준 것이다.

 

32bit에 저장할 수 있는 정수 값의 범위는 0부터 4,294,967,295, 또는 −2,147,483,648부터 2,147,483,647까지이다. 보통은 32bit로하고, 만약 숫자가 크다면 tf.float64로 해주는 것이 좋다. 만약 숫자가 int형으로 이루어져있다면, 이는 int32, int64정도로 해주는 것이 좋다.

 

또한 나중에 placeholder를 정의하면, 나중에 연산을 돌릴 때, feed_dict에 값을 넣어서 계산을 하면 된다. 이는 추후 밑단에 tf.Session() 위에 올려서 계산을 한다.

 

경험에 의하면 tensorflow가 워낙 모듈과 패키지들이 많아서 연산하는데 시간이 굉장히 오래걸린다. 또한 C++, C와는 다르게 인터프리터라는 장점이자 단점덕분에 연산속도가 굉장히 느리다. 따라서 저런 변수들을 정의할 때도 타입과 크기를 고려하고 정의해야 그나마 연산속도를 더 빠르게 할 수 있다. 나중에 tensorflow 연산속도 빠르게 하기위해 멀티쓰레딩과 멀티프로세싱 모듈을 도입해서 코드를 돌려볼 예정이다. 추후 해보고 정리하도록 할 예정이다.

 

 

# Variable 선언
w1 = tf.Variable(tf.random.normal([1], name = 'weight1'))
w2 = tf.Variable(tf.random.normal([1], name = 'weight2'))
w3 = tf.Variable(tf.random.normal([1], name = 'weight3'))
b = tf.Variable(tf.random.normal([1], name = 'bias'))

# Hypothesis 선언
H = x1 * w1 + x2 * w2 + x3 * w3 + b

Variable을 선언을 한다. 여기서 weight와 bias 개념이 나오는데, weight는 실제 입력한 data가 우리가 예측한 값인 Hypothesis에 얼마나 영향을 주는지에 대하여 값을 부여할 수 있다. 또한 이러한 오류를 잡아주기 위해 bias라는 예측하기 힘든 값을 임의로 넣어주어, 우리가 예측하는 Hypothesis를 보정한다. 이 weight, bias에 shape가 [1], name을 부여하였고, 입력파라미터의 type으로 tf.random.normal을 넣어주었다.

 

여기서 변수선언 때 tf.random_normal에 대해 언급하고 가자.

더보기

tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)

정규분포로부터의 난수값을 반환합니다.

  • shape: 정수값의 1-D 텐서 또는 파이썬 배열. 반환값 텐서의 shape입니다.
  • mean: 0-D 텐서 또는 dtype타입의 파이썬 값. 정규분포의 평균값.
  • stddev: 0-D 텐서 또는 dtype타입의 파이썬 값. 정규분포의 표준 편차.
  • dtype: 반환값의 타입.
  • seed: 파이썬 정수. 분포의 난수 시드값을 생성하는데에 사용됩니다.
  • name: 연산의 명칭 (선택사항).

반환값:

정규 난수값들로 채워진 shape으로 정해진 텐서를 반환한다.

주로 우리는 정규분포를 따르는 random_normal을 따르지만, 데이터에 따라 변수에 임의의 값을 넣을 때 어떤 특징을 가지는 값을 넣어야 하는지는 데이터를 분석한 후 결정해야한다. 균등분포를 따르는 random_uniform, 절단정규분포를 따르는 truncated_normal 등등 많이 있다.

 

밑은 다른 변수의 타입을 정해주는 모듈들을 정리해놓았다. 자세한건 이 사이트를 참조한다.

https://tensorflowkorea.gitbooks.io/tensorflow-kr/content/g3doc/api_docs/python/constant_op.html

 

상수, 시퀀스, 난수 생성 · 텐서플로우 문서 한글 번역본

No results matching ""

tensorflowkorea.gitbooks.io

# Hypothesis 정의하기
H = x1 * w1 + x2 * w2 + x3 * w3 + b

# cost 함수 정의하기
cost = tf.reduce_mean(tf.square(H - Y))

 

여기서 Hypothesis는 x1, x2, x3 간에 weight를 곱하고 bias를 더한 값으로 내가 설정을 하였다.

 

cost function

또한 cost 함수는 위와 같은 식으로 정의하였으며, 우리가 예측한 Hypothesis와 실제 입력한 y_data와 차이를 함수로 표한 것이다. 우리는 여기서 고등학교 때 배운 미분을 생각을 안할 수가 없다. cost 함수를 예측값과 실제값의 제곱을 한 이유는 cost함수가 위의 그림처럼 2차함수이다. 여기서 미분을 해서 미분값이 0인 지점이 cost 함수의 최솟값을 이기 때문이다. 따라서 다음과 같이 cost 함수를 정의한다.

 

# optimizer 설정
optimizer = tf.compat.v1.train.GradientDescentOptimizer(learning_rate = 1e-5)
train = optimizer.minimize(cost)

cost함수를 정의하고, optimizer를 정의하여 GradientDescentOptimizer 메소드를 쓴다.

gradient = tf.reduce_mean((W * X - Y) * X)
descent = W - learning_rate * gradient
update = W.assign(descent)

원래는 다음과 같이 정의를 해야한다. gradient는 cost함수를 미분한 값이며, descent는 우리가 임의로 넣은 weight값을 learning_rate를 준 값에 gradient를 곱한 값을 빼준 값이다. 따라서 우리는 learning_rate 만큼 weight을 옮길수있다. update는 weight값을 descent로 assign한다는 의미이다. update는 추후 sess에서 연산을 하면된다. 

 

하지만 우리는 이렇게 번거로운 작업을 하지 않아도,

train = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(cost) 을 사용해 cost를 최적화 시킬 수 있다.

# session 활성화
sess = tf.compat.v1.Session()

# variables 활성화
sess.run(tf.compat.v1.global_variables_initializer())

# session으로 계산구하기
for step in range(2001):
    cost_val, H_val , _ = sess.run([cost, H, train], feed_dict={x1:x1_data, x2:x2_data, x3:x3_data, Y:y_data,})
    if step % 10 == 0:
        print(step, "Cost : ", cost_val, "\nPrediction\n", H_val)

이후 우리는 Tensor를 연산하기 위해 Session에서 연산을 해야한다. Session에 Tensorflow에서 정의한 Tensor들을 연산하도록 시스템이 구축되어있다. tf.global_variables_initializer() 는 우리가 정의한 Variable을 활성화 시키는 메소드이다. 그 후 for문을 이용하여 sess.run에 우리가 연산해야할 함수들을 넣고, feed_dict로 데이터를 입력한다.

 

이는 선형회귀에 전형적인 모델이다.

 

이를 이용하여 많은 선형회귀를 할 수 있다.

 

댓글