다음 글을 참조하여 번역합니다(+ 개인 공부), 예제는 tf 2.0을 기준으로 합니다.
https://www.tensorflow.org/guide/data?hl=en
tf.data API는 복잡한 input pipeline을 재사용성, 단순하게 만들어 사용할 수 있게 합니다. 예를 들어, 이미지 모델을 위한 파이프라인은 분산 파일 시스템에서 데이터를 통합하고, 각 이미지에 랜덤 변화를 주고, 학습에서 랜덤하게 선택한 이미지를 병합하여 사용할 수 있습니다. 텍스트 모델을 위한 파이프라인은 원본 텍스트 데이터에서 심볼을 추출하고, 룩업 테이블의 임베딩 식별자로 변환하여, 길이가 다른 시퀀스를 일괄 처리할 수 있습니다. tf.data API는 대용량의 데이터를 다룰 수 있게 도와주고, 서로 다른 데이터 포맷을 읽을 수 있으며, 복잡한 변환 작업을 수행합니다.
tf.data API는 일련의 요소를 나타낼 수 있는 tf.data.Dataset abstraction을 소개합니다. 예를 들어, 이미지 파이프라인에서 요소는 이미지와 레이블을 나타내는 텐서의 요소 쌍인 단일 학습 예시를 나타낼 수 있습니다.
dataset을 생성하는 두 가지 방법이 있습니다.
- data source는 메모리 또는 하나 이상의 파일에 저장된 데이터로 구성합니다.
- 데이터 변환은 하나 이상의 tf.data.Dataset 객체에서 데이터 세트를 구성합니다.
Basic mechanics
input pipeline을 만들기 위해서는 data source를 필수적으로 사용해야 합니다. 예를 들어, 메모리에 존재하는 데이터로 Dataset을 구성하는 경우, tf.data.Dataset.from_tensors()와 tf.data.Dataset.from_tensor_slices()를 사용합니다. 만약 TFRecord 포맷을 사용하고 있다면, tf.data.TFRecordDataset()을 사용합니다.
Dataset 객체를 가지고 있으면, tf.data.Dataset 객체의 메서드를 호출하여 새로운 Dataset을 만들 수 있습니다. 예를 들어, 원소당 변환을 수행하는 Dataset.map()이나 다중 원소 변환을 수행하는 Dataset.batch() 적용할 수 있습니다. 전체 변환 목록은 tf.data.Dataset 문서를 참조하세요.
Dataset 객체는 Python iterable합니다. for-loop를 통해 해당 요소를 사용할 수 있습니다.
dataset = tf.data.Dataset.from_tensor_slices([8, 3, 0, 8, 2, 1])
dataset
- <TensorSliceDataset shapes: (), types: tf.int32>
for elem in dataset:
print(elem.numpy())
- 8 3 0 8 2 1
iter을 통해 명시적으로 python iterator를 생성하고, next를 통해 사용할 수 있습니다.
it = iter(dataset)
print(next(it).numpy())
- 8
같은 방법으로 데이터셋의 원소를 모든 요소에 대해 단일 결과를 생성하는 reduce 변환을 통해 사용할 수 있습니다. 다음 예제는 데이터셋에 존재하는 숫자의 합을 계산할 때 reduce 변환을 어떻게 활용하는지 보여줍니다.
print(dataset.reduce(0, lambda state, value: state + value).numpy())
- 22
Dataset structure
dataset는 동일한 구조의 요소를 포함하며 구조의 개별 요소는 tf.TypeSpec으로 나타낼 수 있는 Tensor, SparseTensor, RaggedTensor, TensorArray, Dataset의 구조를 가질 수 있습니다.
Dataset.element_spec 속성을 사용하면 개별 요소의 유형을 확인할 수 있습니다. 단일 요소, 튜플 요소, 중첩 튜플 요소를 가지는 tf.TypeSpec 객체를 반환합니다. 다음과 같습니다.
dataset1 = tf.data.Dataset.from_tensor_slices(tf.random.uniform([4, 10]))
dataset1.element_spec
- TensorSpec(shape=(10,), dtype=tf.float32, name=None)
dataset2 = tf.data.Dataset.from_tensor_slices(
(tf.random.uniform([4]),
tf.random.uniform([4, 100], maxval=100, dtype=tf.int32)))
dataset2.element_spec
- (TensorSpec(shape=(), dtype=tf.float32, name=None), TensorSpec(shape=(100,), dtype=tf.int32, name=None))
dataset3 = tf.data.Dataset.zip((dataset1, dataset2))
dataset3.element_spec
- (TensorSpec(shape=(10,), dtype=tf.float32, name=None), (TensorSpec(shape=(), dtype=tf.float32, name=None), TensorSpec(shape=(100,), dtype=tf.int32, name=None)))
# Dataset containing a sparse tensor.
dataset4 = tf.data.Dataset.from_tensors(tf.SparseTensor(indices=[[0, 0], [1, 2]], values=[1, 2], dense_shape=[3, 4]))
dataset4.element_spec
- SparseTensorSpec(TensorShape([3, 4]), tf.int32)
여기서 tf.SparseTensor(indices=[[0, 0], [1, 2]], values =[1, 2], dense_shape=[3, 4])는 다음과 같은 결과를 보여줍니다.
- [[1, 0, 0, 0]
[0, 0, 2, 0]
[0, 0, 0, 0]]
indices는 [0, 0], [1, 2]에 각각 non-zero value가 있음을 명시합니다. 실제로 위의 결과에서 [0, 0]에는 value의 첫 번째 값인 1, [1, 2]에는 두 번째 값인 2가 출력되고 있습니다. dense_shape = [3, 4]는 (3, 4)의 2차원 텐서를 나타냅니다.
# Use value_type to see the type of value represented by the element spec
dataset4.element_spec.value_type
- tensorflow.python.framework.sparse_tensor.SparseTensor
Dataset 변환은 어떠한 구조의 dataset도 지원할 수 있습니다.각 원소에 함수를 적용하는 Dataset.map()과 Dataset.filter() 변환을 사용할 때, 요소 구조는 함수의 인수를 결정합니다.
dataset1 = tf.data.Dataset.from_tensor_slices(
tf.random.uniform([4, 10], minval=1, maxval=10, dtype=tf.int32))
dataset1
- <TensorSliceDataset shapes: (10,), types: tf.int32>
for z in dataset1:
print(z.numpy())
- [8 9 2 7 2 4 8 8 1 7]
[6 8 6 5 6 5 1 7 3 7]
[8 6 9 8 7 9 4 7 4 7]
[4 1 2 5 9 9 1 9 6 8]
dataset2 = tf.data.Dataset.from_tensor_slices(
(tf.random.uniform([4]),
tf.random.uniform([4, 100], maxval=100, dtype=tf.int32)))
dataset2
- <TensorSliceDataset shapes: ((), (100,)), types: (tf.float32, tf.int32)>
dataset3 = tf.data.Dataset.zip((dataset1, dataset2))
dataset3
- <ZipDataset shapes: ((10,), ((), (100,))), types: (tf.int32, (tf.float32, tf.int32))>
for a, (b,c) in dataset3:
print('shapes: {a.shape}, {b.shape}, {c.shape}'.format(a=a, b=b, c=c))
- shapes: (10,), (), (100,)
shapes: (10,), (), (100,)
shapes: (10,), (), (100,)
shapes: (10,), (), (100,)
'# Machine Learning > TensorFlow doc 정리' 카테고리의 다른 글
tf.data tutorial 번역 (3) (0) | 2020.02.26 |
---|---|
tf.data tutorial 번역 (2) (0) | 2020.02.18 |
tensorflow 2.0 keras Write custom callbacks (2) | 2019.04.18 |
tensorflow 2.0 keras Saving and Serializing Models with Tensorflow Keras (0) | 2019.04.15 |
tensorflow 2.0 keras Writing layers and models with tf keras (2) (0) | 2019.04.13 |