텐서플로우 - 파일에서 학습데이타를 읽어보자#2
CSV 파일을 읽어보자
조대협 (http://bcho.tistory.com)
이 글은 http://bcho.tistory.com/1163 의 두번째 글이다. 앞의 글을 먼저 읽고 읽기를 권장한다.
앞의 글에서는 트레이닝 파일명의 목록을 읽어서 큐에 넣고, 파일명을 하나씩 읽어오는 처리 방법에 대해서 알아보았다. 이번 글에서는 그 파일들에 있는 데이타를 읽어서 파싱한 후, 실제 트레이닝 세션에 학습용 데이타로 불러들이는 방법을 설명하도록 한다.
파일에서 데이타 읽기 (Reader)
finename_queue에 파일명이 저장되었으면, 이 파일들을 하나씩 읽어서 처리하는 방법을 알아본다.
파일에서 데이타를 읽어오는 컴포넌트를 Reader라고 한다. 이 Reader들은 filename_queue에 저장된 파일들을 하나씩 읽어서, 그 안에 있는 데이타를 읽어서 리턴한다.
예를 들어 TextLineReader의 경우에는 , 텍스트 파일에서, 한줄씩 읽어서 문자열을 리턴한다.
꼭 텐서플로우에서 미리 정해져있는 Reader 들을 사용할 필요는 없지만, 미리 정의된 Reader를 쓰면 조금 더 편리하다.
미리 정의된 Reader로는 Text File에서, 각 필드가 일정한 길이를 가지고 있을때 사용할 수 있는, FixedLengthRecordReader 그리고, 텐서플로우 데이타를 바이너리 포맷으로 저장하는 TFRecord 포맷에 대한 리더인 TFRecordReader 등이 있다.
Reader를 사용하는 방법은 다음과 같다.
reader = tf.TextLineReader()
key,value = reader.read(filename_queue)
먼저 Reader 변수를 지정한 다음, reader.read를 이용하여 filename_queue 로 부터 파일을 읽게 하면 value에 파일에서 읽은 값이 리턴이 된다
예를 들어 csv 파일에 아래와 같은 문자열이 들어가 있다고 할때
167c9599-c97d-4d42-bdb1-027ddaed07c0,1,2016,REG,3:54
67ea7e52-333e-43f3-a668-6d7893baa8fb,1,2016,REG,2:11
9e44593b-a870-446e-aed5-90a22ab0c952,1,2016,REG,2:32
48832a52-e56c-467f-a1ef-c6f8c6e908ea,1,2016,REG,2:17
위의 코드 처럼, TextLineReader를 이용하여 파일을 읽게 되면 value에는
처음에는 “167c9599-c97d-4d42-bdb1-027ddaed07c0,1,2016,REG,3:54”이, 다음에는 “67ea7e52-333e-43f3-a668-6d7893baa8fb,1,2016,REG,2:11” 문자열이 순차적으로 리턴된다.
읽은 데이타를 디코딩 하기 (Decoder)
Reader에서 읽은 값은 파일의 원시 데이타 (raw)데이타이다. 아직 파싱(해석)이 된 데이타가 아닌데,
예를 들어 Reader를 이용해서 csv 파일을 읽었을 때, Reader에서 리턴되는 값은 csv 파일의 각 줄인 문자열이지, csv 파일의 각 필드 데이타가 아니다.
즉 우리가 학습에서 사용할 데이타는
167c9599-c97d-4d42-bdb1-027ddaed07c0,1,2016,REG,3:54
하나의 문자열이 아니라
Id = “167c9599-c97d-4d42-bdb1-027ddaed07c0”,
Num = 1
Year = 2016
rType = “REG”
rTime = “3:54”
과 같이 문자열이 파싱된 각 필드의 값이 필요하다.
이렇게 읽어드린 데이타를 파싱 (해석) 하는 컴포넌트를 Decoder라고 한다.
Reader와 마찬가지로, Decoder 역시 미리 정해진 Decoder 타입이 있는데, JSON,CSV 등 여러가지 데이타 포맷에 대한 Decoder를 지원한다.
위의 CSV 문자열을 csv 디코더를 이용하여 파싱해보자
record_defaults = [ ["null"],[1],[1900],["null"],["null"]]
id, num, year, rtype , rtime = tf.decode_csv(
value, record_defaults=record_defaults,field_delim=',')
csv decoder를 사용하기 위해서는 각 필드의 디폴트 값을 지정해줘야 한다. record_default는 각 필드의 디폴트 값을 지정해 주는 것은 물론이고, 각 필드의 데이타 타입을 (string,int,float etc)를 정의 하는 역할을 한다.
디폴트 값은 csv 데이타에서 해당 필드가 비워져 있을때 채워 진다.
위에서는 record_deafult에서 첫번째 필드는 string 형이고 디폴트는 “null”로, 두번째 필드는 integer 형이고, 디폴트 값은 1로, 세번째 필드는 integer 형이고 디폴트는 1900 으로, 네번째와 다섯번째 필드는 모두 string형이고, 디폴트 값을 “null” 로 지정하였다.
이 디폴트 값 세팅을 가지고 tf.decode_csv를 이용하여 파싱 한다.
value는 앞에서 읽어 드린 CSV 문자열이다. record_defaults= 를 이용하여 레코드의 형과 디폴트 값을 record_defaults에 정해진 값으로 지정하였고, CSV 파일에서 각 필드를 구분하기 위한 구분자를 ‘,’를 사용한다는 것을 명시 하였다.
다음 Session을 실행하여, 이 Decoder를 실행하면 csv의 각 행을 파싱하여, 각 필드를 id,num,year,rtype,rtime이라는 필드에 리턴하게 된다.
이를 정리해보면 다음과 같은 구조를 가지게 된다.
예제
위에서 설명한 CSV 파일명을 받아서 TextLineReader를 이용하여 각 파일을 읽고, 각 파일에서 CSV 포맷의 데이타를 읽어서 출력하는 예제의 전체 코드를 보면 다음과 같다.
import tensorflow as tf
from numpy.random.mtrand import shuffle
#define filename queue
filename_queue = tf.train.string_input_producer(['/Users/terrycho/training_datav2/queue_test_data/b1.csv'
,'/Users/terrycho/training_datav2/queue_test_data/c2.csv']
,shuffle=False,name='filename_queue')
# define reader
reader = tf.TextLineReader()
key,value = reader.read(filename_queue)
#define decoder
record_defaults = [ ["null"],[1],[1900],["null"],["null"]]
id, num, year, rtype , rtime = tf.decode_csv(
value, record_defaults=record_defaults,field_delim=',')
with tf.Session() as sess:
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
for i in range(100):
print(sess.run([id, num, year, rtype , rtime]))
coord.request_stop()
coord.join(threads)
지금까지 파일에서 데이타를 읽어서 학습 데이타로 사용하는 방법에 대해서 알아보았다.
다음에는 이미지 기반의 CNN 모델을 학습 시키기 위해서 이미지 데이타를 전처리 하고 읽는 방법에 대해서 설명하도록 하겠다.
'빅데이타 & 머신러닝 > 머신러닝' 카테고리의 다른 글
연예인 얼굴 인식 서비스를 만들어보자 #2-CSV에 있는 이미지 목록을 텐서로 읽어보자 (4) | 2017.03.15 |
---|---|
연예인 얼굴 인식 서비스를 만들어보자 #1 - 학습 데이타 준비하기 (2) | 2017.03.14 |
텐서플로우-파일에서 학습 데이타를 읽어보자 #1 (큐 사용 방법과 구조) (4) | 2017.03.07 |
텐서플로우에서 이미지 데이타 처리 성능 향상방법 (2) | 2017.02.25 |
머신러닝 이미지 데이타 뻥튀기 방법 (0) | 2017.02.25 |