خطوط لوله داده با سرعت TPU: tf.data.Dataset و TFRecords

1. بررسی اجمالی

TPU ها بسیار سریع هستند. جریان داده های آموزشی باید با سرعت تمرین آنها مطابقت داشته باشد. در این آزمایشگاه، نحوه بارگیری داده ها از GCS با tf.data.Dataset API برای تغذیه TPU خود را یاد خواهید گرفت.

این آزمایشگاه قسمت 1 از سری "Keras on TPU" است. می توانید آنها را به ترتیب زیر یا به صورت مستقل انجام دهید.

ca8cc21f6838eccc.png

چیزی که یاد خواهید گرفت

  • برای استفاده از tf.data.Dataset API برای بارگیری داده های آموزشی
  • برای استفاده از فرمت TFRecord برای بارگذاری موثر داده های آموزشی از GCS

بازخورد

اگر در این آزمایشگاه کد مشکلی مشاهده کردید، لطفاً به ما بگویید. بازخورد را می توان از طریق مسائل GitHub [ لینک بازخورد ] ارائه کرد.

2. شروع سریع Google Collaboratory

این آزمایشگاه از Google Collaboratory استفاده می کند و نیازی به تنظیم از طرف شما ندارد. Colaboratory یک پلت فرم نوت بوک آنلاین برای اهداف آموزشی است. آموزش رایگان CPU، GPU و TPU را ارائه می دهد.

688858c21e3beff2.png

می‌توانید این نمونه دفترچه یادداشت را باز کنید و از چند سلول عبور کنید تا با Colaboratory آشنا شوید.

c3df49e90e5a654f.png Welcome to Colab.ipynb

یک باطن TPU را انتخاب کنید

8832c6208c99687d.png

در منوی Colab، Runtime > Change runtime type و سپس TPU را انتخاب کنید. در این آزمایشگاه کد از یک TPU (واحد پردازش تنسور) قدرتمند استفاده می‌کنید که برای آموزش سخت‌افزاری تسریع شده پشتیبانی می‌شود. اتصال به زمان اجرا به طور خودکار در اولین اجرا انجام می شود، یا می توانید از دکمه "اتصال" در گوشه سمت راست بالا استفاده کنید.

اجرای نوت بوک

76d05caa8b4db6da.png

با کلیک بر روی یک سلول و استفاده از Shift-ENTER سلول ها را یکی یکی اجرا کنید. همچنین می توانید کل نوت بوک را با Runtime > Run all اجرا کنید

فهرست مطالب

429f106990037ec4.png

همه نوت بوک ها دارای فهرست مطالب هستند. می توانید آن را با استفاده از فلش سیاه سمت چپ باز کنید.

سلول های پنهان

edc3dba45d26f12a.png

برخی از سلول ها فقط عنوان خود را نشان می دهند. این یک ویژگی نوت بوک مخصوص Colab است. می توانید روی آنها دوبار کلیک کنید تا کد داخل آن را ببینید اما معمولاً چندان جالب نیست. به طور معمول توابع پشتیبانی یا تجسم. هنوز باید این سلول ها را اجرا کنید تا توابع داخل آن تعریف شوند.

احراز هویت

cdd4b41413100543.png

این امکان برای Colab وجود دارد که به سطل‌های خصوصی Google Cloud Storage شما دسترسی داشته باشد، مشروط بر اینکه با یک حساب مجاز احراز هویت کنید. قطعه کد بالا یک فرآیند احراز هویت را راه اندازی می کند.

3. [INFO] واحدهای پردازش تانسور (TPU) چیست؟

به طور خلاصه

f88cf6facfc70166.png

کد آموزش مدل بر روی TPU در Keras (و در صورت در دسترس نبودن 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 ها؟

پردازنده‌های گرافیکی مدرن حول محورهای قابل برنامه‌ریزی سازماندهی شده‌اند، معماری بسیار انعطاف‌پذیری که به آن‌ها اجازه می‌دهد تا کارهای مختلفی مانند رندر سه بعدی، یادگیری عمیق، شبیه‌سازی فیزیکی و غیره را انجام دهند. واحد ضرب ماتریس و برتری در هر کاری که ضرب ماتریس بزرگ غالب است، مانند شبکه های عصبی.

8eb3e718b8e2ed08.png

تصویر: یک لایه شبکه عصبی متراکم به عنوان ضرب ماتریس، با دسته‌ای از هشت تصویر که در یک شبکه عصبی پردازش می‌شوند. لطفاً ضرب در یک خط x ستون را اجرا کنید تا بررسی کنید که واقعاً مجموع وزنی تمام مقادیر پیکسل های یک تصویر را انجام می دهد. لایه‌های کانولوشنال را می‌توان به صورت ضرب‌های ماتریسی نیز نشان داد، اگرچه کمی پیچیده‌تر است ( توضیح در اینجا، در بخش 1 ).

سخت افزار

MXU و VPU

یک هسته TPU v2 از یک واحد ضرب ماتریس (MXU) ساخته شده است که ضرب ماتریس را اجرا می کند و یک واحد پردازش برداری (VPU) برای همه کارهای دیگر مانند فعال سازی، سافت مکس و غیره. VPU محاسبات float32 و int32 را انجام می دهد. از سوی دیگر، MXU در فرمت ممیز شناور با دقت ترکیبی 16-32 بیتی کار می کند.

7d68944718f76b18.png

نقطه شناور دقیق مخلوط و bfloat16

MXU ضرب های ماتریس را با استفاده از ورودی های bfloat16 و خروجی های float32 محاسبه می کند. انباشته های میانی با دقت float32 انجام می شود.

19c5fc432840c714.png

آموزش شبکه عصبی معمولاً در برابر نویز ایجاد شده توسط کاهش دقت ممیز شناور مقاوم است. مواردی وجود دارد که نویز حتی به همگرایی بهینه ساز کمک می کند. دقت ممیز شناور 16 بیتی به طور سنتی برای سرعت بخشیدن به محاسبات استفاده می شود، اما فرمت های float16 و float32 محدوده های بسیار متفاوتی دارند. کاهش دقت از float32 به float16 معمولاً منجر به جریان بیش از حد و زیر جریان می شود. راه‌حل‌هایی وجود دارد، اما معمولاً برای کارکرد float16، کار اضافی لازم است.

به همین دلیل است که گوگل فرمت bfloat16 را در TPU ها معرفی کرد. 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 "هسته" نیاز دارد که معمولا امکان پذیر نیست. بزرگترین پردازنده های گرافیکی حدود 4000 هسته دارند. از طرف دیگر یک TPU از حداقل سخت افزار برای واحدهای محاسباتی در MXU استفاده می کند: فقط bfloat16 x bfloat16 => float32 multiply-accumulator، هیچ چیز دیگری. اینها آنقدر کوچک هستند که یک TPU می تواند 16 هزار عدد از آنها را در MXU 128x128 پیاده سازی کند و این ضرب ماتریس را در یک حرکت پردازش کند.

f1b283fc45966717.gif

تصویر: آرایه سیستولیک MXU. عناصر محاسباتی چند انباشته هستند. مقادیر یک ماتریس در آرایه بارگذاری می شوند (نقاط قرمز). مقادیر ماتریس دیگر از طریق آرایه جریان می یابد (نقاط خاکستری). خطوط عمودی مقادیر را به بالا منتشر می کنند. خطوط افقی مجموع جزئی را منتشر می کنند. به عنوان یک تمرین به کاربر سپرده می شود تا تأیید کند که با جریان داده در آرایه، نتیجه ضرب ماتریس از سمت راست را دریافت می کنید.

علاوه بر آن، در حالی که محصولات نقطه ای در یک MXU محاسبه می شوند، مبالغ میانی به سادگی بین واحدهای محاسباتی مجاور جریان می یابد. آنها نیازی به ذخیره و بازیابی در/از حافظه یا حتی یک فایل رجیستر ندارند. نتیجه نهایی این است که معماری آرایه سیستولیک TPU دارای مزیت چگالی و توان قابل توجهی است، و همچنین مزیت سرعت غیر قابل چشم پوشی نسبت به GPU، هنگام محاسبه ضرب ماتریس دارد.

Cloud TPU

هنگامی که یک " Cloud TPU v2" را در Google Cloud Platform درخواست می کنید، یک ماشین مجازی (VM) دریافت می کنید که دارای یک برد TPU متصل به PCI است. برد TPU دارای چهار تراشه TPU دو هسته ای است. هر هسته TPU دارای یک VPU (واحد پردازش برداری) و یک MXU 128x128 (واحد ضرب ماتریکس) است. سپس این "Cloud TPU" معمولاً از طریق شبکه به VM درخواست کننده متصل می شود. بنابراین تصویر کامل به این صورت است:

dfce5522ed644ece.png

تصویر: ماشین مجازی شما با یک شتاب دهنده "Cloud TPU" متصل به شبکه. "Cloud TPU" خود از یک VM با یک برد TPU متصل به PCI با چهار تراشه TPU دو هسته ای بر روی آن ساخته شده است.

غلاف های TPU

در مراکز داده گوگل، TPU ها به یک اتصال محاسباتی با کارایی بالا (HPC) متصل هستند که می تواند آنها را به عنوان یک شتاب دهنده بسیار بزرگ جلوه دهد. گوگل آنها را پاد می نامد و می توانند تا 512 هسته TPU v2 یا 2048 هسته TPU v3 را در بر گیرند.

2ec1e0d341e7fc34.jpeg

تصویر: یک غلاف TPU v3. بردها و قفسه های TPU از طریق اتصال HPC متصل می شوند.

در طول آموزش، شیب ها بین هسته های TPU با استفاده از الگوریتم کاهش همه رد و بدل می شوند ( توضیح خوبی در مورد همه کاهش در اینجا ). مدلی که آموزش می بیند می تواند با آموزش در اندازه های بزرگ از سخت افزار بهره مند شود.

d97b9cc5d40fdb1d.gif

تصویر: همگام سازی گرادیان ها در طول آموزش با استفاده از الگوریتم کاهش همه جانبه در شبکه HPC مش حلقوی دوبعدی Google TPU.

نرم افزار

آموزش اندازه دسته بزرگ

اندازه دسته ای ایده آل برای TPU ها 128 مورد داده در هر هسته TPU است، اما سخت افزار در حال حاضر می تواند استفاده خوبی از 8 مورد داده در هر هسته TPU نشان دهد. به یاد داشته باشید که یک Cloud TPU دارای 8 هسته است.

در این آزمایشگاه کد، از Keras API استفاده خواهیم کرد. در Keras، دسته ای که مشخص می کنید اندازه دسته جهانی برای کل TPU است. دسته های شما به طور خودکار به 8 تقسیم می شوند و روی 8 هسته TPU اجرا می شوند.

da534407825f01e3.png

برای نکات عملکردی بیشتر به راهنمای عملکرد TPU مراجعه کنید. برای اندازه‌های دسته‌ای بسیار بزرگ، ممکن است در برخی از مدل‌ها به مراقبت خاصی نیاز باشد، برای جزئیات بیشتر به LARSOptimizer مراجعه کنید.

زیر کاپوت: XLA

برنامه های تنسورفلو نمودارهای محاسباتی را تعریف می کنند. TPU به طور مستقیم کد پایتون را اجرا نمی کند، بلکه نمودار محاسباتی تعریف شده توسط برنامه تنسورفلو شما را اجرا می کند. در زیر هود، کامپایلری به نام XLA (کامپایلر جبر خطی تسریع شده) نمودار Tensorflow گره های محاسباتی را به کد ماشین TPU تبدیل می کند. این کامپایلر همچنین بسیاری از بهینه‌سازی‌های پیشرفته را روی کد و چیدمان حافظه شما انجام می‌دهد. با ارسال کار به TPU، کامپایل به طور خودکار انجام می شود. شما مجبور نیستید XLA را به صراحت در زنجیره ساخت خود قرار دهید.

edce61112cd57972.png

تصویر: برای اجرا بر روی TPU، نمودار محاسباتی تعریف شده توسط برنامه Tensorflow ابتدا به یک نمایش XLA (کامپایلر جبر خطی تسریع شده) ترجمه می شود، سپس توسط XLA به کد ماشین TPU کامپایل می شود.

استفاده از TPU در Keras

TPU ها از طریق Keras API از Tensorflow 2.1 پشتیبانی می شوند. پشتیبانی Keras روی TPU ها و TPU pod ها کار می کند. در اینجا یک مثال است که روی 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 کار می‌کند (کارهای پلتفرم هوش مصنوعی، همکاری، Kubeflow، ماشین‌های مجازی یادگیری عمیق که از طریق ابزار «ctpu up» ایجاد شده‌اند). این سیستم ها به لطف یک متغیر محیطی TPU_NAME می دانند که TPU آنها کجاست. اگر یک TPU را با دست ایجاد می‌کنید، TPU_NAME env را تنظیم کنید. var روی ماشین مجازی که از آن استفاده می‌کنید، یا TPUClusterResolver با پارامترهای صریح فراخوانی کنید: TPUClusterResolver(tp_uname, zone, project)
  • TPUStrategy بخشی است که توزیع و الگوریتم همگام سازی گرادیان "همه کاهش" را پیاده سازی می کند.
  • استراتژی از طریق یک محدوده اعمال می شود. مدل باید در محدوده استراتژی () تعریف شود.
  • تابع tpu_model.fit یک شی tf.data.Dataset را برای ورودی برای آموزش TPU انتظار دارد.

وظایف رایج انتقال TPU

  • در حالی که راه‌های زیادی برای بارگذاری داده‌ها در یک مدل Tensorflow وجود دارد، برای TPU‌ها، استفاده از tf.data.Dataset API مورد نیاز است.
  • TPU ها بسیار سریع هستند و دریافت داده ها اغلب در هنگام اجرا روی آنها به گلوگاه تبدیل می شود. ابزارهایی وجود دارد که می توانید برای شناسایی تنگناهای داده و سایر نکات عملکردی در راهنمای عملکرد TPU استفاده کنید.
  • اعداد int8 یا int16 به عنوان int32 در نظر گرفته می شوند. TPU سخت افزار اعداد صحیحی ندارد که با کمتر از 32 بیت کار کند.
  • برخی از عملیات Tensorflow پشتیبانی نمی شوند. لیست اینجاست . خبر خوب این است که این محدودیت فقط برای کد آموزشی اعمال می شود، یعنی عبور به جلو و عقب از مدل شما. همچنان می توانید از تمام عملیات Tensorflow در خط لوله ورودی داده خود استفاده کنید زیرا روی CPU اجرا می شود.
  • tf.py_func در TPU پشتیبانی نمی شود.

4. بارگذاری داده ها

c0ecb860e4cad0a9.jpegcc4781a7739c49ae.jpeg81236b00f8bbf39e.jpeg961e2228974076bb.jpeg7517dc163bdffcd5.jpeg96392df4767f566d.png

ما با مجموعه داده ای از تصاویر گل کار خواهیم کرد. هدف این است که یاد بگیرید آنها را به 5 نوع گل دسته بندی کنید. بارگذاری داده ها با استفاده از tf.data.Dataset API انجام می شود. ابتدا اجازه دهید API را بشناسیم.

دست در دست

لطفاً نوت‌بوک زیر را باز کنید، سلول‌ها را اجرا کنید (Shift-ENTER) و دستورالعمل‌ها را هر جا که برچسب "WORK REQUIRED" را مشاهده کردید دنبال کنید.

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

در این مقاله می‌توانید نکات عملکرد و بهترین روش‌های Dataset را بیابید. مستندات مرجع اینجاست .

مبانی 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. بارگذاری سریع داده ها

شتاب‌دهنده‌های سخت‌افزاری واحد پردازش تنسور (TPU) که ​​ما در این آزمایشگاه استفاده خواهیم کرد، بسیار سریع هستند. چالش اغلب این است که داده ها را به اندازه کافی سریع تغذیه کنید تا آنها را مشغول نگه دارید. Google Cloud Storage (GCS) قادر است توان عملیاتی بسیار بالایی را حفظ کند، اما مانند همه سیستم‌های ذخیره‌سازی ابری، راه‌اندازی یک اتصال هزینه‌ای را برای شبکه به عقب و جلو دارد. بنابراین، ذخیره داده های ما به صورت هزاران فایل فردی ایده آل نیست. ما قصد داریم آنها را در تعداد کمتری فایل دسته بندی کنیم و از قدرت tf.data.Dataset برای خواندن از چندین فایل به صورت موازی استفاده کنیم.

خواندن از طریق

کدی که فایل های تصویری را بارگیری می کند، اندازه آنها را به اندازه معمول تغییر می دهد و سپس آنها را در 16 فایل TFRecord ذخیره می کند در دفترچه یادداشت زیر است. لطفا سریع آن را بخوانید. اجرای آن ضروری نیست زیرا داده های با قالب بندی مناسب TFRecord برای بقیه بخش کد ارائه می شود.

c3df49e90e5a654f.png Flower pictures to TFRecords.ipynb

طرح داده ایده آل برای توان عملیاتی GCS بهینه

فرمت فایل TFRecord

فرمت فایل ترجیحی Tensorflow برای ذخیره داده ها، فرمت 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

سه نوع داده را می توان در TFRecords ذخیره کرد: رشته های بایت (لیست بایت ها)، اعداد صحیح 64 بیتی و شناورهای 32 بیتی. آنها همیشه به عنوان لیست ذخیره می شوند، یک عنصر داده منفرد لیستی با اندازه 1 خواهد بود. می توانید از توابع کمکی زیر برای ذخیره داده ها در TFRecords استفاده کنید.

نوشتن رشته های بایت

# 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())

برای خواندن داده‌ها از TFRecords، ابتدا باید طرح‌بندی رکوردهایی را که ذخیره کرده‌اید اعلام کنید. در اعلان، می توانید به هر فیلد نامگذاری شده به عنوان یک لیست با طول ثابت یا یک لیست با طول متغیر دسترسی داشته باشید:

خواندن از TFRecords

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'])

همچنین امکان داشتن فیلدهای اختیاری در TFRecords وجود دارد. اگر هنگام خواندن یک فیلد یک مقدار پیش‌فرض را مشخص کنید، در صورت عدم وجود فیلد، مقدار پیش‌فرض به جای خطا برگردانده می‌شود.

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

آنچه را پوشش داده ایم

  • 🤔 اشتراک گذاری فایل های داده برای دسترسی سریع از GCS
  • 😓 نحوه نوشتن TFRecords. (شما قبلاً نحو را فراموش کرده اید؟ اشکالی ندارد، این صفحه را به عنوان یک برگه تقلب نشانک کنید)
  • 🤔 بارگیری یک مجموعه داده از TFRecords با استفاده از TFRecordDataset

لطفا یک لحظه وقت بگذارید و این چک لیست را در ذهن خود مرور کنید.

6. تبریک می گویم!

اکنون می توانید یک TPU را با داده تغذیه کنید. لطفا به آزمایشگاه بعدی ادامه دهید

TPU ها در عمل

TPU ها و GPU ها در پلتفرم Cloud AI در دسترس هستند:

در نهایت، ما بازخورد را دوست داریم. لطفاً اگر چیزی در این آزمایشگاه اشتباه می بینید یا فکر می کنید باید بهبود یابد، به ما بگویید. بازخورد را می توان از طریق مسائل GitHub [ لینک بازخورد ] ارائه کرد.

HR.png

شناسه مارتین گورنر small.jpg
نویسنده: مارتین گورنر
توییتر: @martin_gorner