ไปป์ไลน์ข้อมูลความเร็ว TPU: tf.data.Dataset และ TFRecords

1. ภาพรวม

TPU ทำงานได้เร็วมาก สตรีมข้อมูลการฝึกต้องยึดตามความเร็วในการฝึก ในห้องทดลองนี้ คุณจะได้ดูวิธีโหลดข้อมูลจาก GCS ด้วย tf.data.Dataset API เพื่อป้อน TPU

ห้องทดลองนี้เป็นส่วนที่ 1 ของซีรีส์ "Keras บน TPU" คุณสามารถดำเนินการตามลำดับต่อไปนี้หรือทำแยกต่างหากก็ได้

ca8cc21f6838eccc.png

สิ่งที่คุณจะได้เรียนรู้

  • วิธีใช้ tf.data.Dataset API เพื่อโหลดข้อมูลการฝึก
  • เพื่อใช้รูปแบบ TFRecord เพื่อโหลดข้อมูลการฝึกอย่างมีประสิทธิภาพจาก GCS

ความคิดเห็น

หากพบสิ่งผิดปกติในแท็บทดลองใช้โค้ดนี้ โปรดแจ้งให้เราทราบ คุณสามารถแสดงความคิดเห็นผ่านปัญหาใน GitHub [ลิงก์ความคิดเห็น]

2. คู่มือเริ่มต้นใช้งานฉบับย่อของ Google Colaboratory

ห้องทดลองนี้ใช้ Google Collaboratory และคุณไม่จำเป็นต้องตั้งค่าใดๆ Colaboratory เป็นแพลตฟอร์มโน้ตบุ๊กออนไลน์เพื่อการศึกษา โดยมีการอบรมเรื่อง CPU, GPU และ TPU ให้ฟรี

688858c21e3beff2.png

คุณเปิดสมุดบันทึกตัวอย่างนี้แล้ววิ่งผ่านเซลล์ 2-3 เซลล์เพื่อทำความคุ้นเคยกับ Colaboratory ได้

c3df49e90e5a654f.png Welcome to Colab.ipynb

เลือกแบ็กเอนด์ TPU

8832c6208c99687d.png

ในเมนู Colab ให้เลือกรันไทม์ > เปลี่ยนประเภทรันไทม์ แล้วเลือก TPU ในโปรแกรมแก้ไขโค้ดนี้ คุณจะใช้ TPU (Tensor Processing Unit) ที่มีประสิทธิภาพซึ่งรองรับการฝึกด้วยฮาร์ดแวร์ที่เร่งความเร็ว การเชื่อมต่อกับรันไทม์จะเกิดขึ้นโดยอัตโนมัติในการดำเนินการครั้งแรก หรือคุณจะใช้ปุ่ม "เชื่อมต่อ" ที่มุมบนขวาก็ได้

การดำเนินการกับสมุดบันทึก

76d05caa8b4db6da.png

เรียกใช้ทีละเซลล์ด้วยการคลิกที่เซลล์แล้วกด Shift-ENTER นอกจากนี้ คุณยังเรียกใช้ทั้งสมุดบันทึกได้ด้วยรันไทม์ > เรียกใช้ทั้งหมด

สารบัญ

429f106990037ec4.png

สมุดบันทึกทั้งหมดมีสารบัญ คุณสามารถเปิดได้โดยใช้ลูกศรสีดำทางด้านซ้าย

เซลล์ที่ซ่อนอยู่

edc3dba45d26f12a.png

บางเซลล์จะแสดงเฉพาะชื่อ ฟีเจอร์นี้เป็นฟีเจอร์สำหรับสมุดบันทึกของ Colab โดยเฉพาะ คุณสามารถดับเบิลคลิกเพื่อดูโค้ดภายในได้ แต่โดยปกติแล้วโค้ดดังกล่าวไม่น่าตื่นเต้นมากนัก โดยทั่วไปจะรองรับหรือฟังก์ชันการแสดงผล คุณยังต้องเรียกใช้เซลล์เหล่านี้เพื่อให้มีการกำหนดฟังก์ชันภายในเซลล์

การตรวจสอบสิทธิ์

cdd4b41413100543.png

Colab สามารถเข้าถึงที่เก็บข้อมูล Google Cloud Storage ส่วนตัวได้หากคุณตรวจสอบสิทธิ์ด้วยบัญชีที่ได้รับอนุญาต ข้อมูลโค้ดด้านบนจะทริกเกอร์กระบวนการตรวจสอบสิทธิ์

3. [INFO] Tensor Processing Unit (TPU) คืออะไร

สรุป

f88cf6facfc70166.png

โค้ดสำหรับการฝึกโมเดลบน TPU ใน Keras (และกลับไปใช้ GPU หรือ CPU หากไม่มี 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=...)

เราจะใช้ TPU ในวันนี้เพื่อสร้างและเพิ่มประสิทธิภาพตัวแยกประเภทดอกไม้ด้วยความเร็วแบบอินเทอร์แอกทีฟ (นาทีต่อการฝึกแต่ละครั้ง)

688858c21e3beff2.png

ทำไมต้องใช้ TPU

GPU สมัยใหม่จะจัดระเบียบตาม "แกน" ที่ตั้งโปรแกรมได้ ซึ่งเป็นสถาปัตยกรรมที่มีความยืดหยุ่นสูงซึ่งช่วยให้สามารถจัดการงานต่างๆ ได้ เช่น การแสดงผล 3 มิติ การเรียนรู้เชิงลึก การจำลองทางกายภาพ ฯลฯ อีกฝั่งหนึ่งจะเป็น TPU ที่จะจับคู่กับหน่วยประมวลผลเวกเตอร์แบบคลาสสิกกับหน่วยการคูณเมทริกซ์โดยเฉพาะ และทำได้อย่างดีเยี่ยมในทุกๆ งานที่มีการใช้การคูณเมทริกซ์ขนาดใหญ่ เช่น โครงข่ายระบบประสาทเทียม

8eb3e718b8e2ed08.png

ภาพประกอบ: ชั้นโครงข่ายระบบประสาทเทียมแบบคูณเมทริกซ์ โดยมีรูปภาพ 8 รูปประมวลผลผ่านโครงข่ายประสาทพร้อมกัน โปรดทำการคูณคอลัมน์ 1 บรรทัด x เพื่อยืนยันว่าเป็นการทำผลรวมแบบถ่วงน้ำหนักของค่าพิกเซลทั้งหมดของรูปภาพ เลเยอร์คอนโวลูชัน (Convolution) อาจแสดงเป็นการคูณเมทริกซ์ได้ด้วย แม้ว่าจะซับซ้อนกว่าเล็กน้อย ( มีคำอธิบายในส่วนที่ 1)

ฮาร์ดแวร์

MXU และ VPU

แกน TPU v2 สร้างขึ้นจาก Matrix Multiply Unit (MXU) ซึ่งเรียกใช้การคูณเมทริกซ์ และ Vectorประมวลผลข้อมูล Unit (VPU) สำหรับงานอื่นๆ ทั้งหมด เช่น การเปิดใช้งาน, softmax เป็นต้น VPU จะจัดการการคำนวณ Float 32 และ int32 ส่วน MXU จะทำงานในรูปแบบจุดลอยตัว 16-32 บิตที่มีความแม่นยำแบบผสม

7d68944718f76b18.png

จุดทศนิยมแบบผสมและ bfloat16

MXU จะคำนวณการคูณเมทริกซ์โดยใช้อินพุต bfloat16 และเอาต์พุต Float32 การเก็บสะสมขั้นกลางจะเกิดขึ้นด้วยความแม่นยำ Float 32

19c5fc432840c714.png

โดยทั่วไปการฝึกโครงข่ายระบบประสาทเทียมจะต้านเสียงที่เกิดจากความแม่นยำของจุดลอยตัวที่ลดลง แต่ก็มีบางกรณีที่เสียงรบกวนช่วยให้เครื่องมือเพิ่มประสิทธิภาพเชื่อมต่อกันได้ เดิมทีมีการใช้ความแม่นยำของจุดลอยตัว 16 บิตเพื่อเร่งการคำนวณ แต่รูปแบบ Float 16 และ Float 32 มีช่วงที่ต่างกันมาก การลดความแม่นยำจาก Float32 เป็น Float 16 มักจะทำให้เกิดการไหลเกินหรือต่ำกว่าที่ควรจะเป็น ปัญหานี้แก้ไขได้ แต่โดยทั่วไปแล้วจะต้องดำเนินการเพิ่มเติมเพื่อให้ float16 ทำงานได้

นั่นคือเหตุผลที่ Google เปิดตัวรูปแบบ bFlo 16 ใน TPU โดย bfloat16 เป็น Float 32 ที่ตัดให้สั้นลงโดยมีช่วงและบิตเลขชี้กำลังเหมือนกับ Float 32 นอกจากข้อเท็จจริงที่ว่า TPU จะคํานวณการคูณเมทริกซ์ด้วยความแม่นยำแบบผสมกับอินพุต bFloat16 แต่เอาต์พุต Float 32 หมายความว่าโดยทั่วไปแล้วไม่จําเป็นต้องเปลี่ยนแปลงโค้ดเพื่อให้ได้รับประโยชน์จากประสิทธิภาพที่เพิ่มขึ้นจากความแม่นยำที่ลดลง

อาร์เรย์ Systolic

MXU ใช้การคูณเมทริกซ์ในฮาร์ดแวร์โดยใช้สถาปัตยกรรมที่เรียกว่า "อาร์เรย์ Systolic" ซึ่งองค์ประกอบข้อมูลจะไหลผ่านอาร์เรย์ของหน่วยการประมวลผลฮาร์ดแวร์ (ในทางการแพทย์ "ซิสโตลิค" หมายถึงการหดตัวของหัวใจและการไหลเวียนของเลือด ในที่นี้หมายถึงการไหลเวียนของข้อมูล)

องค์ประกอบพื้นฐานของการคูณเมทริกซ์คือผลคูณจุดระหว่างแถวจากเมทริกซ์หนึ่งกับคอลัมน์จากเมทริกซ์อีกเมทริกซ์หนึ่ง (ดูภาพประกอบที่ด้านบนของส่วนนี้) สําหรับการคูณเมทริกซ์ 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=16,000 ซึ่งโดยทั่วไปแล้วไม่สามารถทำได้ โดย GPU ที่ใหญ่ที่สุดจะมีแกนประมาณ 4,000 แกน ในทางกลับกัน TPU ใช้ฮาร์ดแวร์ขั้นต่ำสำหรับหน่วยประมวลผลใน MXU ซึ่งก็คือตัวคูณสะสม bfloat16 x bfloat16 => float32 เท่านั้น หน่วยเหล่านี้มีขนาดเล็กมากจน TPU ติดตั้งใช้งานได้ 16,000 ตัวใน MXU ขนาด 128x128 และประมวลผลการดำเนินการคูณเมทริกซ์นี้พร้อมกันได้

f1b283fc45966717.gif

ภาพประกอบ: อาร์เรย์ความดันซิสโตลิกของ MXU องค์ประกอบการประมวลผลคือตัวสะสมแบบคูณ ระบบจะโหลดค่าของเมทริกซ์ 1 รายการเข้าไปในอาร์เรย์ (จุดสีแดง) ค่าของเมทริกซ์อื่นๆ จะไหลผ่านอาร์เรย์ (จุดสีเทา) เส้นแนวตั้งจะแสดงค่าขึ้น เส้นแนวนอนจะแสดงผลรวมของบางส่วน จึงทิ้งไว้เป็นแบบฝึกหัดสำหรับผู้ใช้เพื่อยืนยันว่าขณะที่ข้อมูลไหลผ่านอาร์เรย์ คุณจะได้ผลลัพธ์ของการคูณเมทริกซ์จากด้านขวา

นอกจากนี้ ขณะที่ระบบคำนวณผลิตภัณฑ์แบบจุดใน MXU ผลรวมที่เป็นกลางจะไหลไปมาระหว่างหน่วยประมวลผลที่อยู่ติดกัน คุณไม่จำเป็นต้องเก็บและเรียกข้อมูลไปยัง/จากหน่วยความจำ หรือแม้แต่ไฟล์การลงทะเบียน ผลลัพธ์ที่ได้คือสถาปัตยกรรมอาร์เรย์แบบซิสโตลิคของ TPU มีความหนาแน่นและประโยชน์ด้านพลังงานที่สำคัญ รวมถึงให้ความเร็วที่ไม่สำคัญเมื่อเทียบกับ GPU เมื่อคำนวณการคูณเมทริกซ์

Cloud TPU

เมื่อขอ "Cloud TPU v2" 1 เครื่องใน Google Cloud Platform คุณจะได้รับเครื่องเสมือน (VM) ที่มีบอร์ด TPU ที่ต่อกับ PCI บอร์ด TPU มีชิป TPU แบบ Dual-Core 4 ชิป แต่ละแกน TPU มี VPU (หน่วยประมวลผลเวกเตอร์) และ MXU (หน่วยการคูณเมทริกซ์) ขนาด 128x128 จากนั้น "Cloud TPU" นี้จะเชื่อมต่อผ่านเครือข่ายกับ VM ที่ส่งคำขอ ภาพรวมทั้งหมดจะมีลักษณะดังนี้

dfce5522ed644ece.png

ภาพประกอบ: VM ที่มีตัวเร่ง "Cloud TPU" ที่เชื่อมต่อเครือข่าย "Cloud TPU" เองสร้างจาก VM ที่มีบอร์ด TPU ประกอบ PCI ซึ่งมีชิป TPU แบบ Dual Core 4 ชิปอยู่

พ็อด TPU

ในศูนย์ข้อมูลของ Google นั้น TPU จะเชื่อมต่อกับการเชื่อมต่อระหว่างการประมวลผลประสิทธิภาพสูง (HPC) ซึ่งทำให้ปรากฏเป็น Accelerator ขนาดใหญ่มากตัวเดียว Google เรียกอุปกรณ์นี้ว่าพ็อดและรวมแกน TPU v2 ได้สูงสุด 512 แกน หรือแกน TPU v3 2048 แกน

2ec1e0d341e7fc34.jpeg

ภาพประกอบ: พ็อด TPU v3 บอร์ดและชั้นวาง TPU เชื่อมต่อกันผ่านการเชื่อมต่อถึงกัน HPC

ในระหว่างการฝึก ระบบจะแลกเปลี่ยนการไล่ระดับสีระหว่างแกน TPU โดยใช้อัลกอริทึม All-reduce ( คำอธิบายที่ดีของ all-reduce ที่นี่) โมเดลที่กำลังฝึกจะใช้ประโยชน์จากฮาร์ดแวร์ได้ด้วยการฝึกในแบบกลุ่มขนาดใหญ่

d97b9cc5d40fdb1d.gif

ภาพประกอบ: การซิงค์ของ Gradient ระหว่างการฝึกโดยใช้อัลกอริทึม All-Reduce ในเครือข่าย HPC แบบกริดทรงกลม 2 มิติของ Google TPU

ซอฟต์แวร์

การฝึกอบรมกลุ่มขนาดใหญ่

ขนาดการประมวลผลกลุ่มที่เหมาะสมสําหรับ TPU คือรายการข้อมูล 128 รายการต่อแกน TPU แต่ฮาร์ดแวร์สามารถแสดงการใช้งานที่ดีจากรายการข้อมูล 8 รายการต่อแกน TPU อยู่แล้ว โปรดทราบว่า Cloud TPU 1 ตัวมี 8 คอร์

ในแล็บโค้ดนี้ เราจะใช้ Keras API ใน Keras แบทช์ที่คุณระบุคือขนาดกลุ่มทั่วโลกสำหรับ TPU ทั้งหมด แบทช์จะแยกเป็น 8 โดยอัตโนมัติและทำงานบน 8 แกนของ TPU

da534407825f01e3.png

สำหรับเคล็ดลับด้านประสิทธิภาพเพิ่มเติม โปรดดูคู่มือประสิทธิภาพ TPU สำหรับกลุ่มที่มีขนาดใหญ่มาก บางโมเดลอาจต้องใช้ความระมัดระวังเป็นพิเศษ โปรดดูรายละเอียดเพิ่มเติมใน LARSOptimizer

กลไกภายใน: XLA

โปรแกรม TensorFlow จะกำหนดกราฟการประมวลผล TPU ไม่ได้เรียกใช้โค้ด Python โดยตรง แต่จะเรียกใช้กราฟการคำนวณที่กำหนดโดยโปรแกรม Tensorflow คอมไพเลอร์ชื่อ XLA (คอมไพเลอร์คณิตศาสตร์เชิงเส้นแบบเร่ง) จะเปลี่ยนกราฟ Tensorflow ของโหนดการประมวลผลเป็นรหัสเครื่อง TPU คอมไพเลอร์นี้จะดำเนินการเพิ่มประสิทธิภาพขั้นสูงหลายอย่างกับโค้ดและเลย์เอาต์หน่วยความจำของคุณ การคอมไพล์จะเกิดขึ้นโดยอัตโนมัติเมื่อมีการส่งงานไปยัง TPU คุณไม่จำเป็นต้องใส่ XLA ไว้ในเชนบิลด์อย่างชัดเจน

edce61112cd57972.png

ภาพ: ในการเรียกใช้บน TPU กราฟการคำนวณที่กำหนดโดยโปรแกรม Tensorflow จะได้รับการแปลเป็นการนำเสนอแบบ XLA (Accelerated Linear Algebra) ก่อน จากนั้นจึงคอมไพล์ด้วย XLA ลงในโค้ดเครื่อง TPU

การใช้ TPU ใน Keras

TPU ได้รับการสนับสนุนผ่าน Keras API ใน Tensorflow 2.1 การรองรับ 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, VM ของ Deep Learning ที่สร้างผ่านยูทิลิตี "ctpu up") ระบบเหล่านี้จะทราบว่า TPU ของตนอยู่ที่ใดด้วยตัวแปรสภาพแวดล้อม TPU_NAME หากคุณสร้าง TPU ด้วยตนเอง ให้ตั้งค่าตัวแปรสภาพแวดล้อม TPU_NAME ใน VM ที่ใช้อยู่ หรือเรียกใช้ TPUClusterResolver ด้วยพารามิเตอร์ที่ชัดเจน TPUClusterResolver(tp_uname, zone, project)
  • TPUStrategy คือส่วนที่ใช้การกระจายและอัลกอริทึมการซิงค์แบบไล่ระดับสี "all-reduce"
  • นำกลยุทธ์ไปใช้ผ่านขอบเขต ต้องกำหนดโมเดลภายในขอบเขตกลยุทธ์()
  • ฟังก์ชัน tpu_model.fit ต้องการออบเจ็กต์ tf.data.Dataset สำหรับอินพุตการฝึก TPU

งานการย้าย TPU ทั่วไป

  • แม้ว่าการโหลดข้อมูลในรูปแบบ Tensorflow จะมีหลายวิธี แต่สำหรับ TPU จำเป็นต้องมีการใช้ API ของ tf.data.Dataset
  • 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)

ชุดข้อมูลของ Tuples

ในการเรียนรู้แบบควบคุม โดยทั่วไปชุดข้อมูลการฝึกจะประกอบด้วยคู่ข้อมูลการฝึกและคำตอบที่ถูกต้อง ฟังก์ชันการถอดรหัสจึงต้องแสดงผลทูเพล็ตเพื่อให้อนุญาตการดำเนินการนี้ จากนั้นคุณจะมีชุดข้อมูลของ Tuples และ Tuples จะส่งคืนเมื่อคุณทำซ้ำ ค่าที่แสดงผลคือ Tensor ของ 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
  • 🤔 ชุดข้อมูลของ Tuples
  • 😀 เป็นการทำซ้ำผ่านชุดข้อมูล

โปรดใช้เวลาสักครู่เพื่อทบทวนรายการตรวจสอบนี้

5. โหลดข้อมูลได้อย่างรวดเร็ว

โปรแกรมเร่งความเร็วฮาร์ดแวร์ Tensor Processing Unit (TPU) ที่เราจะใช้ในห้องทดลองนี้ทำงานได้เร็วมาก ความท้าทายคือการให้ข้อมูลแก่นักเรียนให้เร็วพอที่จะทำให้นักเรียนไม่ว่าง Google Cloud Storage (GCS) สามารถรองรับปริมาณข้อมูลที่ส่งผ่านได้สูงมาก แต่เช่นเดียวกับระบบพื้นที่เก็บข้อมูลระบบคลาวด์ทั้งหมด การสร้างการเชื่อมต่อจะทำให้เกิดการส่งข้อมูลไปมาทางเครือข่าย ดังนั้น การเก็บข้อมูลของเราเป็นไฟล์เดี่ยวๆ หลายพันไฟล์จึงไม่ใช่วิธีที่เหมาะสม เราจะจัดกลุ่มไฟล์เป็นจํานวนน้อยลงและใช้ความสามารถของ tf.data.Dataset เพื่ออ่านจากหลายไฟล์พร้อมกัน

การอ่าน

โค้ดที่โหลดไฟล์ภาพ ปรับขนาดเป็นขนาดทั่วไป แล้วจัดเก็บไว้ในไฟล์ TFRecord 16 ไฟล์อยู่ในสมุดบันทึกต่อไปนี้ โปรดอ่านข้อมูลดังกล่าวอย่างรวดเร็ว คุณไม่จำเป็นต้องเรียกใช้ เนื่องจากจะมีการจัดเตรียมข้อมูลที่จัดรูปแบบเป็น TFRecord อย่างถูกต้องไว้ให้สำหรับโค้ดแล็บที่เหลือ

c3df49e90e5a654f.png Flower pictures to TFRecords.ipynb

เลย์เอาต์ข้อมูลที่เหมาะสำหรับอัตราการส่งข้อมูล GCS ที่เหมาะสมที่สุด

รูปแบบไฟล์ TFRecord

รูปแบบไฟล์ที่ Tensorflow ต้องการสำหรับการจัดเก็บข้อมูลคือรูปแบบ TFRecord ที่ใช้ Protobuf รูปแบบอนุกรมอื่นๆ ก็ใช้ได้เช่นกัน แต่คุณสามารถโหลดชุดข้อมูลจากไฟล์ 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

คุณจัดเก็บข้อมูลได้ 3 ประเภทใน 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 (คุณลืมไวยากรณ์แล้วหรือยัง ไม่มีปัญหา บุ๊กมาร์กหน้านี้เป็นข้อมูลสรุป)
  • 🤔 กำลังโหลดชุดข้อมูลจาก TFRecord โดยใช้ TFRecordDataset

โปรดสละเวลาสักครู่เพื่อทบทวนรายการตรวจสอบนี้ในใจ

6. ยินดีด้วย

ตอนนี้คุณสามารถป้อนข้อมูลให้กับ TPU ได้แล้ว โปรดไปยังห้องทดลองถัดไป

การใช้งาน TPU

TPU และ GPU พร้อมให้บริการใน Cloud AI Platform

สุดท้ายนี้ เรายินดีรับฟังความคิดเห็น โปรดแจ้งให้เราทราบ หากคุณพบสิ่งที่ควรปรับปรุงในห้องทดลองนี้ หรือคุณคิดว่าเราควรปรับปรุง คุณแสดงความคิดเห็นได้ผ่านปัญหาเกี่ยวกับ GitHub [ feedback link]

HR.png

Martin Görner ID large.jpg
ผู้เขียน: Martin Görner
Twitter: @martin_gorner