شبکه های عصبی کانولوشنال، با Keras و TPU

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

در این آزمایشگاه، نحوه مونتاژ لایه کانولوشن را در یک مدل شبکه عصبی که می تواند گل ها را تشخیص دهد، یاد خواهید گرفت. این بار، خودتان مدل را از ابتدا می‌سازید و از قدرت TPU برای آموزش آن در چند ثانیه و تکرار طرح آن استفاده می‌کنید.

این آزمایشگاه شامل توضیحات نظری لازم در مورد شبکه های عصبی کانولوشن است و نقطه شروع خوبی برای توسعه دهندگان یادگیری عمیق است.

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

ca8cc21f6838eccc.png

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

  • برای ساخت یک طبقه بندی کننده تصویر کانولوشنال با استفاده از مدل Keras Sequential.
  • برای آموزش مدل Keras خود بر روی TPU
  • برای تنظیم دقیق مدل خود با انتخاب خوبی از لایه های کانولوشن.

بازخورد

اگر در این آزمایشگاه کد مشکلی مشاهده کردید، لطفاً به ما بگویید. بازخورد را می توان از طریق مسائل 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. [INFO] طبقه بندی شبکه عصبی 101

به طور خلاصه

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

برای مدل‌هایی که به‌عنوان دنباله‌ای از لایه‌ها ساخته می‌شوند، Keras API متوالی را ارائه می‌کند. برای مثال، یک طبقه‌بندی‌کننده تصویر با استفاده از سه لایه متراکم می‌تواند در Keras به صورت زیر نوشته شود:

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
    tf.keras.layers.Dense(500, activation="relu"),
    tf.keras.layers.Dense(50, activation="relu"),
    tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])

# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy']) # % of correct answers

# train the model
model.fit(dataset, ... )

688858c21e3beff2.png

شبکه عصبی متراکم

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

c21bae6dade487bc.png

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

نورون ها، فعال سازی ها، RELU

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

644f4213a4ee70e5.png

محبوب ترین تابع فعال سازی RELU برای واحد خطی اصلاح شده نام دارد. این یک تابع بسیار ساده است همانطور که در نمودار بالا می بینید.

فعال سازی سافت مکس

شبکه بالا با یک لایه 5 نورونی به پایان می رسد زیرا ما گل ها را به 5 دسته (رز، لاله، قاصدک، دیزی، آفتابگردان) طبقه بندی می کنیم. نورون ها در لایه های میانی با استفاده از تابع فعال سازی کلاسیک RELU فعال می شوند. در آخرین لایه، می خواهیم اعدادی بین 0 و 1 را محاسبه کنیم که نشان دهنده احتمال گل رز، لاله و غیره است. برای این کار از یک تابع فعال سازی به نام softmax استفاده می کنیم.

اعمال softmax بر روی یک بردار با گرفتن نمایی هر عنصر و سپس نرمال سازی بردار انجام می شود، معمولاً با استفاده از هنجار L1 (مجموع مقادیر مطلق) به طوری که مجموع مقادیر به 1 می رسد و می توان آنها را به عنوان احتمال تفسیر کرد.

ef0d98c0952c262d.pngd51252f75894479e.gif

از دست دادن آنتروپی متقابل

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

هر فاصله ای کار می کند، اما برای مشکلات طبقه بندی، به اصطلاح "فاصله آنتروپی متقابل" موثرترین است. ما این را تابع خطا یا "از دست دادن" خود می نامیم:

7bdf8753d20617fb.png

نزول گرادیان

"آموزش" شبکه عصبی در واقع به معنای استفاده از تصاویر و برچسب های آموزشی برای تنظیم وزن ها و سوگیری ها به گونه ای است که تابع تلفات متقابل آنتروپی را به حداقل برساند. در اینجا نحوه کار آن است.

آنتروپی متقاطع تابعی از وزن ها، بایاس ها، پیکسل های تصویر تمرینی و کلاس شناخته شده آن است.

اگر مشتقات جزئی آنتروپی متقاطع را نسبت به همه وزن‌ها و همه بایاس‌ها محاسبه کنیم، یک "gradient" به دست می‌آوریم که برای تصویر، برچسب و ارزش فعلی وزن‌ها و بایاس‌ها محاسبه می‌شود. به یاد داشته باشید که ما می‌توانیم میلیون‌ها وزن و سوگیری داشته باشیم، بنابراین محاسبه گرادیان کار زیادی به نظر می‌رسد. خوشبختانه، تنسورفلو این کار را برای ما انجام می دهد. ویژگی ریاضی یک گرادیان این است که به سمت بالا اشاره می کند. از آنجایی که می خواهیم به جایی برویم که آنتروپی متقاطع کم است، در جهت مخالف می رویم. وزن ها و سوگیری ها را با کسری از گرادیان به روز می کنیم. سپس همین کار را بارها و بارها با استفاده از دسته های بعدی تصاویر و برچسب های آموزشی در یک حلقه آموزشی انجام می دهیم. امیدواریم که این به جایی برسد که آنتروپی متقاطع حداقل باشد، اگرچه هیچ چیزی منحصر به فرد بودن این حداقل را تضمین نمی کند.

گرادیان descent2.png

مینی بچینگ و تکانه

شما می‌توانید گرادیان خود را فقط بر روی یک تصویر مثال محاسبه کنید و وزن‌ها و بایاس‌ها را فوراً به‌روزرسانی کنید، اما انجام این کار روی دسته‌ای از مثلاً 128 تصویر، گرادیانی به دست می‌دهد که محدودیت‌های اعمال‌شده توسط تصاویر نمونه‌های مختلف را بهتر نشان می‌دهد و بنابراین احتمالاً همگرا می‌شود. به سمت راه حل سریعتر اندازه مینی بچ یک پارامتر قابل تنظیم است.

این تکنیک، که گاهی اوقات "نزول گرادیان تصادفی" نامیده می‌شود، یک مزیت عملی‌تر دیگر نیز دارد: کار با دسته‌ها همچنین به معنای کار با ماتریس‌های بزرگ‌تر است و معمولاً بهینه‌سازی آنها روی GPU و TPU آسان‌تر است.

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

52e824fe4716c4a0.png

تصویر: یک نقطه زین. گرادیان 0 است اما در همه جهات حداقل نیست. (اشاره به تصویر ویکی‌مدیا: توسط Nicoguaro - Own Work, CC BY 3.0 )

راه حل این است که مقداری حرکت به الگوریتم بهینه سازی اضافه شود تا بتواند بدون توقف از نقاط زین عبور کند.

واژه نامه

دسته ای یا مینی دسته ای : آموزش همیشه بر روی دسته ای از داده ها و برچسب های آموزشی انجام می شود. انجام این کار به همگرایی الگوریتم کمک می کند. بعد "دسته ای" معمولاً اولین بعد تانسورهای داده است. برای مثال یک تانسور شکل [100، 192، 192، 3] حاوی 100 تصویر 192x192 پیکسل با سه مقدار در هر پیکسل (RGB) است.

از دست دادن آنتروپی متقابل : یک تابع تلفات ویژه که اغلب در طبقه‌بندی‌کننده‌ها استفاده می‌شود.

لایه متراکم : لایه ای از نورون ها که در آن هر نورون به تمام نورون های لایه قبلی متصل است.

ویژگی ها : ورودی های یک شبکه عصبی گاهی اوقات "ویژگی" نامیده می شود. هنر فهمیدن اینکه کدام بخش از یک مجموعه داده (یا ترکیبی از قطعات) باید به شبکه عصبی وارد شود تا پیش‌بینی‌های خوبی داشته باشیم، «مهندسی ویژگی» نامیده می‌شود.

برچسب ها : نام دیگری برای "کلاس ها" یا پاسخ های صحیح در یک مشکل طبقه بندی نظارت شده

نرخ یادگیری : کسری از گرادیان که توسط آن وزن‌ها و سوگیری‌ها در هر تکرار از حلقه آموزشی به‌روز می‌شوند.

logits : خروجی های لایه ای از نورون ها قبل از اعمال تابع فعال سازی "logits" نامیده می شوند. این اصطلاح از "عملکرد لجستیک" با نام "تابع سیگموئید" می آید که در گذشته محبوب ترین تابع فعال سازی بود. "خروجی های نورون قبل از عملکرد لجستیک" به "logits" کوتاه شد.

ضرر : تابع خطا در مقایسه خروجی های شبکه عصبی با پاسخ های صحیح

نورون : مجموع وزنی ورودی های خود را محاسبه می کند، بایاس اضافه می کند و نتیجه را از طریق یک تابع فعال سازی تغذیه می کند.

کدگذاری تک داغ : کلاس 3 از 5 به صورت بردار 5 عنصری کدگذاری می شود، همه صفرها به جز سومی که 1 است.

relu : واحد خطی اصلاح شده یک تابع فعال سازی محبوب برای نورون ها.

sigmoid : یکی دیگر از عملکردهای فعال سازی که قبلاً محبوب بود و هنوز هم در موارد خاص مفید است.

softmax : یک تابع فعال‌سازی ویژه که بر روی یک بردار عمل می‌کند، اختلاف بین بزرگترین مؤلفه و سایر مؤلفه‌ها را افزایش می‌دهد، و همچنین بردار را با مجموع 1 نرمال می‌کند تا بتوان آن را به عنوان بردار احتمالات تفسیر کرد. به عنوان آخرین مرحله در طبقه بندی کننده ها استفاده می شود.

تانسور : یک "تانسور" مانند یک ماتریس است اما دارای تعداد دلخواه ابعاد است. تانسور یک بعدی یک بردار است. یک تانسور دو بعدی یک ماتریس است. و سپس می توانید تانسورهایی با ابعاد 3، 4، 5 یا بیشتر داشته باشید.

5. [اطلاعات جدید] شبکه های عصبی کانولوشن

به طور خلاصه

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

convolutional.gif

تصویر: فیلتر کردن یک تصویر با دو فیلتر متوالی از 4x4x3=48 وزن قابل یادگیری هر کدام.

یک شبکه عصبی کانولوشنال ساده در Keras به این صورت است:

model = tf.keras.Sequential([
  # input: images of size 192x192x3 pixels (the three stands for RGB channels)
  tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu', input_shape=[192, 192, 3]),
  tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=6, padding='same', activation='relu'),
  tf.keras.layers.Flatten(),
  # classifying into 5 categories
  tf.keras.layers.Dense(5, activation='softmax')
])

model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy'])

688858c21e3beff2.png

شبکه های عصبی کانولوشن 101

در لایه‌ای از یک شبکه کانولوشن، یک «نرون» مجموع وزنی پیکسل‌ها را درست بالای آن، فقط در ناحیه کوچکی از تصویر انجام می‌دهد. این یک سوگیری اضافه می کند و مجموع را از طریق یک تابع فعال سازی تغذیه می کند، درست همانطور که یک نورون در یک لایه متراکم منظم انجام می دهد. سپس این عمل در کل تصویر با استفاده از وزن های مشابه تکرار می شود. به یاد داشته باشید که در لایه های متراکم، هر نورون وزن مخصوص به خود را داشت. در اینجا، یک "پچ" از وزن ها در هر دو جهت روی تصویر می لغزند (یک "پیچیدگی"). مقدار خروجی به اندازه پیکسل های تصویر است (هر چند در لبه ها مقداری padding لازم است). این یک عملیات فیلتر است، با استفاده از فیلتر 4x4x3=48 وزن.

با این حال، 48 وزنه کافی نخواهد بود. برای افزودن درجات آزادی بیشتر، همین عمل را با یک مجموعه وزنه جدید تکرار می کنیم. این مجموعه جدیدی از خروجی های فیلتر را تولید می کند. بیایید آن را یک "کانال" از خروجی ها بر اساس قیاس با کانال های R,G,B در تصویر ورودی بنامیم.

اسکرین شات 29/07/2016 در 16.02.37.png

دو (یا بیشتر) مجموعه وزن را می توان با افزودن یک بعد جدید به عنوان یک تانسور خلاصه کرد. این شکل کلی تانسور وزنه را برای یک لایه کانولوشن به ما می دهد. از آنجایی که تعداد کانال‌های ورودی و خروجی پارامتر هستند، می‌توانیم لایه‌های کانولوشنال را انباشته و زنجیره‌ای کنیم.

d1b557707bcd1cb9.png

تصویر: یک شبکه عصبی کانولوشن "مکعب" داده را به "مکعب" دیگر داده تبدیل می کند.

پیچیدگی های راه راه، حداکثر تجمع

با انجام کانولوشن ها با گام 2 یا 3، می توانیم مکعب داده به دست آمده را در ابعاد افقی آن نیز کوچک کنیم. دو روش متداول برای انجام این کار وجود دارد:

  • پیچیدگی راه راه: یک فیلتر کشویی مانند بالا اما با گام> 1
  • حداکثر ادغام: یک پنجره کشویی که عملیات MAX را اعمال می کند (معمولاً در وصله های 2x2 که هر 2 پیکسل تکرار می شود)

2b2d4263bb8470b.gif

تصویر: لغزاندن پنجره محاسباتی با 3 پیکسل منجر به مقادیر کمتر خروجی می شود. کانولوشن های راه راه یا حداکثر ادغام (حداکثر در یک پنجره 2x2 کشویی با گام 2) راهی برای کوچک کردن مکعب داده در ابعاد افقی است.

C طبقه‌بندی‌کننده متحرک

در نهایت، یک سر طبقه بندی را با صاف کردن آخرین مکعب داده و تغذیه آن از طریق یک لایه متراکم و فعال شده با softmax متصل می کنیم. یک طبقه بندی کانولوشنال معمولی می تواند به شکل زیر باشد:

4a61aaffb6cba3d1.png

تصویر: یک طبقه‌بندی کننده تصویر با استفاده از لایه‌های کانولوشنال و سافت مکس. از فیلترهای 3x3 و 1x1 استفاده می کند. لایه های maxpool حداکثر گروه های 2x2 نقطه داده را می گیرند. سر طبقه بندی با یک لایه متراکم با فعال سازی softmax اجرا می شود.

در کراس

پشته کانولوشنال نشان داده شده در بالا را می توان در Keras به این صورت نوشت:

model = tf.keras.Sequential([
  # input: images of size 192x192x3 pixels (the three stands for RGB channels)    
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu', input_shape=[192, 192, 3]),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
  tf.keras.layers.MaxPooling2D(pool_size=2),
  tf.keras.layers.Conv2D(kernel_size=3, filters=16, padding='same', activation='relu'),
  tf.keras.layers.Conv2D(kernel_size=1, filters=8, padding='same', activation='relu'),
  tf.keras.layers.Flatten(),
  # classifying into 5 categories
  tf.keras.layers.Dense(5, activation='softmax')
])

model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy'])

6. convnet سفارشی شما

دست در

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

c3df49e90e5a654f.png Keras_Flowers_TPU (playground).ipynb

هدف شکست دادن دقت 75 درصدی مدل یادگیری انتقال است. این مدل یک مزیت داشت، زیرا از قبل بر روی مجموعه داده ای از میلیون ها تصویر آموزش داده شده بود، در حالی که ما در اینجا فقط 3670 تصویر داریم. آیا می توانید حداقل آن را مطابقت دهید؟

اطلاعات تکمیلی

چند لایه، چند لایه؟

انتخاب اندازه لایه ها بیشتر یک هنر است تا یک علم. شما باید تعادل مناسبی بین داشتن پارامترهای خیلی کم و زیاد (وزن ها و سوگیری ها) پیدا کنید. با وزن های بسیار کم، شبکه عصبی نمی تواند پیچیدگی اشکال گل را نشان دهد. با تعداد زیاد، می تواند مستعد "بیش از حد مناسب شدن" باشد، یعنی متخصص در تصاویر آموزشی و ناتوانی در تعمیم. با پارامترهای زیاد، آموزش مدل نیز کند خواهد بود. در Keras، تابع model.summary() ساختار و تعداد پارامترهای مدل شما را نمایش می دهد:

Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 192, 192, 16)      448       
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 192, 192, 30)      4350      
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 96, 96, 30)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 96, 96, 60)        16260     
_________________________________________________________________
 ... 
_________________________________________________________________
global_average_pooling2d (Gl (None, 130)               0         
_________________________________________________________________
dense (Dense)                (None, 90)                11790     
_________________________________________________________________
dense_1 (Dense)              (None, 5)                 455       
=================================================================
Total params: 300,033
Trainable params: 300,033
Non-trainable params: 0
_________________________________________________________________

چند نکته:

  • داشتن چندین لایه چیزی است که شبکه های عصبی "عمیق" را موثر می کند. برای این مشکل ساده تشخیص گل، 5 تا 10 لایه منطقی است.
  • از فیلترهای کوچک استفاده کنید. به طور معمول فیلترهای 3x3 در همه جا خوب هستند.
  • فیلترهای 1x1 نیز قابل استفاده هستند و ارزان هستند. آنها واقعاً چیزی جز محاسبه ترکیب خطی کانال ها را "فیلتر" نمی کنند. آنها را با فیلترهای واقعی جایگزین کنید. (اطلاعات بیشتر در مورد "پیچش 1x1" در بخش بعدی.)
  • برای مشکل طبقه‌بندی مانند این، مرتباً با لایه‌های max-pooling (یا کانولوشن با گام> 1) نمونه برداری کنید. برای شما مهم نیست که گل کجاست، فقط گل رز یا قاصدک است، بنابراین از دست دادن اطلاعات x و y مهم نیست و فیلتر کردن مناطق کوچکتر ارزان تر است.
  • تعداد فیلترها معمولاً شبیه به تعداد کلاس‌های انتهای شبکه می‌شود (چرا؟ ترفند "تجمع میانگین جهانی" را در زیر ببینید). اگر به صدها کلاس طبقه بندی می کنید، تعداد فیلترها را به تدریج در لایه های متوالی افزایش دهید. برای مجموعه داده گل با 5 کلاس، فیلتر کردن تنها با 5 فیلتر کافی نخواهد بود. شما می توانید از همان تعداد فیلتر در اکثر لایه ها استفاده کنید، به عنوان مثال 32 و آن را تا انتها کاهش دهید.
  • لایه(های) متراکم نهایی گران هستند/گران هستند. این/آنها می توانند وزن بیشتری از مجموع همه لایه های کانولوشن داشته باشند. به عنوان مثال، حتی با یک خروجی بسیار معقول از آخرین مکعب داده 24x24x10 نقطه داده، یک لایه متراکم 100 نورونی 24x24x10x100 = 576000 وزن هزینه خواهد داشت. سعی کنید متفکر باشید یا میانگین جهانی را امتحان کنید (به زیر مراجعه کنید).

تجمیع میانگین جهانی

به جای استفاده از یک لایه متراکم گران قیمت در انتهای یک شبکه عصبی کانولوشنال، می‌توانید «مکعب» داده‌های ورودی را به تعداد کلاس‌هایی که دارید تقسیم کنید، مقادیر آن‌ها را میانگین کنید و از طریق یک تابع فعال‌سازی softmax تغذیه کنید. این روش ساخت سر طبقه بندی 0 وزن هزینه دارد. در Keras، نحو tf.keras.layers.GlobalAveragePooling2D().

93240029f59df7c2.png

راه حل

این دفترچه راه حل است. اگر گیر کرده اید می توانید از آن استفاده کنید.

c3df49e90e5a654f.png Keras_Flowers_TPU (solution).ipynb

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

  • 🤔 بازی با لایه های کانولوشن
  • 🤓 با حداکثر ادغام، گام‌ها، جمع‌بندی میانگین جهانی، ... آزمایش شده است.
  • 😀 روی یک مدل واقعی به سرعت، روی TPU تکرار شد

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

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

شما اولین شبکه عصبی کانولوشنال مدرن خود را ساخته اید و آن را با دقت 80% + آموزش داده اید و به لطف TPU ها فقط در چند دقیقه معماری آن را تکرار می کنید. لطفاً برای آشنایی با معماری‌های کانولوشن مدرن به آزمایشگاه بعدی بروید:

TPU ها در عمل

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

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

hr.png

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

tensorflow logo.jpg
www.tensorflow.org