본문 바로가기
AI 이론과 개발의 혼재/Implementation

Tensorflow, Input pipeline 예제 코드 (string_input_producer)

by ministar 2018. 8. 28.


Tensorflow
Input Pipeline 구현


TensorFlow를 이용해서 딥러닝을 구현하고자 할 때, 
먼저 데이터를 로드하고, 그래프를 정의하고 학습을 하는 코드를 작성할 것이다.
가장 먼저 일어나는 학습 데이터를 불러오는 일은 보통 Numpy나 Pandas로 처리하기도 하지만,
최근에는 메모리 활용을 잘한다는 tf.Data API 또한 많이 이용하고 있다. 

내가 만난 문제점은 바로 이 것 ,,

만약 Training Data의 용량이 매~우 클 경우에는 
한번에 Load할 경우,
엄청나게 많은 Memory를 잡고있기 때문에 효율적이지 못하다.

어떻게 적은 메모리를 사용하면서 대용량의 이미지 데이터를 학습할 수 있을까? 


string_input_producer 활용방법


1) Image File Directory 정의



#img files directory img_file_names = os.listdir(f'{os.getcwd()}\img_data') img_file_names = [ f'{os.getcwd()}\img_data\{f_nm}' for f_nm in img_file_names ]


예) ['C:\\Dev\\pythonStudy\\adc\\img_data\\001.jpg', 
'C:\\Dev\\pythonStudy\\adc\\img_data\\002.jpg', 
  'C:\\Dev\\pythonStudy\\adc\\img_data\\003.jpg', 
  'C:\\Dev\\pythonStudy\\adc\\img_data\\004.jpg', 
...
,   'C:\\Dev\\pythonStudy\\adc\\img_data\\010.jpg' ] 

2) input producer 정의

string_input_producer를 이용하여 파일명들을 큐잉으로 읽어들일 수 있게 하는 작업으로,
여러 개의 File을 읽기 위해서는 list형으로 file명들을 넣어주면 된다.


filenameQ = tf.train.string_input_producer(img_file_names, shuffle=False, num_epochs=1) reader = tf.WholeFileReader() key, value = reader.read(filenameQ) #simple image preprocessing img = tf.image.decode_png(value, channels=1) img = tf.image.convert_image_dtype(img, tf.float32) resized_img = tf.image.resize_images(img, [512, 512]) #resize rot_img = tf.image.rot90(resized_img) #rotate


Note.
tf.train.string_input_producer에서 num_epoch를 None으로 설정해놓으면
계속 반복해서 input을 생성하게 됨
(000.jpg , ... , 010.jpg, 000.jpg, ... , 010.jpg, ... 이런식으로 무한루프)

3) Batch 정의

tf.train.batch 함수는 batch_size에 맞춰 데이터를 묶어서 리턴해주는 함수이다.
입력 텐서의 shape이 [x,y,z]일 경우 return 값은 [batch_size, x , y , z] 가 된다.


img_batch = tf.train.batch([resized_img], batch_size=3)

 

4) TensorFlow initialization

#string_input_producer에서 num_epoch값 설정시 아래 코드 error 발생 #init_op = tf.global_variables_initializer() #proposed init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())


* 여기서 주의할 점!
tf.train.string_input_producer에서 num_epoch에 값을 주면 실행할 때 에러가 발생한다.
FailedPreconditionError: Attempting to use uninitialized value input_producer/limit_epochs/epochs
[[Node: input_producer/limit_epochs/CountUpTo = CountUpTo[T=DT_INT64, _class=["loc:@input_producer/limit_epochs/epochs"], limit=1, _device="/job:localhost/replica:0/task:0/cpu:0"](input_producer/limit_epochs/epochs)]]
initalizer에 tf.local_variables_initializer()를 추가 시켜주면 깔끔하게 해결~!

 

5) Test (Main)

세션을 정의하고 데이터를 순차적으로 읽어들이기 위한 Queue runner를 수행! (start_queue_runners)
작업이 끝난 후, 해당 thread를 종료시켜준다 ~!



with tf.Session() as sess: sess.run(init_op) coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(coord=coord) try : while not coord.should_stop(): x_batch = sess.run([img_batch]) for x in x_batch : print('~~~~') except tf.errors.OutOfRangeError: print('error') pass finally: print('end finally') coord.request_stop() coord.join(threads)


댓글