1. Tổng quan
TPU có tốc độ rất cao. Luồng dữ liệu huấn luyện phải theo kịp tốc độ huấn luyện. Trong phòng thí nghiệm này, bạn sẽ tìm hiểu cách tải dữ liệu từ GCS bằng API tf.data.Dataset để cung cấp cho TPU.
Lớp học này là Phần 1 của loạt bài "Keras trên TPU". Bạn có thể thực hiện các bước này theo thứ tự sau hoặc thực hiện độc lập.
- [LỚP HỌC NÀY] Quy trình truyền dữ liệu tốc độ TPU: tf.data.Dataset và TFRecords
- Mô hình Keras đầu tiên của bạn, có tính năng học chuyển giao
- Mạng nơron tích chập, với Keras và TPU
- Mạng nơ-ron tích chập hiện đại, squeezenet, Xception, với Keras và TPU

Kiến thức bạn sẽ học được
- Cách sử dụng API tf.data.Dataset để tải dữ liệu huấn luyện
- Sử dụng định dạng TFRecord để tải dữ liệu huấn luyện một cách hiệu quả từ GCS
Phản hồi
Nếu bạn thấy có vấn đề trong lớp học lập trình này, vui lòng cho chúng tôi biết. Bạn có thể gửi ý kiến phản hồi thông qua các vấn đề trên GitHub [ đường liên kết phản hồi].
2. Hướng dẫn bắt đầu nhanh về Google Colaboratory
Phòng thí nghiệm này sử dụng Google Colaboratory và bạn không cần thiết lập gì. Colaboratory là một nền tảng sổ tay trực tuyến dành cho mục đích giáo dục. Nền tảng này cung cấp các khoá đào tạo miễn phí về CPU, GPU và TPU.

Bạn có thể mở sổ tay mẫu này và chạy qua một vài ô để làm quen với Colaboratory.
Chọn một phần phụ trợ TPU

Trong trình đơn Colab, hãy chọn Thời gian chạy > Thay đổi loại thời gian chạy rồi chọn TPU. Trong lớp học lập trình này, bạn sẽ sử dụng một TPU (Tensor Processing Unit) mạnh mẽ được hỗ trợ để huấn luyện có tăng tốc phần cứng. Quá trình kết nối với thời gian chạy sẽ diễn ra tự động trong lần thực thi đầu tiên hoặc bạn có thể sử dụng nút "Kết nối" ở góc trên bên phải.
Thực thi sổ tay

Thực thi từng ô bằng cách nhấp vào một ô và sử dụng tổ hợp phím Shift-ENTER. Bạn cũng có thể chạy toàn bộ sổ tay bằng cách chọn Thời gian chạy > Chạy tất cả
Mục lục

Tất cả sổ tay đều có mục lục. Bạn có thể mở trình đơn này bằng cách nhấn vào mũi tên màu đen ở bên trái.
Các ô bị ẩn

Một số ô sẽ chỉ hiển thị tiêu đề. Đây là một tính năng sổ tay dành riêng cho Colab. Bạn có thể nhấp đúp vào các tệp này để xem mã bên trong, nhưng thường thì mã này không có gì thú vị. Thường là các hàm hỗ trợ hoặc trực quan hoá. Bạn vẫn cần chạy các ô này để xác định các hàm bên trong.
Xác thực

Colab có thể truy cập vào các bộ chứa riêng tư của bạn trên Google Cloud Storage, miễn là bạn xác thực bằng một tài khoản được uỷ quyền. Đoạn mã ở trên sẽ kích hoạt một quy trình xác thực.
3. [THÔNG TIN] Tensor Processing Unit (TPU) là gì?
Tóm lại

Mã để huấn luyện một mô hình trên TPU trong Keras (và quay lại GPU hoặc CPU nếu không có TPU):
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=...)
Hôm nay, chúng ta sẽ sử dụng TPU để xây dựng và tối ưu hoá một trình phân loại hoa ở tốc độ tương tác (vài phút cho mỗi lần chạy huấn luyện).

Tại sao nên dùng TPU?
GPU hiện đại được sắp xếp xung quanh các "lõi" có thể lập trình, một kiến trúc rất linh hoạt cho phép chúng xử lý nhiều tác vụ như kết xuất 3D, học sâu, mô phỏng vật lý, v.v. Mặt khác, TPU kết hợp bộ xử lý vectơ cổ điển với một đơn vị nhân ma trận chuyên dụng và vượt trội ở mọi tác vụ mà phép nhân ma trận lớn chiếm ưu thế, chẳng hạn như mạng nơ-ron.

Minh hoạ: một lớp mạng nơron dày đặc dưới dạng phép nhân ma trận, với một lô gồm 8 hình ảnh được xử lý cùng lúc thông qua mạng nơron. Vui lòng chạy phép nhân một hàng x một cột để xác minh rằng phép nhân này thực sự đang tính tổng có trọng số của tất cả các giá trị pixel của một hình ảnh. Các lớp tích chập cũng có thể được biểu thị dưới dạng phép nhân ma trận mặc dù phức tạp hơn một chút ( giải thích tại đây, trong phần 1).
Phần cứng
MXU và VPU
Một lõi TPU phiên bản 2 được tạo thành từ một Đơn vị nhân ma trận (MXU) chạy các phép nhân ma trận và một Đơn vị xử lý vectơ (VPU) cho tất cả các tác vụ khác như kích hoạt, softmax, v.v. VPU xử lý các phép tính float32 và int32. Mặt khác, MXU hoạt động ở định dạng dấu phẩy động 16-32 bit có độ chính xác hỗn hợp.

Dấu phẩy động có độ chính xác hỗn hợp và bfloat16
MXU tính toán phép nhân ma trận bằng cách sử dụng đầu vào bfloat16 và đầu ra float32. Các phép tích luỹ trung gian được thực hiện với độ chính xác float32.

Quá trình huấn luyện mạng nơ-ron thường có khả năng chống lại nhiễu do độ chính xác của số thực dấu phẩy động bị giảm. Có những trường hợp nhiễu thậm chí còn giúp trình tối ưu hoá hội tụ. Độ chính xác của dấu phẩy động 16 bit thường được dùng để tăng tốc các phép tính, nhưng định dạng float16 và float32 có phạm vi rất khác nhau. Việc giảm độ chính xác từ float32 xuống float16 thường dẫn đến tình trạng tràn số và thiếu số. Có các giải pháp nhưng thường cần thêm công việc để float16 hoạt động.
Đó là lý do Google giới thiệu định dạng bfloat16 trong TPU. bfloat16 là một float32 bị cắt ngắn với chính xác các bit và dải số mũ như float32. Điều này, cộng với việc TPU tính toán các phép nhân ma trận với độ chính xác hỗn hợp bằng đầu vào bfloat16 nhưng đầu ra float32, có nghĩa là thông thường, bạn không cần thay đổi mã để hưởng lợi từ hiệu suất tăng lên do độ chính xác giảm.
Mảng tâm thu
MXU triển khai các phép nhân ma trận trong phần cứng bằng cách sử dụng cái gọi là cấu trúc "mảng tâm thu", trong đó các phần tử dữ liệu truyền qua một mảng các đơn vị tính toán phần cứng. (Trong y học, "tâm thu" đề cập đến sự co bóp của tim và lưu lượng máu, ở đây là lưu lượng dữ liệu.)
Phần tử cơ bản của phép nhân ma trận là tích vô hướng giữa một hàng của ma trận này và một cột của ma trận kia (xem hình minh hoạ ở đầu phần này). Đối với phép nhân ma trận Y=X*W, một phần tử của kết quả sẽ là:
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]
Trên GPU, người ta sẽ lập trình tích vô hướng này vào một "lõi" GPU, sau đó thực thi tích vô hướng này trên nhiều "lõi" nhất có thể song song để cố gắng tính toán mọi giá trị của ma trận kết quả cùng một lúc. Nếu ma trận kết quả có kích thước 128x128, thì cần có 128x128=16.000 "lõi" để có thể sử dụng. Điều này thường không thể thực hiện được. Các GPU lớn nhất có khoảng 4.000 lõi. Mặt khác, TPU sử dụng phần cứng tối thiểu cho các đơn vị tính toán trong MXU: chỉ có bfloat16 x bfloat16 => float32 bộ nhân tích luỹ, không có gì khác. Các đơn vị này nhỏ đến mức một TPU có thể triển khai 16.000 đơn vị trong một MXU 128x128 và xử lý phép nhân ma trận này trong một lần.

Hình minh hoạ: mảng tâm thu MXU. Các phần tử điện toán là bộ nhân tích luỹ. Các giá trị của một ma trận được tải vào mảng (các dấu chấm màu đỏ). Các giá trị của ma trận khác sẽ chảy qua mảng (các dấu chấm màu xám). Các đường thẳng đứng truyền các giá trị lên trên. Các đường ngang sẽ truyền tổng phụ. Người dùng cần tự xác minh rằng khi dữ liệu truyền qua mảng, bạn sẽ nhận được kết quả của phép nhân ma trận ở phía bên phải.
Ngoài ra, trong khi các tích vô hướng đang được tính toán trong MXU, các tổng trung gian chỉ cần chuyển giữa các đơn vị tính toán liền kề. Chúng không cần được lưu trữ và truy xuất đến/từ bộ nhớ hoặc thậm chí là một tệp đăng ký. Kết quả cuối cùng là kiến trúc mảng tâm thu TPU có mật độ và công suất đáng kể, cũng như tốc độ không đáng kể so với GPU khi tính toán phép nhân ma trận.
Cloud TPU
Khi yêu cầu một "Cloud TPU phiên bản 2" trên Google Cloud Platform, bạn sẽ nhận được một máy ảo (VM) có bảng TPU được gắn PCI. Bảng TPU có 4 chip TPU lõi kép. Mỗi lõi TPU đều có một VPU (Vector Processing Unit) và một MXU (MatriX multiply Unit) 128x128. Sau đó, "Cloud TPU" này thường được kết nối thông qua mạng với VM đã yêu cầu. Vì vậy, toàn bộ quy trình sẽ có dạng như sau:

Hình minh hoạ: máy ảo của bạn có một trình tăng tốc "Cloud TPU" được gắn vào mạng. "Cloud TPU" được tạo thành từ một máy ảo có bảng TPU được gắn PCI với 4 chip TPU lõi kép trên đó.
Nhóm TPU
Trong các trung tâm dữ liệu của Google, TPU được kết nối với một hệ thống kết nối điện toán hiệu năng cao (HPC) có thể khiến chúng xuất hiện dưới dạng một bộ tăng tốc rất lớn. Google gọi chúng là các nhóm và chúng có thể bao gồm tối đa 512 lõi TPU phiên bản 2 hoặc 2048 lõi TPU phiên bản 3.

Hình minh hoạ: một nhóm TPU phiên bản 3. Các bảng và giá đỡ TPU được kết nối thông qua HPC interconnect.
Trong quá trình huấn luyện, các độ dốc được trao đổi giữa các lõi TPU bằng cách sử dụng thuật toán giảm tất cả ( giải thích rõ ràng về thuật toán giảm tất cả tại đây). Mô hình đang được huấn luyện có thể tận dụng phần cứng bằng cách huấn luyện trên các kích thước lô lớn.

Hình minh hoạ: quá trình đồng bộ hoá các độ dốc trong quá trình huấn luyện bằng thuật toán giảm tất cả trên mạng HPC dạng lưới hình xuyến 2 chiều của TPU của Google.
Phần mềm
Huấn luyện kích thước lô lớn
Kích thước lô lý tưởng cho TPU là 128 mục dữ liệu trên mỗi lõi TPU, nhưng phần cứng đã có thể cho thấy mức sử dụng tốt từ 8 mục dữ liệu trên mỗi lõi TPU. Hãy nhớ rằng một Cloud TPU có 8 lõi.
Trong lớp học lập trình này, chúng ta sẽ sử dụng API Keras. Trong Keras, lô mà bạn chỉ định là kích thước lô chung cho toàn bộ TPU. Các lô của bạn sẽ tự động được chia thành 8 lô và chạy trên 8 lõi của TPU.

Để biết thêm các mẹo về hiệu suất, hãy xem Hướng dẫn về hiệu suất TPU. Đối với các kích thước lô rất lớn, bạn có thể cần phải đặc biệt chú ý đến một số mô hình, hãy xem LARSOptimizer để biết thêm thông tin chi tiết.
Tìm hiểu sâu: XLA
Các chương trình Tensorflow xác định đồ thị tính toán. TPU không chạy trực tiếp mã Python mà chạy biểu đồ tính toán do chương trình Tensorflow của bạn xác định. Về cơ bản, một trình biên dịch có tên là XLA (trình biên dịch Đại số tuyến tính được tăng tốc) sẽ chuyển đổi biểu đồ Tensorflow của các nút tính toán thành mã máy TPU. Trình biên dịch này cũng thực hiện nhiều hoạt động tối ưu hoá nâng cao trên mã và bố cục bộ nhớ của bạn. Quá trình biên dịch sẽ diễn ra tự động khi công việc được gửi đến TPU. Bạn không cần phải đưa XLA vào chuỗi bản dựng một cách rõ ràng.

Minh hoạ: để chạy trên TPU, biểu đồ tính toán do chương trình Tensorflow của bạn xác định trước tiên sẽ được dịch sang biểu diễn XLA (trình biên dịch Đại số tuyến tính được tăng tốc), sau đó được XLA biên dịch thành mã máy TPU.
Sử dụng TPU trong Keras
TPU được hỗ trợ thông qua API Keras kể từ Tensorflow 2.1. Tính năng hỗ trợ Keras hoạt động trên TPU và nhóm TPU. Sau đây là một ví dụ hoạt động trên TPU, (các) GPU và 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=...)
Trong đoạn mã này:
TPUClusterResolver().connect()tìm thấy TPU trên mạng. Công cụ này hoạt động mà không cần tham số trên hầu hết các hệ thống của Google Cloud (các công việc trên Nền tảng Trí tuệ nhân tạo, Colaboratory, VM học sâu được tạo thông qua tiện ích "ctpu up"). Các hệ thống này biết vị trí của TPU nhờ biến môi trường TPU_NAME. Nếu bạn tạo TPU theo cách thủ công, hãy đặt biến môi trường TPU_NAME trên VM mà bạn đang sử dụng hoặc gọiTPUClusterResolverbằng các tham số rõ ràng:TPUClusterResolver(tp_uname, zone, project)TPUStrategylà phần triển khai thuật toán đồng bộ hoá độ dốc "giảm tất cả" và phân phối.- Chiến lược này được áp dụng thông qua một phạm vi. Mô hình phải được xác định trong phạm vi chiến lược().
- Hàm
tpu_model.fitdự kiến sẽ có một đối tượng tf.data.Dataset để làm dữ liệu đầu vào cho quá trình huấn luyện TPU.
Các thao tác di chuyển TPU thường gặp
- Mặc dù có nhiều cách để tải dữ liệu trong mô hình Tensorflow, nhưng đối với TPU, bạn phải sử dụng API
tf.data.Dataset. - TPU có tốc độ rất cao và việc nhập dữ liệu thường trở thành điểm tắc nghẽn khi chạy trên các TPU này. Bạn có thể sử dụng các công cụ để phát hiện điểm tắc nghẽn dữ liệu và các mẹo khác về hiệu suất trong Hướng dẫn về hiệu suất TPU.
- Các số int8 hoặc int16 được coi là int32. TPU không có phần cứng số nguyên hoạt động trên dưới 32 bit.
- Một số thao tác Tensorflow không được hỗ trợ. Danh sách có tại đây. Tin vui là hạn chế này chỉ áp dụng cho mã huấn luyện, tức là quá trình truyền xuôi và truyền ngược qua mô hình của bạn. Bạn vẫn có thể sử dụng tất cả các thao tác của Tensorflow trong quy trình nhập dữ liệu vì quy trình này sẽ được thực thi trên CPU.
tf.py_funckhông được hỗ trợ trên TPU.
4. Đang tải dữ liệu

Chúng ta sẽ làm việc với một tập dữ liệu gồm các bức ảnh về hoa. Mục tiêu là học cách phân loại chúng thành 5 loại hoa. Quá trình tải dữ liệu được thực hiện bằng API tf.data.Dataset. Trước tiên, hãy tìm hiểu về API này.
Thực hành
Vui lòng mở sổ tay sau, thực thi các ô (Shift-ENTER) và làm theo hướng dẫn bất cứ khi nào bạn thấy nhãn "CẦN THỰC HIỆN".
Fun with tf.data.Dataset (playground).ipynb
Thông tin khác
Giới thiệu về tập dữ liệu "flowers"
Tập dữ liệu được sắp xếp thành 5 thư mục. Mỗi thư mục chứa một loại hoa. Các thư mục có tên là hoa hướng dương, hoa cúc, hoa bồ công anh, hoa tulip và hoa hồng. Dữ liệu được lưu trữ trong một bộ chứa công khai trên Google Cloud Storage. Đoạn trích:
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
Tại sao nên dùng tf.data.Dataset?
Keras và TensorFlow chấp nhận các Tập dữ liệu trong tất cả các hàm huấn luyện và đánh giá. Sau khi bạn tải dữ liệu vào một Tập dữ liệu, API sẽ cung cấp tất cả các chức năng phổ biến hữu ích cho dữ liệu huấn luyện mạng nơ-ron:
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
Bạn có thể xem các mẹo về hiệu suất và các phương pháp hay nhất về Tập dữ liệu trong bài viết này. Bạn có thể xem tài liệu tham khảo tại đây.
Kiến thức cơ bản về tf.data.Dataset
Dữ liệu thường có trong nhiều tệp, ở đây là hình ảnh. Bạn có thể tạo một tập dữ liệu gồm các tên tệp bằng cách gọi:
filenames_dataset = tf.data.Dataset.list_files('gs://flowers-public/*/*.jpg')
# The parameter is a "glob" pattern that supports the * and ? wildcards.
Sau đó, bạn "ánh xạ" một hàm đến từng tên tệp. Hàm này thường sẽ tải và giải mã tệp thành dữ liệu thực tế trong bộ nhớ:
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)
Cách lặp lại trên một Tập dữ liệu:
for data in my_dataset:
print(data)
Tập dữ liệu của các bộ dữ liệu
Trong học có giám sát, một tập dữ liệu huấn luyện thường được tạo thành từ các cặp dữ liệu huấn luyện và câu trả lời chính xác. Để cho phép điều này, hàm giải mã có thể trả về các bộ giá trị. Sau đó, bạn sẽ có một tập dữ liệu gồm các bộ và các bộ sẽ được trả về khi bạn lặp lại trên tập dữ liệu đó. Các giá trị được trả về là các tensor Tensorflow đã sẵn sàng được mô hình của bạn sử dụng. Bạn có thể gọi .numpy() trên các giá trị này để xem giá trị thô:
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())
Kết luận:tải từng hình ảnh một rất chậm!
Khi lặp lại trên tập dữ liệu này, bạn sẽ thấy rằng bạn có thể tải khoảng 1-2 hình ảnh mỗi giây. Tốc độ đó quá chậm! Các bộ tăng tốc phần cứng mà chúng ta sẽ sử dụng để huấn luyện có thể duy trì tốc độ này nhiều lần. Hãy chuyển đến phần tiếp theo để xem cách chúng ta sẽ đạt được mục tiêu này.
Giải pháp
Sau đây là sổ tay giải pháp. Bạn có thể sử dụng mã này nếu gặp khó khăn.
Fun with tf.data.Dataset (solution).ipynb
Nội dung đã đề cập
- 🤔 tf.data.Dataset.list_files
- 🤔 tf.data.Dataset.map
- 🤔 Tập dữ liệu của các bộ
- 😀 lặp lại qua Tập dữ liệu
Vui lòng dành chút thời gian để xem qua danh sách kiểm tra này.
5. Tải dữ liệu nhanh
Các trình tăng tốc phần cứng Tensor Processing Unit (TPU) mà chúng ta sẽ sử dụng trong phòng thí nghiệm này có tốc độ rất cao. Thách thức thường gặp là cung cấp cho chúng dữ liệu đủ nhanh để chúng luôn bận rộn. Google Cloud Storage (GCS) có khả năng duy trì thông lượng rất cao, nhưng giống như mọi hệ thống lưu trữ đám mây, việc bắt đầu kết nối sẽ tốn một số thời gian qua lại trên mạng. Do đó, việc lưu trữ dữ liệu dưới dạng hàng nghìn tệp riêng lẻ không phải là cách lý tưởng. Chúng ta sẽ nhóm các tệp này thành một số lượng nhỏ hơn và sử dụng sức mạnh của tf.data.Dataset để đọc song song từ nhiều tệp.
Đọc qua
Mã tải tệp hình ảnh, đổi kích thước thành kích thước chung rồi lưu trữ trên 16 tệp TFRecord nằm trong sổ tay sau. Vui lòng đọc nhanh qua nội dung này. Bạn không cần thực thi thao tác này vì dữ liệu được định dạng TFRecord đúng cách sẽ được cung cấp cho phần còn lại của lớp học lập trình.
Flower pictures to TFRecords.ipynb
Bố cục dữ liệu lý tưởng để có được thông lượng GCS tối ưu
Định dạng tệp TFRecord
Định dạng tệp mà Tensorflow ưu tiên để lưu trữ dữ liệu là định dạng TFRecord dựa trên protobuf. Các định dạng chuyển đổi tuần tự khác cũng sẽ hoạt động, nhưng bạn có thể tải trực tiếp một tập dữ liệu từ các tệp TFRecord bằng cách viết:
filenames = tf.io.gfile.glob(FILENAME_PATTERN)
dataset = tf.data.TFRecordDataset(filenames)
dataset = dataset.map(...) # do the TFRecord decoding here - see below
Để có hiệu suất tối ưu, bạn nên sử dụng đoạn mã phức tạp hơn sau đây để đọc từ nhiều tệp TFRecord cùng một lúc. Mã này sẽ đọc từ N tệp song song và bỏ qua thứ tự dữ liệu để tăng tốc độ đọc.
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
Bản tóm tắt về TFRecord
Có 3 loại dữ liệu có thể được lưu trữ trong TFRecord: chuỗi byte (danh sách byte), số nguyên 64 bit và số thực 32 bit. Chúng luôn được lưu trữ dưới dạng danh sách, một phần tử dữ liệu duy nhất sẽ là danh sách có kích thước 1. Bạn có thể sử dụng các hàm trợ giúp sau để lưu trữ dữ liệu vào TFRecord.
writing byte strings
# 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))
viết số nguyên
def _int_feature(list_of_ints): # int64
return tf.train.Feature(int64_list=tf.train.Int64List(value=list_of_ints))
viết nổi
def _float_feature(list_of_floats): # float32
return tf.train.Feature(float_list=tf.train.FloatList(value=list_of_floats))
viết một TFRecord, sử dụng các trợ giúp ở trên
# 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())
Để đọc dữ liệu từ TFRecord, trước tiên, bạn phải khai báo bố cục của các bản ghi mà bạn đã lưu trữ. Trong khai báo, bạn có thể truy cập vào bất kỳ trường nào được đặt tên dưới dạng danh sách có độ dài cố định hoặc danh sách có độ dài thay đổi:
đọc từ 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)
Các đoạn mã hữu ích:
đọc các phần tử dữ liệu riêng lẻ
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
đọc danh sách các phần tử có kích thước cố định
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
đọc một số lượng biến của các mục dữ liệu
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 trả về một vectơ thưa và bạn cần thực hiện thêm một bước sau khi giải mã TFRecord:
dense_data = tf.sparse.to_dense(tf_record['my_var_len_feature'])
Bạn cũng có thể có các trường không bắt buộc trong TFRecord. Nếu bạn chỉ định một giá trị mặc định khi đọc một trường, thì giá trị mặc định sẽ được trả về thay vì lỗi nếu trường đó bị thiếu.
tf.io.FixedLenFeature([], tf.int64, default_value=0) # this field is optional
Nội dung đã đề cập
- 🤔 phân đoạn tệp dữ liệu để truy cập nhanh từ GCS
- 😓 cách viết TFRecord. (Bạn đã quên cú pháp rồi ư? Không sao cả, hãy đánh dấu trang này làm tài liệu tham khảo)
- 🤔 tải một Tập dữ liệu từ TFRecords bằng TFRecordDataset
Vui lòng dành chút thời gian để xem qua danh sách kiểm tra này.
6. Xin chúc mừng!
Giờ đây, bạn có thể cung cấp dữ liệu cho TPU. Vui lòng tiếp tục thực hiện bài thực hành tiếp theo
- [LỚP HỌC NÀY] Quy trình truyền dữ liệu tốc độ TPU: tf.data.Dataset và TFRecords
- Mô hình Keras đầu tiên của bạn, có tính năng học chuyển giao
- Mạng nơron tích chập, với Keras và TPU
- Mạng nơ-ron tích chập hiện đại, squeezenet, Xception, với Keras và TPU
TPU trong thực tế
TPU và GPU có trên Cloud AI Platform:
- Trên Deep Learning VM
- Trong AI Platform Notebooks
- Trong các công việc AI Platform Training
Cuối cùng, chúng tôi rất mong nhận được ý kiến phản hồi. Vui lòng cho chúng tôi biết nếu bạn thấy có điều gì sai sót trong phòng thí nghiệm này hoặc nếu bạn nghĩ rằng chúng tôi nên cải thiện. Bạn có thể gửi ý kiến phản hồi thông qua các vấn đề trên GitHub [ đường liên kết phản hồi].

|
|

