본문 바로가기
머신러닝과 딥러닝/실습

TensorFlow로 파일에서 데이터 읽어오기

by Bentist 2020. 2. 11.

실습 파일 자료 https://github.com/hunkim/DeepLearningZeroToAll

 

데이터가 많아지면, 소스 코드에 일일이 써놓기가 힘들어진다.

그래서 이제는 콤마로 나눠진 텍스트 파일을 읽어와서 실습을 해볼 것이다.

간단하게 numpy의 loadtxt를 이용해보자.

import numpy as np

xy = np.loadtxt('data-01-test-score.csv', delimiter=',', dtype=np.float32)
x_data = xy[:, 0:-1]
y_data = xy[:, [-1]]

# Make sure the shape and data are OK
print(x_data.shape, x_data, len(x_data))
print(y_data.shape, y_data)
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

# 선형 회귀를 위해서 텐서 플로우 1의 코드 실행을 위한 임포트
# 현재는 텐서 플로우 2로 선형 회귀를 훨씬 간단하게 구현할 수 있다.
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

tf.set_random_seed(777)
xy = np.loadtxt('data-01-test-score.csv', delimiter=',', dtype=np.float32)

x_data = xy[:, 0:-1]
y_data = xy[:, [-1]]

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

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))

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_val, hy_val, _ = sess.run([cost, hypothesis, train],
                                  feed_dict={X: x_data, Y: y_data})
    if step%100 == 0:
        print(step, 'cost:', cost_val, "\nprediction:\n", hy_val)
        
# 학습 완료   

# 모델을 테스트하기 위해 임의의 점수를 넣어보자.

print("your score will be", 
      sess.run(hypothesis, feed_dict={X: [[100, 70, 101]]}))

> your score will be [[181.73277]]

X에 인풋값을 넣고 hypothesis(Y)를 출력해보면, 예측 값이 출력되는 것을 알 수 있다.

 

데이터 파일이 여러개 이거나 너무 크다면 어떻게 해야 할까?

파일이 굉장히 커지면, 메모리에 한번에 올리기가 힘들어진다. 이런 경우에 numpy를 써서 올릴 수가 없다.
그래서 Tensorflow에서는 Queue Runners라는 멋진 아이를 만들어 두었다.
먼저 여러 개의 파일을 읽어와서, Queue에 쌓고 Reader에 연결해서 데이터를 읽는다. 그리고 데이터 양식에 맞게 Decoder로 콤마를 분리하는 등의 작업을 거쳐서 Queue에 다시 쌓는다. 학습을 시킬 때는 전체를 다 읽어들이지 말고, 
조금씩 꺼내쓰는 방식인 batch를 통해 batch_size 만큼만 읽어와서 학습시킨다.

1) 불러들일 파일들을 리스트화 시킨다. 수백개까지도 가능하다. 

2) Reader를 정의한다. 여기서는 텍스트라인으로 읽어오겠고 key, value로 나누어서 읽겠다. 

3) value의 데이터 타입으로 float인 0. 을 정의해주었다.

 

그런데 최신 버전에서는 tf.TextLineReader, tf.train.string_input_producer 등 메서드들을 더이상 사용할 수 없기 때문에, 코드를 조금 바꿔서 진행하겠다.

import tensorflow as tf

#tf.data를 이용하여 파일에서 데이터 읽어오기
#.skip(1) : 첫번째 줄은 제외하고(헤더)
#.repeat() : 파일의 끝에 도달하더라도 처음부터 무한 반복
#.batch(10) : 한 번에 10개씩 묶어서 사용
iterator = tf.data.TextLineDataset("data-01-test-score.csv")\
           .skip(1)\
           .repeat()\
           .batch(10)\
           .make_initializable_iterator();

#반복자가 다음 데이터를 읽어오도록 dataset 노드에 명령을 저장
dataset = iterator.get_next()

#csv를 읽어서 데이터로 변환한다.
lines = tf.decode_csv(dataset, record_defaults=[[0.], [0.], [0.], [0.]])
#변환된 데이터의 첫번째 열부터 마지막-1번째 열까지 합쳐서 train_x_batch에 할당
train_x_batch = tf.stack(lines[0:-1], axis=1)
#마지막 열을 합쳐서 train_y_batch에 할당
train_y_batch = tf.stack(lines[-1:], axis=1)

#placeholder는 실제 값이 입력된다.
X = tf.placeholder(tf.float32, shape=[None, 3]) #x값은 Nx3의 행렬이다.
y = tf.placeholder(tf.float32, shape=[None, 1]) #y값은 Nx1의 행렬이다.

#Variable은 모델을 훈련하여 업데이트 된다.
W = tf.Variable(tf.random_normal([3,1]), name="weight") #3x1의 행렬(3행 1열)
b = tf.Variable(tf.random_normal([1]), name="bias")

#가설h
h = tf.matmul(X, W) + b

#loss(cost) 함수
loss = tf.reduce_mean(tf.square(h - y))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)
train = optimizer.minimize(loss)

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

for step in range(2001):
    #반복자 초기화
    ss.run(iterator.initializer)
    #반복자를 통해 할당된 값을 읽어오기
    x_batch, y_batch = ss.run([train_x_batch, train_y_batch])
    #모델 훈련을 진행하고 loss및 h값 가져오기
    loss_val, h_val, _ = ss.run([loss, h, train],
                                     feed_dict={X: x_batch, y: y_batch})
    if step % 10 == 0:
        print("loss : {0}".format(loss_val))

print("score..", ss.run(h, feed_dict={X:[[100,70,101]]}))

댓글