머신러닝

Log Linear Regression을 위한 자연 log 함수형 hypothesis 적용 사례

coding art 2021. 7. 6. 17:24
728x90

머신 러닝은 시작은 1957Rosenblatt에 의해 오래 전에 시작되었지만 오래동안 내팽개쳐져 왔으며 아직도 내팽개쳐진 상태로 있는 분야로서 2000년이 지나서야 비로서 점차 관심이 집중되고 있는 분야이다.

 

머신러닝을 배우는 가장 초기에 접하게 되는 주제가 바로 선형회귀(Linear Regression) 문제가 아닐까 한다. 머신 러닝은 워낙 더디게 발전했지만 이미 통계학과 관련된 기술 분야에서 다 다루었던 주제이다. 선형 회귀에서 한걸음 더 나아가 Log Linear Regression 문제가 있는데 이 주제는 기계공학이나 재료공학에서 금속재료의 피로성능평가 분야에서 오랜 동안 발전해왔으며 위 그림에서처럼 피로시험 시편에 일정한 진폭의 하중을 지속적으로 가할 경우 피로균열 성장 관찰에서 얻어지는 그래프이다. 이 피로시험 결과 도출되는 함수의 형태는 log linear regression에 적합한 형태를 보여 준다. 이 그래프 양끝 부부에서 좀 더 피로 시험을 추가하면 커브 모양이 S자 형을 이루게 되는데 이 S 자는 바로 머신 러닝에서 hypothesis 함수로 많이 활용되는 Sigmoid형으로 불리운다. 머신 러닝이 발전하기 이전에 이미 엔지니어링 분야에서 이와 같은 log linnear regression을 보여 주는 현상들에 대해 많은 연구가 이루어졌다.

 

TensorFlow를 사용하는 머신 러닝 측면에서는 선형회귀와 달리 어떤 형태로 hypothesis를 설정하여 학습해야 하는지 다루어 보자.

log linear regression을 다루기 위한 입력과 출력 데이타는 다음과 같이 설정하도록 하자.

 

x_train = [1, 10, 100]

y_train = [1, 2, 3]

 

이 관계식에서 x_train 데이터의 상용로그 값을 취하면 막바로 y_train 값들이 얻어짐을 알 수 있다. 즉 이 문제는 3점 데아타 (1,1), (2,2), (3,3)을 사용하는 선형회귀 분석과 밀접한 관계를 맺고 있다. 상용로그로 설명 하면 아주 간단하지만 실제 TensorFlow 라이브러리 모듈에서는 상용로그함수가 지원되지 않으므로 자연로그를 사용하기로 한다.

 

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

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

hypothesis = tf.log(x_train * W + b)

 

선형회귀 문제와의 유사성을 감안하여 hypothesis = log(XW + b) 형태를 사용해 그 적합성을 확인해 보도록 하자. x_train 데이터의 자연 log 값을 취해도 근사적으로는 선형에 가깝기 때문에 cost 함수는 선형회귀 분석과 마찬가지로 최소제곱법을 그대로 사용하면 될 것이며 linear regression 코드 전체적으로 변경할 부분은 거의 없는 듯하다. learning rate 값은 어떻게 될지 모르므로 시행착오를 통해서 경험적으로 찾아야 한다. 여기서는 많은 계산 경험 결과 얻어진 learning rate0.0005 로 설정하고 학습횟수는 2만회로 둔다.

 

초기 학습에 사용하는 랜덤 데아타는 random_normal() 보다는 random_uniform() 이 훨씬 실패율이 적어 보인다. random_normal() default 조건에서 평균값이 0.0이므로 0 근처의 값들이 웨이트 W 와 바이아스 b로 주어지면 자연 log 값 계산이 실패하기 십상이다.

 

아래의 웨이트와 바이아스 계산 결과를 가지고 학습 결과에 대한 오차를 검토해 보자.

위 계산 결과를 사용하여 다음과 같이 오차를 평가해 보자.

계산 결과를 보면 x = 10 에서 에러가 상당히 크며 전반적으로 오차가 크다고 볼 수 있다. 학습횟수를 늘려도 그다지 개선이 되지 않으며 hypothesis 설정 방법을 바꾸어 보는 게 좋을 듯하다.

 

TensorFlow 라이브러리에서는 자연로그 함수만 제공하기 때문에 상용로그를 사용하기 위해서는 base를 변환해 주는 아래의 공식을 사용하도록 한다.

이 공식을 사용해서 hypothesis를 아래와 같이 설정해서 계산해 보자.

 

hypothesis = tf.log(x_train * W )/2.303 + b

위 계산 결과를 표로 정리해 보자.

결과가 1.0, 2.0, 3.0 으로 나왔기 때문에 오차가 거의 0.0%임을 알 수 있다.

이 두가지 경우에 대한 결과를 커버 그림에 그래프로 작성하였으니 참조하자.

정리해 보면 regression 머신 러닝에서 hypothesis 설정 방법에 따라 오차가 상당한 차이를 보여준다. 문제의 성격에 맞도록 hypothesis를 정확히 설정해야 한다.

 

첨부된 파이선 코드를 실행해 보자. session = tf.Session() 이하 영역에서 indentation 이 무너진 부분을 반드시 복구하여 실행하기 바란다

 

#Log_Linear Regression

import tensorflow as tf
tf.set_random_seed(777)  # for reproducibility

# X and Y data
x_train = [1, 10, 100]
y_train = [1, 2, 3]


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

hypothesis = (tf.log(x_train * W)/2.303 + b)

cost = tf.reduce_mean(tf.square(hypothesis - y_train))

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.0005)
train = optimizer.minimize(cost)

sess = tf.Session()

sess.run(tf.global_variables_initializer())

for step in range(20001):
    sess.run(train)
    if step % 1000 == 0:
        print(step, sess.run(cost), sess.run(hypothesis),sess.run(W), sess.run(b))