TPU 속도의 데이터 파이프라인: tf.data.Dataset 및 TFRecords

TPU 속도의 데이터 파이프라인:
tf.data.Dataset 및 TFRecords

이 Codelab 정보

subject최종 업데이트: 10월 4, 2021
account_circle작성자: Martin Görner - @martin_gorner

1. 개요

TPU는 매우 빠릅니다. 학습 데이터 스트림은 학습 속도를 따라갈 수 있어야 합니다. 이 실습에서는 tf.data.Dataset API로 GCS에서 데이터를 로드하여 TPU에 제공하는 방법을 알아봅니다.

이 실습은 'TPU 기반 Keras'의 1부입니다. Google Cloud 시리즈를 확인해 보세요 다음 순서대로 또는 개별적으로 수행할 수 있습니다.

ca8cc21f6838eccc.png

학습할 내용

  • tf.data.Dataset API를 사용해 학습 데이터 로드하기
  • TFRecord 형식을 사용하여 GCS에서 학습 데이터를 효율적으로 로드하기 위해

의견

이 Codelab에서 잘못된 부분을 발견하면 알려주세요. 의견은 GitHub 문제[의견 링크]를 통해 제공할 수 있습니다.

2. Google Colaboratory 빠른 시작

이 실습에서는 Google Collaboratory를 사용하므로 사용자가 별도로 설정할 필요가 없습니다. Colaboratory는 교육용 온라인 노트북 플랫폼입니다. 무료 CPU, GPU, TPU 학습을 제공합니다.

688858c21e3beff2.png

이 샘플 노트북을 열고 몇 개의 셀을 실행하여 Colaboratory에 익숙해지세요.

c3df49e90e5a654f.png Welcome to Colab.ipynb

TPU 백엔드 선택

8832c6208c99687d.png

Colab 메뉴에서 런타임 > 런타임 유형 변경을 선택한 다음 TPU를 선택합니다. 이 Codelab에서는 하드웨어 가속 학습에 지원되는 강력한 TPU (Tensor Processing Unit)를 사용합니다. 처음 실행 시 런타임에 자동으로 연결이 이루어집니다. 또는 '연결' 버튼을 클릭합니다.

노트북 실행

76d05caa8b4db6da.png

셀을 클릭하고 Shift-Enter를 사용하여 셀을 한 번에 하나씩 실행합니다. 런타임 > 모두 실행

목차

429f106990037ec4.png

모든 노트북에는 목차가 있습니다. 왼쪽에 있는 검은색 화살표를 사용해 파일을 열 수 있습니다.

숨겨진 셀

edc3dba45d26f12a.png

일부 셀에는 제목만 표시됩니다. Colab 전용 노트북 기능입니다. 두 번 클릭하면 안의 코드를 볼 수 있지만 보통은 그다지 흥미롭지 않습니다. 일반적으로 지원 또는 시각화 함수입니다. 내부의 함수를 정의하려면 이러한 셀을 실행해야 합니다.

인증

cdd4b41413100543.png

승인된 계정으로 인증하면 Colab에서 비공개 Google Cloud Storage 버킷에 액세스할 수 있습니다. 위의 코드 스니펫은 인증 프로세스를 트리거합니다.

3. [정보] Tensor Processing Unit (TPU)이란 무엇인가요?

요약

f88cf6facfc70166.png

Keras의 TPU에서 모델을 학습시키기 위한 코드 (TPU를 사용할 수 없는 경우 GPU 또는 CPU로 대체)

try: # detect TPUs
    tpu
= tf.distribute.cluster_resolver.TPUClusterResolver.connect()
    strategy
= tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
    strategy
= tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines

# use TPUStrategy scope to define model
with strategy.scope():
  model
= tf.keras.Sequential( ... )
  model
.compile( ... )

# train model normally on a tf.data.Dataset
model
.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)

오늘은 TPU를 사용하여 상호작용 속도 (학습 실행당 분)의 꽃 분류기를 빌드하고 최적화해 보겠습니다.

688858c21e3beff2.png

TPU를 사용해야 하는 이유

최신 GPU는 프로그래밍 가능한 '코어'를 중심으로 구성됩니다. 코어는 3D 렌더링, 딥 러닝, 물리적 시뮬레이션 등과 같은 다양한 작업을 처리할 수 있는 매우 유연한 아키텍처입니다. 반면 TPU는 기본 벡터 프로세서에 전용 행렬 곱셈 유닛을 결합하고 신경망과 같이 큰 행렬 곱셈이 중요한 모든 작업에서 탁월한 성능을 발휘합니다.

8eb3e718b8e2ed08.png

그림: 행렬 곱셈이 적용된 밀집 신경망 레이어로, 신경망을 통해 한 번에 처리된 8개의 이미지 배치가 포함됩니다. 한 줄 x 열 곱셈을 실행하여 이미지의 모든 픽셀 값에 대한 가중치가 적용된 합계를 실제로 수행하고 있는지 확인하세요. 컨볼루셔널 레이어는 조금 더 복잡하지만 ( 이 섹션 1의 설명)도 행렬 곱셈으로 표현할 수 있습니다.

하드웨어

MXU 및 VPU

TPU v2 코어는 행렬 곱셈과 VPU(벡터 처리 장치)를 실행하는 MXU(Matrix Multiply Unit)로 구성되며, 활성화, softmax 등의 기타 모든 작업을 위한 VPU(벡터 처리 장치)가 실행됩니다. VPU는 float32 및 int32 계산을 처리합니다. 반면에 MXU는 혼합 정밀도 16~32비트 부동 소수점 형식으로 작동합니다.

7d68944718f76b18.png

정밀도 부동 소수점과 bfloat16이 혼합됨

MXU는 bfloat16 입력 및 float32 출력을 사용하여 행렬 곱셈을 계산합니다. 중간 누적은 float32 정밀도로 실행됩니다.

19c5fc432840c714.png

신경망 학습은 일반적으로 부동 소수점 정밀도 감소로 인해 발생하는 노이즈에 강합니다. 노이즈가 옵티마이저가 수렴하는 데까지 도움이 되는 경우도 있습니다. 전통적으로 16비트 부동 소수점 정밀도는 계산을 가속화하는 데 사용되었지만 float16 및 float32 형식은 범위가 매우 다릅니다. 정밀도를 float32에서 float16으로 줄이면 일반적으로 오버 및 언더플로가 발생합니다. 솔루션이 있지만 float16이 작동하려면 일반적으로 추가 작업이 필요합니다.

이러한 이유로 Google은 TPU에 bfloat16 형식을 도입했습니다. bfloat16은 float32와 정확히 동일한 지수 비트와 범위를 가진 잘린 float32입니다. 이는 TPU가 bfloat16 입력과 float32 출력의 혼합 정밀도로 행렬 곱셈을 계산한다는 사실에 더해, 일반적으로 낮은 정밀도의 성능 향상 이점을 누리기 위해 코드를 변경할 필요가 없다는 뜻입니다.

수축 배열

MXU는 이른바 '시스톨릭 배열'을 사용하여 하드웨어에서 행렬 곱셈을 구현합니다. 데이터 요소가 하드웨어 계산 장치의 배열을 통해 흐르는 아키텍처. (의학에서 '수축기'는 심장 수축과 혈류, 여기서는 데이터의 흐름을 의미합니다.)

행렬 곱셈의 기본 요소는 한 행렬의 선과 다른 행렬의 열 사이의 내적입니다 (이 섹션 상단의 그림 참조). 행렬 곱셈 Y=X*W의 경우 결과의 한 요소는 다음과 같습니다.

Y[2,0] = X[2,0]*W[0,0] + X[2,1]*W[1,0] + X[2,2]*W[2,0] + ... + X[2,n]*W[n,0]

GPU에서는 이 제품을 GPU '코어'로 프로그래밍합니다. 최대한 많은 '코어'에서 결과 행렬의 모든 값을 한 번에 계산하려고 시도합니다. 결과 행렬이 128x128 큰 경우 128x128=16K '코어'가 필요합니다. 일반적으로는 불가능한 상태입니다 가장 큰 GPU에는 약 4000개의 코어가 있습니다. 반면 TPU는 MXU의 컴퓨팅 단위에 최소한의 하드웨어만 사용합니다. 즉, bfloat16 x bfloat16 => float32 곱셈-누산기만 사용합니다. 이러한 연산은 매우 작아서 TPU에서 128x128 MXU로 16K를 구현하고 한 번에 행렬 곱셈을 처리할 수 있습니다.

f1b283fc45966717.gif

그림: MXU 수축기 배열 컴퓨팅 요소는 곱셈-누산기입니다. 한 행렬의 값이 배열 (빨간색 점)에 로드됩니다. 다른 행렬의 값은 배열 (회색 점)을 통과합니다. 수직선은 값을 위로 전파합니다. 가로선은 부분 합계를 전파합니다. 데이터가 배열을 통과할 때 오른쪽에서 행렬 곱셈의 결과가 나오는지 확인하는 작업은 사용자의 연습으로 남겨 둡니다.

그 밖에도, 내적이 MXU에서 계산되는 동안 중간 합계는 단순히 인접한 컴퓨팅 단위 간에 흐릅니다. 메모리 또는 레지스터 파일에서도 저장하고 검색할 필요가 없습니다. 결과적으로 TPU 시스톨릭 배열 아키텍처는 밀도와 전력 측면에서 상당한 이점을 얻을 뿐만 아니라 행렬 곱셈을 계산할 때 GPU에 비해 무시할 수 없는 속도상의 이점을 얻게 됩니다.

Cloud TPU

" Cloud TPU v2인치 PCI 연결 TPU 보드가 포함된 가상 머신 (VM)을 얻을 수 있습니다. TPU 보드에는 4개의 듀얼 코어 TPU 칩이 있습니다. 각 TPU 코어에는 VPU (벡터 처리 장치)와 128x128 MXU (MatriX 곱하기 단위)가 있습니다. 이 'Cloud TPU'는 일반적으로 네트워크를 통해 이를 요청한 VM에 연결됩니다. 전체 그림은 다음과 같습니다.

dfce5522ed644ece.png

그림: 네트워크에 연결된 'Cloud TPU'가 있는 VM 액셀러레이터를 생성합니다 'Cloud TPU' 듀얼 코어 TPU 칩이 4개 있는 PCI 연결 TPU 보드가 탑재된 VM으로 구성됩니다.

TPU 포드

Google의 데이터 센터에서 TPU는 고성능 컴퓨팅 (HPC) 상호 연결에 연결되어 하나의 거대한 가속기처럼 보일 수 있습니다. Google은 이를 포드라고 부르며 최대 512개의 TPU v2 코어 또는 2,048개의 TPU v3 코어를 포함할 수 있습니다.

2ec1e0d341e7fc34.jpeg

그림: TPU v3 포드 HPC Interconnect를 통해 연결된 TPU 보드 및 랙

학습 중에는 AllReduce 알고리즘을 사용하여 TPU 코어 간에 경사가 교환됩니다 ( 여기에 all-Reduce에 대한 자세한 설명). 학습 중인 모델은 큰 배치 크기로 학습시켜 하드웨어를 활용할 수 있습니다.

d97b9cc5d40fdb1d.gif

그림: Google TPU의 2D 원환형 메시 HPC 네트워크에서 AllReduce 알고리즘을 사용하여 학습 중 경사의 동기화

소프트웨어는

대형 배치 크기 학습

TPU에 이상적인 배치 크기는 TPU 코어당 128개의 데이터 항목이지만, 하드웨어는 이미 TPU 코어당 8개의 데이터 항목 중에서 적절한 사용률을 표시하고 있습니다. Cloud TPU 한 개에는 코어가 8개 있습니다.

이 Codelab에서는 Keras API를 사용합니다. Keras에서 지정하는 배치는 전체 TPU의 전역 배치 크기입니다. 배치가 자동으로 8개로 분할되어 TPU의 8개 코어에서 실행됩니다.

da534407825f01e3.png

추가 성능 팁은 TPU 성능 가이드를 참조하세요. 매우 큰 배치 크기의 경우 일부 모델에서 특별한 주의가 필요할 수 있습니다. 자세한 내용은 LARSOptimizer를 참고하세요.

비하인드 스토리: XLA

TensorFlow 프로그램은 계산 그래프를 정의합니다. TPU는 Python 코드를 직접 실행하지 않고 TensorFlow 프로그램에서 정의한 계산 그래프를 실행합니다. 내부적으로 XLA (가속 선형 대수 컴파일러)라는 컴파일러는 계산 노드의 TensorFlow 그래프를 TPU 기계어 코드로 변환합니다. 이 컴파일러는 코드 및 메모리 레이아웃에 관해 다양한 고급 최적화도 실행합니다. 작업이 TPU로 전송될 때 컴파일이 자동으로 실행됩니다. 빌드 체인에 명시적으로 XLA를 포함하지 않아도 됩니다.

edce61112cd57972.png

그림: TPU에서 실행하기 위해 TensorFlow 프로그램에서 정의한 계산 그래프는 먼저 XLA (가속 선형 대수학 컴파일러) 표현으로 변환된 다음 XLA를 통해 TPU 머신 코드로 컴파일됩니다.

Keras에서 TPU 사용

TPU는 Tensorflow 2.1부터 Keras API를 통해 지원됩니다. Keras 지원은 TPU 및 TPU 포드에서 작동합니다. 다음은 TPU, GPU, CPU에서 작동하는 예입니다.

try: # detect TPUs
    tpu
= tf.distribute.cluster_resolver.TPUClusterResolver.connect()
    strategy
= tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
    strategy
= tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines

# use TPUStrategy scope to define model
with strategy.scope():
  model
= tf.keras.Sequential( ... )
  model
.compile( ... )

# train model normally on a tf.data.Dataset
model
.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)

이 코드 스니펫에서 각 항목의 의미는 다음과 같습니다.

  • TPUClusterResolver().connect()는 네트워크에서 TPU를 찾습니다. 대부분의 Google Cloud 시스템 (AI Platform 작업, Colaboratory, Kubeflow, 'ctpu up' 유틸리티를 통해 생성된 딥 러닝 VM)에서 매개변수 없이 작동합니다. 이러한 시스템은 TPU_NAME 환경 변수 덕분에 TPU의 위치를 알고 있습니다. TPU를 직접 만드는 경우 TPU_NAME 환경을 설정하거나 var. 사용 중인 VM에서 또는 명시적 매개변수(TPUClusterResolver(tp_uname, zone, project))를 사용하여 TPUClusterResolver를 호출합니다.
  • TPUStrategy는 분포와 'all-reduce'를 구현하는 부분입니다. 경사 동기화 알고리즘입니다.
  • 전략이 범위를 통해 적용됩니다. 모델은 전략 scope() 내에 정의되어야 합니다.
  • tpu_model.fit 함수에는 TPU 학습을 위한 입력으로 tf.data.Dataset 객체가 필요합니다.

일반적인 TPU 포팅 작업

  • TensorFlow 모델에서 데이터를 로드하는 방법에는 여러 가지가 있지만 TPU의 경우 tf.data.Dataset API를 사용해야 합니다.
  • TPU는 매우 빠르기 때문에 데이터를 수집할 때 TPU 실행 시 병목 현상이 발생하는 경우가 많습니다. TPU 성능 가이드에는 데이터 병목 현상을 감지하는 데 사용할 수 있는 도구와 기타 성능 팁이 있습니다.
  • int8 또는 int16 숫자는 int32로 취급됩니다. TPU에는 32비트 미만에서 작동하는 정수 하드웨어가 없습니다.
  • 일부 TensorFlow 작업은 지원되지 않습니다. 목록은 여기에서 확인하세요. 좋은 소식은 이 제한이 모델을 정방향 및 역방향으로 전달하는 학습 코드에만 적용된다는 것입니다. 모든 TensorFlow 작업은 CPU에서 실행되므로 데이터 입력 파이프라인에서 계속 사용할 수 있습니다.
  • tf.py_func는 TPU에서 지원되지 않습니다.

4. 데이터 로드

c0ecb860e4cad0a9.jpeg cc4781a7739c49ae.jpeg 81236b00f8bbf39e.jpeg 961e2228974076bb.jpeg 7517dc163bdffcd5.jpeg 96392df4767f566d.png

꽃 사진의 데이터 세트로 작업하겠습니다. 목표는 꽃을 5가지 꽃 유형으로 분류하는 방법을 배우는 것입니다. 데이터 로드는 tf.data.Dataset API를 사용하여 수행됩니다. 먼저 API에 대해 알아보겠습니다.

실습

다음 노트북을 열고 셀을 실행 (Shift-ENTER)한 다음 '작업 필요'가 표시되면 안내를 따르세요. 라벨을 지정합니다.

c3df49e90e5a654f.png Fun with tf.data.Dataset (playground).ipynb

추가 정보

'꽃'에 대한 정보 데이터 세트

데이터 세트는 5개의 폴더로 구성되어 있습니다. 각 폴더에는 한 종류의 꽃이 있습니다. 폴더의 이름은 해바라기, 데이지, 민들레, 튤립, 장미로 지정됩니다. 데이터는 Google Cloud Storage의 공개 버킷에서 호스팅됩니다. 발췌문:

gs://flowers-public/sunflowers/5139971615_434ff8ed8b_n.jpg
gs
://flowers-public/daisy/8094774544_35465c1c64.jpg
gs
://flowers-public/sunflowers/9309473873_9d62b9082e.jpg
gs
://flowers-public/dandelion/19551343954_83bb52f310_m.jpg
gs
://flowers-public/dandelion/14199664556_188b37e51e.jpg
gs
://flowers-public/tulips/4290566894_c7f061583d_m.jpg
gs
://flowers-public/roses/3065719996_c16ecd5551.jpg
gs
://flowers-public/dandelion/8168031302_6e36f39d87.jpg
gs
://flowers-public/sunflowers/9564240106_0577e919da_n.jpg
gs
://flowers-public/daisy/14167543177_cd36b54ac6_n.jpg

tf.data.Dataset를 사용해야 하는 이유

Keras와 Tensorflow는 모든 학습 및 평가 함수에서 데이터 세트를 허용합니다. 데이터 세트에 데이터를 로드하면 API가 신경망 학습 데이터에 유용한 모든 일반 기능을 제공합니다.

dataset = ... # load something (see below)
dataset = dataset.shuffle(1000) # shuffle the dataset with a buffer of 1000
dataset = dataset.cache() # cache the dataset in RAM or on disk
dataset = dataset.repeat() # repeat the dataset indefinitely
dataset = dataset.batch(128) # batch data elements together in batches of 128
AUTOTUNE = tf.data.AUTOTUNE
dataset = dataset.prefetch(AUTOTUNE) # prefetch next batch(es) while training

성능 팁과 데이터 세트 권장사항은 이 도움말에서 확인할 수 있습니다. 참조 문서는 여기에서 확인할 수 있습니다.

tf.data.Dataset 기본사항

데이터는 일반적으로 여러 파일(예: 이미지)으로 제공됩니다. 다음을 호출하여 파일 이름으로 구성된 데이터 세트를 만들 수 있습니다.

filenames_dataset = tf.data.Dataset.list_files('gs://flowers-public/*/*.jpg')
# The parameter is a "glob" pattern that supports the * and ? wildcards.

그런 다음 각 파일 이름에 함수를 추가합니다. 이 함수는 일반적으로 파일을 메모리의 실제 데이터로 로드하고 디코딩합니다.

def decode_jpeg(filename):
  bits
= tf.io.read_file(filename)
  image
= tf.io.decode_jpeg(bits)
 
return image

image_dataset
= filenames_dataset.map(decode_jpeg)
# this is now a dataset of decoded images (uint8 RGB format)

데이터 세트에서 반복하는 방법은 다음과 같습니다.

for data in my_dataset:
 
print(data)

튜플 데이터 세트

지도 학습에서 학습 데이터 세트는 일반적으로 학습 데이터와 정답의 쌍으로 구성됩니다. 이를 위해 디코딩 함수는 튜플을 반환할 수 있습니다. 그러면 튜플 데이터 세트가 생성되고 이 데이터 세트를 반복할 때 튜플이 반환됩니다. 반환되는 값은 모델에서 사용할 수 있는 TensorFlow 텐서입니다. .numpy()를 호출하여 원시 값을 볼 수 있습니다.

def decode_jpeg_and_label(filename):
  bits
= tf.read_file(filename)
  image
= tf.io.decode_jpeg(bits)
  label
= ... # extract flower name from folder name
 
return image, label

image_dataset
= filenames_dataset.map(decode_jpeg_and_label)
# this is now a dataset of (image, label) pairs

for image, label in dataset:
 
print(image.numpy().shape, label.numpy())

결론:이미지를 하나씩 로드하는 것이 느립니다.

이 데이터 세트를 반복하면 초당 1~2개의 이미지를 로드할 수 있음을 알 수 있습니다. 너무 느립니다. 학습에 사용할 하드웨어 가속기는 이 속도를 여러 배로 유지할 수 있습니다. 다음 섹션으로 이동하여 어떻게 이 목표를 달성할지 알아보세요.

해결 방법

다음은 솔루션 노트북입니다. 문제가 있을 때 사용할 수 있습니다.

c3df49e90e5a654f.png Fun with tf.data.Dataset (solution).ipynb

학습한 내용

  • 🤔 tf.data.Dataset.list_files
  • 🤔 tf.data.Dataset.map
  • 🤔 튜플 데이터 세트
  • 버튼 데이터 세트 반복

잠시 시간을 내어 이 체크리스트를 머릿속에 살펴보세요.

5. 빠른 데이터 로드

이 실습에서 사용할 Tensor Processing Unit (TPU) 하드웨어 가속기는 매우 빠릅니다. 이때 어려운 점은 데이터를 빨리 제공하여 이들이 바쁘게 지내도록 하는 것입니다. Google Cloud Storage (GCS)는 매우 높은 처리량을 유지할 수 있지만 다른 모든 클라우드 스토리지 시스템과 마찬가지로 연결을 시작할 때 네트워크 비용이 발생합니다. 따라서 데이터를 수천 개의 개별 파일로 저장하는 것은 이상적이지 않습니다. 더 적은 수의 파일로 일괄 처리하고 tf.data.Dataset의 기능을 사용하여 여러 파일에서 병렬로 읽어 보겠습니다.

읽기

이미지 파일을 로드하고 일반적인 크기로 크기를 조절한 후 16개의 TFRecord 파일에 저장하는 코드는 다음 노트북에 나와 있습니다. 빠르게 읽어 주세요. Codelab의 나머지 부분에서는 올바른 TFRecord 형식의 데이터가 제공되므로 이 작업을 실행할 필요가 없습니다.

c3df49e90e5a654f.png Flower pictures to TFRecords.ipynb

최적의 GCS 처리량을 위한 이상적인 데이터 레이아웃

TFRecord 파일 형식

TensorFlow에서 선호하는 데이터 저장 파일 형식은 protobuf 기반 TFRecord 형식입니다. 다른 직렬화 형식도 사용할 수 있지만 다음을 작성하여 TFRecord 파일에서 직접 데이터 세트를 로드할 수 있습니다.

filenames = tf.io.gfile.glob(FILENAME_PATTERN)
dataset
= tf.data.TFRecordDataset(filenames)
dataset
= dataset.map(...) # do the TFRecord decoding here - see below

최적의 성능을 위해 다음과 같이 더 복잡한 코드를 사용하여 여러 TFRecord 파일에서 한 번에 읽는 것이 좋습니다. 이 코드는 N개의 파일에서 동시에 읽고 데이터 순서를 무시하여 읽기 속도를 높입니다.

AUTOTUNE = tf.data.AUTOTUNE
ignore_order
= tf.data.Options()
ignore_order
.experimental_deterministic = False

filenames
= tf.io.gfile.glob(FILENAME_PATTERN)
dataset
= tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTOTUNE)
dataset
= dataset.with_options(ignore_order)
dataset
= dataset.map(...) # do the TFRecord decoding here - see below

TFRecord 요약본

TFRecord에는 바이트 문자열 (바이트 목록), 64비트 정수, 32비트 부동 소수점 수, 세 가지 유형의 데이터를 저장할 수 있습니다. 항상 목록으로 저장되며 크기가 1인 목록이 단일 데이터 요소가 됩니다. 다음 도우미 함수를 사용하여 TFRecord에 데이터를 저장할 수 있습니다.

바이트 문자열 쓰기

# warning, the input is a list of byte strings, which are themselves lists of bytes
def _bytestring_feature(list_of_bytestrings):
 
return tf.train.Feature(bytes_list=tf.train.BytesList(value=list_of_bytestrings))

정수 쓰기

def _int_feature(list_of_ints): # int64
 
return tf.train.Feature(int64_list=tf.train.Int64List(value=list_of_ints))

부동 소수점 수 작성

def _float_feature(list_of_floats): # float32
 
return tf.train.Feature(float_list=tf.train.FloatList(value=list_of_floats))

위의 도우미를 사용하여 TFRecord 작성

# input data in my_img_bytes, my_class, my_height, my_width, my_floats
with tf.python_io.TFRecordWriter(filename) as out_file:
  feature = {
    "image": _bytestring_feature([my_img_bytes]), # one image in the list
    "class": _int_feature([my_class]),            # one class in the list
    "size": _int_feature([my_height, my_width]),  # fixed length (2) list of ints
    "float_data": _float_feature(my_floats)       # variable length  list of floats
  }
  tf_record = tf.train.Example(features=tf.train.Features(feature=feature))
  out_file.write(tf_record.SerializeToString())

TFRecord에서 데이터를 읽으려면 먼저 저장한 레코드의 레이아웃을 선언해야 합니다. 선언에서 모든 이름이 지정된 필드에 고정 길이 목록 또는 가변 길이 목록으로 액세스할 수 있습니다.

TFRecord에서 읽기

def read_tfrecord(data):
  features = {
    # tf.string = byte string (not text string)
    "image": tf.io.FixedLenFeature([], tf.string), # shape [] means scalar, here, a single byte string
    "class": tf.io.FixedLenFeature([], tf.int64),  # shape [] means scalar, i.e. a single item
    "size": tf.io.FixedLenFeature([2], tf.int64),  # two integers
    "float_data": tf.io.VarLenFeature(tf.float32)  # a variable number of floats
  }

  # decode the TFRecord
  tf_record = tf.io.parse_single_example(data, features)

  # FixedLenFeature fields are now ready to use
  sz = tf_record['size']

  # Typical code for decoding compressed images
  image = tf.io.decode_jpeg(tf_record['image'], channels=3)

  # VarLenFeature fields require additional sparse.to_dense decoding
  float_data = tf.sparse.to_dense(tf_record['float_data'])

  return image, sz, float_data

# decoding a tf.data.TFRecordDataset
dataset = dataset.map(read_tfrecord)
# now a dataset of triplets (image, sz, float_data)

유용한 코드 스니펫:

단일 데이터 요소 읽기

tf.io.FixedLenFeature([], tf.string)   # for one byte string
tf
.io.FixedLenFeature([], tf.int64)    # for one int
tf
.io.FixedLenFeature([], tf.float32)  # for one float

고정된 크기의 요소 목록 읽기

tf.io.FixedLenFeature([N], tf.string)   # list of N byte strings
tf.io.FixedLenFeature([N], tf.int64)    # list of N ints
tf.io.FixedLenFeature([N], tf.float32)  # list of N floats

가변적인 수의 데이터 항목 읽기

tf.io.VarLenFeature(tf.string)   # list of byte strings
tf
.io.VarLenFeature(tf.int64)    # list of ints
tf
.io.VarLenFeature(tf.float32)  # list of floats

VarLenFeature는 희소 벡터를 반환하며, TFRecord를 디코딩한 후 추가 단계가 필요합니다.

dense_data = tf.sparse.to_dense(tf_record['my_var_len_feature'])

TFRecord에 선택사항 필드가 있을 수도 있습니다. 필드를 읽을 때 기본값을 지정하면 필드가 누락되었을 때 오류 대신 기본값이 반환됩니다.

tf.io.FixedLenFeature([], tf.int64, default_value=0) # this field is optional

학습한 내용

  • 🤔 GCS에서 빠르게 액세스하기 위한 데이터 파일 샤딩
  • 🔐 TFRecord를 작성하는 방법 문법을 잊어버리셨나요? 괜찮습니다. 이 페이지를 요약본으로 북마크에 추가하세요.)
  • 🤔 TFRecordDataset를 사용하여 TFRecords에서 데이터 세트 로드

잠시 시간을 내어 이 체크리스트를 머릿속에 살펴보세요.

6. 축하합니다.

이제 TPU에 데이터를 피드할 수 있습니다. 다음 실습을 계속 진행하세요.

TPU의 실제 사용 사례

TPU 및 GPU는 Cloud AI Platform에서 사용할 수 있습니다.

마지막으로, YouTube는 고객의 의견을 소중하게 생각합니다. 이 실습에서 부족한 부분이 있거나 개선이 필요하다고 생각되는 부분이 있으면 알려 주세요. 의견은 GitHub 문제[의견 링크]를 통해 제공할 수 있습니다.

HR.png

마틴 괴르너 ID small.jpg
작성자: 마틴 괴르너
트위터: @martin_gorner