이론

지난 포스트에서는 학습 데이터의 종류가 하나인 상황에서 Linear Regression을 해보았는데요, Multivariable Linear Regression에 대하여 배워보려 합니다. 상황을 우선 설정하면 여러 학생들이 현재 마지막 최종 시험을 앞둔 상황입니다. 최종 시험 점수를 \bg_white \large y 라고 하였을 때 이전에 본 3번의 시험 점수 \bg_white x_1, x_2, x_3 로 최종 점수를 예측해보자는 것입니다.

이론은 역시나 똑같습니다.

 

1) Hypothesis

데이터 종류가 3개인 상황을 가정합니다. 그렇다면 가설 H(x) 는 다음과 같겠네요.

\dpi{80} \large H(x_1, x_2, x_3) = w_1x_1 + w_2x_2 + w_3x_3 + b

2) Cost function

이 역시 어렵지 않게 설정할 수 있습니다.

\dpi{100} \small cost(W, b)= \frac{1}{m}\sum(H(x_1,x_2,x_3)-y)^2

n개로의 확장 역시 가능합니다. 다만 여기서의 관건은 어떻게 쉽게 w 와 x 의 곱셈 연산을 수행할 수 있겠냐는 건데요. 이때 행렬을 이용하게 됩니다.

Hypothesis using matrix

\dpi{80} \begin{pmatrix} x_1 & x_2 & x_3 \end{pmatrix} \begin{pmatrix} w_1\\ w_2\\ w_3 \end{pmatrix} = \begin{pmatrix} x_1w_1+x_2w_2+x_3w_3 \end{pmatrix}

가 되겠네요. 다시 말해 우리의 가설은

\dpi{100} \small \bg_white \large H(x) = XW

로 귀결됩니다.

시험의 종류가 늘어난다면 즉 \bg_white \large x 의 종류가 늘어난다면 변수 \dpi{80} \bg_white \large w 의 개수도 증가하게 됩니다. 하지만 학생 수가 늘어나면 어떻게 될까요? 즉 다시 말해, 행렬 \dpi{80} \bg_white \large X에서 열의 개수가 증가하면 어떻게 될까요? 이 때는 위에서 사용한 \dpi{80} \bg_white \large W 를 그대로 사용할 수 있습니다. 행렬의 곱셈에서 중요한 것은 앞 행렬의 열 개수 == 뒤 행렬의 행 개수 입니다.

03) Gradient Descent Algorithm

One variable의 Linear Regression과 마찬가지로 경사를 따라 내려오는 알고리즘을 사용합니다.
강의 하나를 포스트 작성에서 누락 시켰습니다. 아래 링크를 통해 보실 수 있습니다.
>> Linear Regression의 최소화

 

실습

변수가 한개일 때와 거의 동일합니다.

import tensorflow as tf
# x와 y의 초기 데이터를 설정합니다.
# 이때 주의할 점은 y_data를 n x 1 행렬로 만들어주기 위해 []를 두번씩 써야 한다는 점입니다.
x_data = [[70., 80., 90.],
          [85., 95., 65.],
          [80., 85., 90.],
          [70., 55., 95.],
          [85., 70., 100.]]
y_data = [[230.], [235.], [245.], [210.], [245.]]
# 가설 설정을 위한 변수를 설정하고
W = tf.Variable(tf.random_normal([3,1]), name="weight")
b = tf.Variable(tf.random_normal([1]), name="bias")

# 가설을 설정합니다.
# tf.matmul은 행렬의 곱 연산 함수 입니다.
hypothesis = tf.matmul(X, W) + b
# cost op를 만들고
cost = tf.reduce_mean(tf.square(hypothesis-Y))

# cost를 최소화 시키기 위한 op를 train에 등록합니다.
optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)
train = optimizer.minimize(cost)
# 세션을 실행합니다.
# 이전 포스트와 실행 방법을 달리하였습니다.
with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer())
    for step in range(8001):
        cost_val, W_val, b_val,  _ = sess.run([cost, W, b, train], feed_dict={X:x_data, Y:y_data})
        if step % 20 == 0:
            print (step, "Cost: ", cost_val, "\n",  W_val, "x +" , b_val) 

    # 모델을 테스트하기 위해서 한줄 추가해보았습니다.
    # 주의할 점은 이 역식도 세션 상에서 실행되어야 한다는 점입니다.
    print(sess.run(hypothesis, feed_dict={X: [[80., 100., 90.]]}))

세션 실행하기

파이썬에서는 file을 열 경우 꼭 닫는 작업이 필요합니다.

# 파일을 열었을 경우에는
f = open("test.txt", "w")

# 모든 작업 완료 후 파일을 닫아주어야 합니다.
f.close()

특히 “쓰기” 작업에서 열린 파일에 데이터를 작성할 경우 파이썬 상에서는 사용자가 입력한 데이터를 곧바로 파일에 담지 않고 임시 메모리인 buffer에 저장해 둡니다. 파이썬은 스스로 buffer의 메모리를 가져오지 않습니다. 사용자가 입력을 끝마칠 때까지 기다리게 되는데요. 입력을 마쳤다는 것을 알리는 방법 중 하나가 바로 파일을 닫는 것입니다.

During the I/O process, data is buffered: this means that it is held in a temporary location before being written to the file. Python doesn’t flush the buffer—that is, write data to the file—until it’s sure you’re done writing. One way to do this is to close the file. If you write to a file without closing, the data won’t make it to the target file. <fn>http://codecademy.com</fn>

매번 close() 함수를 호출하여 파일을 닫는 행위가 번거롭게 느껴질 때 쓰는 것이 with ~ as 구문입니다. 즉 위의 코드는 아래와 같이 바뀝니다. <fn>http://ingorae.tistory.com/505</fn>

with open("test.txt") as f:
     pass

세션 역시 이러한 특성을 지닙니다. 세션을 열고 모든 작업 완료 후에는 꼭 닫아주어야 합니다. 닫는 작업이 번거롭게 느껴질 때 세션 역시 with ~ as 구문으로 작업을 실행할 수 있습니다.


0개의 댓글

답글 남기기

Avatar placeholder

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다