티스토리 뷰

모두의 딥러닝

여러개의 입력(feature) Linear Regression

강의

이번 동영상에서는 기존의 입력에서 추가적인 입력을 다룬다.

예제로 학업 성적에 대해 다루는데, 이전 시험 성적 데이터로 나중에 시험 성적을 예측할 수는 있지만, 조금 신뢰성 있고, 정확도를 높이기 위해, 이전 시험 데이터 갯수를 늘이고, 시험 시간 기타 요소들을 추가로 넣으면 더욱 정확한 결과값이 나올 것이다.


위의 이미지를 토대로 hypothesis 만들면 어떻게 될까? X 대한 값에 따라 w 값만 곱해주면 된다.

그렇다면 cost 함수는 어떻게 될까? 해당 가설을 그대로 대입해주면 된다.


이렇게 몇개 x 증가되지않은 상황에서의 계산은 기존과 같이 x 추가해서 계산을 하면 같다.

그러나 만약 x 값이 엄청나게 늘어나거나, 개수가 10 이상만 되더라도, 소스코드는 엄청 복잡해 것이다. 그래서 이러한 부분을 보안하기 위해 행렬이 등장한다.


옆의 행렬을 간단하게 설명하면, [2,3] * [3,2] 구한 것이고 이는 [2,2] 결과를 나타내는 행렬로 나타난다.

행렬을 곱을 위해선, 앞의 렬과 뒤의 행이 같으면 곱이 가능해지고 결과는 앞의 그리고 뒤의 렬로 나타난다.

위의 형태도 앞의 (3) 뒤의 (3) 같기때문에 계산이 되고, 앞의 (2), 뒤의 (2) 결과값이 되어 [2,2] 행렬값으로 나타나는 것이다.


그래서 위의 이미지 같이 나타낼 있다.

 

그래서 위와 같은 데이터셋이 n개가 있다면 다음과 같이 나타낼 있다.


매트릭스로 계산하지 않고, 직접 계산을 하도록 구성하려 했다면 엄청 복잡했을 것이다.

 

Lab

이번 강의는 2개를 설명한다. 첫번째 동영상은 행렬(matrix) 사용하여, 소스를 구성하는 방식이고, 두번째는 파일에 있는 데이터를 불러와 데이터셋을 훈련하는 방법이다.

정확하게 말하면, 매트릭스를 사용하기 전과 후를 비교? 하기 위해, 두가지 방법으로 소스를 구현한다. 그러나, 나중에 사용할 것도 매트릭스를 사용하여 구현할 것이기 때문에, 앞에 부분은 생략하고 매트릭스로 구현한 소스만 보도록 한다.

import tensorflow as tf

# 행렬로 처리를 하여 다음과 같은 모양(X:[5,3], Y:[5,1]) 된다.
x_data = [[73., 80., 75.], [93., 88., 93.], [89., 91., 90.], [96., 98., 100.], [73., 66., 70.]]
y_data = [[
152.], [185.], [180.], [196.], [142.]]

# 기본의 방식과는 다르게 shape 지정해준다. 데이터셋이 얼만큼 있을지 모르기 때문에, 부분은 None으로 처리한다.
X = tf.placeholder(
dtype=tf.float32, shape=[None, 3])
Y = tf.placeholder(
dtype=tf.float32, shape=[None, 1])

# 여기서 주의할점은, 행렬의 곱셈을 생각하면 쉽게 이해할 있다. W shape [3,1] 이유는 곱해주는 X 데이터가 [None,3]이라 렬의 숫자 3 맞추기 위해서이다.
W = tf.Variable(tf.random_normal([
3, 1]), name='weight')
b = tf.Variable(tf.random_normal([
1]), name='bias')

# 매트릭스를 곱하는 API matmul 사용한다. 행렬이므로 인자들을 넣을 주의!
hypothesis = tf.matmul(X
, W) + b
cost = tf.reduce_mean(tf.square(hypothesis - Y))
optimizer = tf.train.GradientDescentOptimizer(
learning_rate=1e-5)
train = optimizer.minimize(cost)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

for step in range(2001):
    cost_
, hy_, _ = sess.run([cost, hypothesis, train], feed_dict={X: x_data, Y: y_data})
   
if step % 20 == 0:
       
print(step, "Cost: ", cost_, "Prediction: ", hy_)


결과값

위의 소스에서 주의해야 부분은, matmul이란 API 행렬 곱셈이라는 점이다. 조금 상세히 말하면, 행렬이 곱해지기 위해선 앞에 행렬의 렬과 뒤의 행렬 행의 숫자가 같아야 곱이 가능해진다.

그래서 위의 소스를 보면 W 행값(3) X 렬값(3) 같게 맞춰준게 보인다.

 

다음으로는 파일에 있는 데이터를 가지고 학습을 시키는 소스를 구현한다.

파일을 불러오는 모듈로 numpy 사용하는데, 파이썬에 익숙하지 않은 나로써는 학습이 필요할 같다. 그러나 여기에서 사용하는 예시들로만 보더라도 사용법을 숙지할 필요가 있을만큼 강력하고, 많이 사용하는 모듈이다.

이런 내용과 관련된 치트시트를 찾았는데 내용은 아래와 같다. 아래의 이미지만 숙지를 하더라도, 많이 도움이 것이라 의심치 않는다.

 

import tensorflow as tf
import numpy as np

# 참조: https://www.tensorflow.org/api_docs/python/tf/set_random_seed

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


tf.set_random_seed(
777)

#
데이터를 가져오고, ‘,’ 짜르며, 타입은 float32

xy = np.loadtxt('train_data.csv', delimiter=',', dtype=np.float32)

# numpy slice 특징으로 -1 경우, 마지막 다음 데이터를 말한다.
x_data = xy[:
, 0:-1]
y_data = xy[:
, [-1]]

## For Test
# print(x_data.shape, x_data, len(x_data))
# print(y_data.shape, y_data)

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

W = tf.Variable(tf.random_normal([
3, 1]), name='weight')
b = tf.Variable(tf.random_normal([
1]), name='bias')
hypothesis = tf.matmul(X
, W) + b

cost = tf.reduce_mean(tf.square(hypothesis - Y))
# learning_rate
값을 1e-4 두었을 경우, 데이터 학습이 제대로 안이루어졌다. Learning_rate 적절히 배치하기 위해 학습을 시키기 해당 learning_rate 적절한지에 대한 검증이 필요할 같다.

optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)
train = optimizer.minimize(cost)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

for step in range(2001):
    cost_
, hy_, _ = sess.run([cost, hypothesis, train], feed_dict={X: x_data, Y: y_data})
   
if step % 100 == 0:
       
print(step, "Cost: ", cost_, " Predict: ", hy_)

print("Your score will be ", sess.run(hypothesis, feed_dict={X: [[100, 70, 101]]}))
print("Other scores will be ", sess.run(hypothesis, feed_dict={X: [[60, 70, 110], [90, 100, 80]]}))

                                                                                                                                     

 

다음 이미지는 메모리에 한번에 올려서 처리하기가 부담스러울 정도의 크기를 가진 (여러)파일을 불러오는 방법에 대해 설명하고 있다. 교수님 말씀에 따르면, Queue 사용하여, 하나씩 처리가 되기 때문에, 엄청난 양의 데이터를 부르더라도, 메모리에서 하나씩 처리되어, 부담이 없도록 설계되었다고 한다. 파일을 불러와 Queue 쌓은 다음, Reader기가 파일 데이터를 하나씩 불러와 Decoder 하여, Queue 쌓아둔다. 그러면 텐서플로우가 해당 Queue 쌓인 데이터를 가지고 학습을 하는 형식이다. 이런 API 사용하여, 몇백개의 파일도 불러와 학습할 있게 된다.

위의 이미지를 소스로 구현하면 아래와 같다.

 

import tensorflow as tf

# 파일 개수는 배열에 불러오고 싶은 파일명을 불러오면 가능하다. 현재는 1개의 파일만 불러온다.

# shuffle false 설정하고, name 지정해준다.
filename_queue = tf.train.string_input_producer(
    [
'train_data.csv'], shuffle=False, name="filename_queue")

# TextLineReader 포멧이 같다면 한라인씩 순차적으로 처리를 한다.

# 해당 데이터는 value 부분에서 확인을 있다.

reader = tf.TextLineReader()
key
, value = reader.read(filename_queue)

# 불러온 파일을 decode(raw파일을 파싱) 처리한다.

# 추가로 설명을 하면, value형태는 각각의 필드로 구분된 상태가 아닌 하나의 문자로 인식한다. 그래서 이를 # 각각의 필드로 구분해주기 위해 Decode하는 절차가 필요하다.

# record_defaults 해당 필드에 데이터가 없는 경우, 기본값을 채워주기 위해 사용한다. 아래의 방식은

# 0. Float 채워주도록 설계하였다.
record_defaults = [[
0.], [0.], [0.], [0.]]
xy = tf.decode_csv(value
, record_defaults=record_defaults)

# 배치사이즈를 10개로 해서, 10개씩 데이터를 각각 train batch 데이터에 입력시킨다.
train_x_batch
, train_y_batch = tf.train.batch([xy[0:-1], xy[-1:]], batch_size=10)


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

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

hypothesis = tf.matmul(X
, W) + b
cost = tf.reduce_mean(tf.square(hypothesis - Y))

optimizer = tf.train.GradientDescentOptimizer(
learning_rate=1e-5)
train = optimizer.minimize(cost)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

# 쓰레드들을 관리하기 위한 Coordinator
coord = tf.train.Coordinator()

# 사용할 쓰레드들을 생성

threads = tf.train.start_queue_runners(sess=sess, coord=coord)

for step in range(2001):

    # 10개씩 데이터를 가져온다.
    x_batch
, y_batch = sess.run([train_x_batch, train_y_batch])
    cost_
, hy_, _ = sess.run([cost, hypothesis, train], feed_dict={X: x_batch, Y: y_batch})

   
if step % 20 == 0:
       
print(step, "Cost: ", cost_, "Prediction: ", hy_)

# 사용한 쓰레드 정지 요청
coord.request_stop()
#
사용한 쓰레드 정지되기 까지 기다림
coord.join(threads)

 

소스에 설명을 하는게 좋을 같아. 소스에 주석으로 해당 동작에 대해 설명을 하였다.

참고로 데이터를 가져오는 방법은 여러개가 있으며, 김성훈 교수님도 더이상의 부가적인 설명 대신 참고할 있는 사이트와 shuffle 배치에 대해서만 소개해주고 강의를 끝낸다.


댓글
공지사항
최근에 올라온 글
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함