!pip install -q tfds-nightly tensorflow matplotlib

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf

import tensorflow_datasets as tfds

"""
Explanation: TensorFlow Datasets
TFDS provides a collection of ready-to-use datasets for use with TensorFlow, Jax, and other Machine Learning frameworks.
It handles downloading and preparing the data deterministically and constructing a tf.data.Dataset (or np.array).
Note: Do not confuse TFDS (this library) with tf.data (TensorFlow API to build efficient data pipelines). TFDS is a high level wrapper around tf.data. If you're not familiar with this API, we encourage you to read the official tf.data guide first.
Copyright 2018 The TensorFlow Datasets Authors, Licensed under the Apache License, Version 2.0
<table class="tfo-notebook-buttons" align="left">
  <td>     <a target="_blank" href="https://www.tensorflow.org/datasets/overview"><img src="https://www.tensorflow.org/images/tf_logo_32px.png">TensorFlow.org에서 보기</a>   </td>
  <td><a target="_blank" href="https://colab.research.google.com/github/tensorflow/docs-l10n/blob/master/site/ko/datasets/overview.ipynb"><img src="https://www.tensorflow.org/images/colab_logo_32px.png">Google Colab에서 실행</a></td>
  <td><a target="_blank" href="https://github.com/tensorflow/docs-l10n/blob/master/site/ko/datasets/overview.ipynb"><img src="https://www.tensorflow.org/images/GitHub-Mark-32px.png">GitHub에서 소스 보기</a></td>
  <td><a href="https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/ko/datasets/overview.ipynb"><img src="https://www.tensorflow.org/images/download_logo_32px.png">노트북 다운로드</a></td>
</table>

설치
TFDS는 두 가지 패키지로 존재합니다.

pip install tensorflow-datasets: 안정적인 버전으로, 몇 개월마다 릴리스됩니다.
pip install tfds-nightly: 매일 릴리스되며, 데이터세트의 마지막 버전이 포함됩니다.

이 colab은 tfds-nightly를 사용합니다.
End of explanation
"""


tfds.list_builders()

"""
Explanation: 사용 가능한 데이터세트 찾기
모든 데이터세트 빌더는 tfds.core.DatasetBuilder의 서브 클래스입니다. 사용 가능한 빌더의 목록을 얻으려면, tfds.list_builders()를 사용하거나 카탈로그를 살펴보세요.
End of explanation
"""


ds = tfds.load('mnist', split='train', shuffle_files=True)
assert isinstance(ds, tf.data.Dataset)
print(ds)

"""
Explanation: 데이터세트 로드하기
tfds.load
데이터세트를 로드하는 가장 쉬운 방법은 tfds.load입니다.

데이터를 다운로드하여 tfrecord 파일로 저장합니다.
tfrecord를 로드하고 tf.data.Dataset를 생성합니다.
End of explanation
"""


builder = tfds.builder('mnist')
# 1. Create the tfrecord files (no-op if already exists)
builder.download_and_prepare()
# 2. Load the `tf.data.Dataset`
ds = builder.as_dataset(split='train', shuffle_files=True)
print(ds)

"""
Explanation: 몇 가지 일반적인 인수:

split=: 읽을 분할(예: 'train', ['train', 'test'], 'train[80%:]',...). 분할 API 가이드를 참조하세요.
shuffle_files=: 각 epoch 간에 파일을 셔플할지 여부를 제어합니다(TFDS는 큰 데이터세트를 여러 개의 작은 파일에 저장합니다).
data_dir=: 데이터세트가 저장된 위치(기본값은 ~/tensorflow_datasets/)
with_info=True: 데이터세트 메타 데이터를 포함하는 tfds.core.DatasetInfo를 반환합니다.
download=False: 다운로드를 비활성화합니다.

tfds.builder
tfds.load는 tfds.core.DatasetBuilder를 둘러싼 얇은 래퍼입니다. tfds.core.DatasetBuilder API를 사용하여 같은 출력을 얻을 수 있습니다.
End of explanation
"""


ds = tfds.load('mnist', split='train')
ds = ds.take(1)  # Only take a single example

for example in ds:  # example is `{'image': tf.Tensor, 'label': tf.Tensor}`
  print(list(example.keys()))
  image = example["image"]
  label = example["label"]
  print(image.shape, label)

"""
Explanation: tfds build CLI
특정 데이터 세트를 생성하려는 경우tfds 명령 줄을 사용할 수 있습니다. 예시:
sh
tfds build mnist
사용 가능한 플래그 는 문서 를 참조하십시오.
데이터세트 반복하기
dict
기본적으로 tf.data.Dataset 객체에는 tf.Tensor의 dict가 포함됩니다.
End of explanation
"""


ds = tfds.load('mnist', split='train', as_supervised=True)
ds = ds.take(1)

for image, label in ds:  # example is (image, label)
  print(image.shape, label)

"""
Explanation: dict 키 이름과 구조를 찾으려면 카탈로그 의 데이터세트 설명서를 참조하세요(예: mnist 문서).
튜플로(as_supervised=True)
as_supervised=True를 사용하면 감독된 데이터세트 대신 튜플 (features, label)을 얻을 수 있습니다.
End of explanation
"""


ds = tfds.load('mnist', split='train', as_supervised=True)
ds = ds.take(1)

for image, label in tfds.as_numpy(ds):
  print(type(image), type(label), label)

"""
Explanation: numpy로(tfds.as_numpy)
tfds.as_numpy를 사용하여 변환합니다.

tf.Tensor &gt; np.array
tf.data.Dataset -&gt; Iterator[Tree[np.array]](Tree는 임의의 중첩된 Dict, Tuple일 수 있음)
End of explanation
"""


image, label = tfds.as_numpy(tfds.load(
    'mnist',
    split='test',
    batch_size=-1,
    as_supervised=True,
))

print(type(image), image.shape)

"""
Explanation: 일괄 처리된 tf.Tensor로(batch_size=-1)
batch_size=-1을 사용하여 전체 데이터세트를 단일 배치로 로드할 수 있습니다.
as_supervised=True 및 tfds.as_numpy와 결합하여 데이터를 (np.array, np.array)로 가져올 수 있습니다.
End of explanation
"""


ds = tfds.load('mnist', split='train')
ds = ds.batch(32).prefetch(1)

tfds.benchmark(ds, batch_size=32)
tfds.benchmark(ds, batch_size=32)  # Second epoch much faster due to auto-caching

"""
Explanation: 데이터세트가 메모리에 저장하기 적합하고, 모든 예제의 형상이 같습니다.
데이터세트 벤치마킹
데이터세트를 벤치마킹하려면 모든 iterable(예: tf.data.Dataset, tfds.as_numpy,...}에서 간단히 tfds.benchmark를 호출하면 됩니다.
End of explanation
"""


ds, info = tfds.load('mnist', split='train', with_info=True)

tfds.as_dataframe(ds.take(4), info)

"""
Explanation: batch_size= kwarg를 사용하여 배치 크기별로 결과를 정규화하는 것을 잊지 마세요.
요약하면, tf.data.Dataset 추가 설정 시간(예: 버퍼 초기화 등)을 캡처하기 위해 첫 번째 웜업 배치가 다른 배치와 분리됩니다.
TFDS 자동 캐싱으로 인해 두 번째 반복이 훨씬 더 빨라진 것을 확인하세요.
tfds.benchmark는 추가 분석을 위해 검사할 수 있는 tfds.core.BenchmarkResult를 반환합니다.

엔드 투 엔드 파이프라인 빌드하기
더 진행하려면, 다음을 살펴볼 수 있습니다.

전체 훈련 파이프라인(배치 처리, 셔플링 등)을 확인하는 엔드 투 엔드 Keras 예제
파이프라인 속도 향상을 위한 성능 가이드(팁: tfds.benchmark(ds)를 사용하여 데이터세트 벤치마킹).

시각화
tfds.as_dataframe
tf.data.Dataset 객체는 Colab에서 시각화할 tfds.as_dataframe과 함께 pandas.DataFrame으로 변환할 수 있습니다.

이미지, 오디오, 텍스트, 동영상을 시각화하기 위해 tfds.core.DatasetInfo을 tfds.as_dataframe의 두 번째 인수로 추가합니다.
ds.take(x) 를 사용하여 처음 x 예제 만 표시합니다. pandas.DataFrame 은 메모리 내 전체 데이터세트를 로드하며 표시하는 데 비용이 많이들 수 있습니다.
End of explanation
"""


ds, info = tfds.load('mnist', split='train', with_info=True)

fig = tfds.show_examples(ds, info)

"""
Explanation: tfds.show_examples
tfds.show_examples는 matplotlib.figure.Figure를 반환합니다(현재 지원되는 이미지 데이터세트만).
End of explanation
"""


ds, info = tfds.load('mnist', with_info=True)

"""
Explanation: 데이터세트 메타 데이터에 액세스하기
모든 빌더에는 데이터세트 메타 데이터를 포함하는 tfds.core.DatasetInfo 객체가 포함됩니다.
다음을 통해 액세스할 수 있습니다.

tfds.load API:
End of explanation
"""


builder = tfds.builder('mnist')
info = builder.info

"""
Explanation: tfds.core.DatasetBuilder API:
End of explanation
"""


print(info)

"""
Explanation: 데이터세트 정보에는 데이터세트에 대한 추가 정보(버전, 인용, 홈페이지, 설명 등)가 포함됩니다.
End of explanation
"""


info.features

"""
Explanation: 특성 메타 데이터(레이블 이름, 이미지 형상 등)
tfds.features.FeatureDict에 액세스합니다.
End of explanation
"""


print(info.features["label"].num_classes)
print(info.features["label"].names)
print(info.features["label"].int2str(7))  # Human readable version (8 -> 'cat')
print(info.features["label"].str2int('7'))

"""
Explanation: 클래스 수, 레이블 이름:
End of explanation
"""


print(info.features.shape)
print(info.features.dtype)
print(info.features['image'].shape)
print(info.features['image'].dtype)

"""
Explanation: 형상, dtype:
End of explanation
"""


print(info.splits)

"""
Explanation: 분할 메타 데이터(예: 분할 이름, 예제 수 등)
tfds.core.SplitDict에 액세스합니다.
End of explanation
"""


print(list(info.splits.keys()))

"""
Explanation: 사용 가능한 분할:
End of explanation
"""


print(info.splits['train'].num_examples)
print(info.splits['train'].filenames)
print(info.splits['train'].num_shards)

"""
Explanation: 개별 분할에 대한 정보를 얻습니다.
End of explanation
"""


print(info.splits['train[15%:75%]'].num_examples)
print(info.splits['train[15%:75%]'].file_instructions)

"""
Explanation: 하위 분할 API와도 동작합니다.
End of explanation
"""


