# from_generator
텐서플로 vs. 파이토치
이야기가 많다. 텐서플로는 어렵다는 인식이 있다.
개인적으로도 텐서플로는 접근을 위한 초기 장벽, 보통 러닝-커브 라고 인식하는 부분이 높다고 생각한다.
하지만,
텐서플로와 파이토치 사이에서 무엇이 우수한지는 쉽게 결정할 수 없다.
각자 가지고 있는 장점이 있고,
내가 무엇을 하고자 하는지에 따라서도 선택의 갈림길이 생긴다.
난 텐서플로 2 버젼이 나오면서 이러한 고민들이 모두 사라졌다.
훨씬 유연하고 어떠한 상황에서도 설계가 가능하도록 머릿속에 구상을 할 수 있다.
그래서 텐서플로 vs. 파이토치 고민에서 자유로워 질 수 있었다.
그 중에서도 Dataset의 from_generator 를 첫번째로 이야기 할 수 있다.
간단하게 generator 형식을 학습 데이터로 활용할 수 있도록 도와준다.
시나리오는 이렇다.
혹시 내가 AWS에 S3 내부에서 큰 파일을 가지고 있다고 가정하자.
이걸 전부 읽어들인 후에, 전처리를 하고, 기타 다른 조작을 가하면서 변수에 담아두려고 한다면,
100% 메모리를 다 사용하고,
머지않아 메모리가 부족한 현상이 나타날 수 있다.
파이썬을 활용할 때 보통 메모리 문제는 generator 로 해결 할 수 있다.
이걸 텐서플로에서도 같은 방식으로 사용할 수 있는데,
더 쉽고 간결하게 구현할 수 있다.
import tensorflow as tf
import smart_open
import numpy as np
path = './data/train_prod.dat'
# 대략 32GB 정도의 파일이 있다. S3에서 다운로드 하였다.
# 원한다면 S3에서 파로 읽으면서 데이터셋을 구성할 수도 있다.
def gen_data(stop):
with smart_open.open(path, 'r') as fin:
for i, line in enumerate(fin):
_line = line.strip().split(' ')
if len(_line) > stop:
yield tf.keras.preprocessing.sequence.pad_sequences(np.array(_line).astype(np.int32).reshape(1, -1), maxlen=100, padding='post')[0]
# 간단하게 데이터를 만들어본다.
# 파일에서 직접 읽어들이면서 generator 를 구현한다.
# 필요한 전처리는 yield 직전에 직접 구현하거나 함수를 만들어 적용시킬 수 있다.
gen_dataset = tf.data.Dataset.from_generator(gen_data, args=[10,],
output_types=(tf.int32),
output_shapes=(None,), )
# 각자의 데이터 성격을 파악하고 있어야 하는데,
# 내가 가진 데이터는 가변의 2-D 데이터 형태를 가진다.
# 가변이기 때문에 output_shapes 를 None 으로 표현했다.
# 하지만 전처리를 통해서 가변으로 구성된 데이터를 maxlen=100 으로 잡아주면서 None --> 100 으로 수정해도 문제가 없어진다.
for data_batch in gen_dataset.repeat().batch(32).take(1):
print(data_batch.numpy())
break
# 32GB를 모두 읽어들이지 않았지만,
# 데이터의 일부를 확인해 볼 수 있다.
텐서플로 + 케라스 조합은 이후에 모델 레이어를 구성하고 연결하는데 기타 다른 딥러닝 프레임워크들 보다 편리하고 유연하다.
데이터를 학습하고 평가할 때,
위와 같은 방식으로 데이터셋을 만들고 넣어주면 된다.
참고:
https://www.tensorflow.org/guide/data