شبکه های مدرن، squeezenet، Xception، با Keras و TPU

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

در این آزمایشگاه با معماری کانولوشن مدرن آشنا می شوید و از دانش خود برای پیاده سازی یک convnet ساده اما موثر به نام "squeezenet" استفاده می کنید.

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

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

ca8cc21f6838eccc.png

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

  • برای تسلط بر سبک عملکردی Keras
  • برای ساخت یک مدل با استفاده از معماری squeezenet
  • برای استفاده از TPU ها به منظور آموزش سریع و تکرار معماری خود
  • برای پیاده سازی افزایش داده ها با tf.data.dataset
  • برای تنظیم دقیق یک مدل بزرگ از پیش آموزش دیده (Xception) روی 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. [INFO] شبکه های عصبی کانولوشنال

به طور خلاصه

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

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. [اطلاعات جدید] معماری های کانولوشنال مدرن

به طور خلاصه

7968830b57b708c0.png

تصویر: یک "ماژول" کانولوشن. چه چیزی در این مرحله بهترین است؟ یک لایه max-pool به دنبال یک لایه کانولوشن 1x1 یا ترکیبی متفاوت از لایه ها؟ همه آنها را امتحان کنید، نتایج را به هم متصل کنید و اجازه دهید شبکه تصمیم بگیرد. در سمت راست: معماری کانولوشن " شروع " با استفاده از این ماژول ها.

در Keras، برای ایجاد مدل هایی که جریان داده می تواند به داخل و خارج منشعب شود، باید از سبک مدل "عملکردی" استفاده کنید. در اینجا یک مثال است:

l = tf.keras.layers # syntax shortcut

y = l.Conv2D(filters=32, kernel_size=3, padding='same',
             activation='relu', input_shape=[192, 192, 3])(x) # x=input image

# module start: branch out
y1 = l.Conv2D(filters=32, kernel_size=1, padding='same', activation='relu')(y)
y3 = l.Conv2D(filters=32, kernel_size=3, padding='same', activation='relu')(y)
y = l.concatenate([y1, y3]) # output now has 64 channels
# module end: concatenation

# many more layers ...

# Create the model by specifying the input and output tensors.
# Keras layers track their connections automatically so that's all that's needed.
z = l.Dense(5, activation='softmax')(y)
model = tf.keras.Model(x, z)

688858c21e3beff2.png

سایر ترفندهای ارزان قیمت

فیلترهای کوچک 3x3

40a7b15fb7dbe75c.png

در این تصویر، نتیجه دو فیلتر 3*3 متوالی را مشاهده می کنید. سعی کنید نقاط داده ای را که در نتیجه نقش داشته اند ردیابی کنید: این دو فیلتر 3x3 متوالی ترکیبی از یک منطقه 5x5 را محاسبه می کنند. این دقیقاً همان ترکیبی نیست که یک فیلتر 5x5 محاسبه می کند، اما ارزش امتحان کردن را دارد زیرا دو فیلتر 3x3 متوالی ارزان تر از یک فیلتر 5x5 منفرد هستند.

پیچش 1x1

fd7cac16f8ecb423.png

از نظر ریاضی، یک کانولوشن "1x1" ضرب در یک ثابت است، مفهوم چندان مفیدی نیست. با این حال، در شبکه‌های عصبی کانولوشن، به یاد داشته باشید که فیلتر روی یک مکعب داده اعمال می‌شود، نه فقط یک تصویر دو بعدی. بنابراین، یک فیلتر "1x1" مجموع وزنی یک ستون 1x1 از داده ها را محاسبه می کند (تصویر را ببینید) و همانطور که آن را روی داده ها می کشید، ترکیبی خطی از کانال های ورودی به دست خواهید آورد. این در واقع مفید است. اگر کانال‌ها را به‌عنوان نتایج عملیات فیلتر کردن فردی در نظر بگیرید، به‌عنوان مثال فیلتری برای «گوش‌های نوک‌دار»، فیلتری دیگر برای «سبیل‌ها» و سومی برای «چشم‌های شکاف»، یک لایه کانولوشنال «1x1» در حال محاسبه چندگانه خواهد بود. ترکیبات خطی ممکن از این ویژگی ها، که ممکن است هنگام جستجوی یک "گربه" مفید باشد. علاوه بر این، لایه های 1x1 از وزنه های کمتری استفاده می کنند.

7. Squeezenet

یک راه ساده برای کنار هم قرار دادن این ایده ها در مقاله "Squeezenet" به نمایش گذاشته شده است. نویسندگان یک طرح ماژول کانولوشن بسیار ساده را پیشنهاد می کنند که تنها از لایه های کانولوشنال 1x1 و 3x3 استفاده می کند.

1730ac375379269b.png

تصویر: معماری squeezenet بر اساس "ماژول های آتش". آنها یک لایه 1x1 را جایگزین می کنند که داده های دریافتی را در بعد عمودی "فشرده" می کند و به دنبال آن دو لایه کانولوشن 1x1 و 3x3 موازی که عمق داده ها را دوباره "بسط" می دهد.

دست در

در نوت بوک قبلی خود ادامه دهید و یک شبکه عصبی کانولوشنال الهام گرفته از squeezenet بسازید. شما باید کد مدل را به "سبک عملکردی" Keras تغییر دهید.

c3df49e90e5a654f.png Keras_Flowers_TPU (playground).ipynb

اطلاعات اضافی

برای این تمرین تعریف یک تابع کمکی برای یک ماژول squeezenet مفید خواهد بود:

def fire(x, squeeze, expand):
  y = l.Conv2D(filters=squeeze, kernel_size=1, padding='same', activation='relu')(x)
  y1 = l.Conv2D(filters=expand//2, kernel_size=1, padding='same', activation='relu')(y)
  y3 = l.Conv2D(filters=expand//2, kernel_size=3, padding='same', activation='relu')(y)
  return tf.keras.layers.concatenate([y1, y3])

# this is to make it behave similarly to other Keras layers
def fire_module(squeeze, expand):
  return lambda x: fire(x, squeeze, expand)

# usage:
x = l.Input(shape=[192, 192, 3])
y = fire_module(squeeze=24, expand=48)(x) # typically, squeeze is less than expand
y = fire_module(squeeze=32, expand=64)(y)
...
model = tf.keras.Model(x, y)

هدف این بار رسیدن به دقت 80 درصد است.

چیزهایی که باید امتحان کنید

با یک لایه کانولوشن شروع کنید، سپس با " fire_modules "، متناوب با لایه های MaxPooling2D(pool_size=2) دنبال کنید. شما می توانید با 2 تا 4 لایه حداکثر ادغام در شبکه و همچنین با 1، 2 یا 3 ماژول آتش متوالی بین لایه های حداکثر ادغام آزمایش کنید.

در ماژول های آتش، پارامتر "فشرده" معمولا باید کوچکتر از پارامتر "گسترش" باشد. این پارامترها در واقع تعدادی فیلتر هستند. آنها معمولاً می توانند از 8 تا 196 متغیر باشند. می‌توانید با معماری‌هایی آزمایش کنید که در آن تعداد فیلترها به تدریج از طریق شبکه افزایش می‌یابد، یا معماری‌های ساده‌ای که همه ماژول‌های آتش دارای تعداد فیلترهای یکسانی هستند.

در اینجا یک مثال است:

x = tf.keras.layers.Input(shape=[*IMAGE_SIZE, 3]) # input is 192x192 pixels RGB

y = tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu')(x)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.MaxPooling2D(pool_size=2)(y)
y = fire_module(24, 48)(y)
y = tf.keras.layers.GlobalAveragePooling2D()(y)
y = tf.keras.layers.Dense(5, activation='softmax')(y)

model = tf.keras.Model(x, y)

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

عادی سازی دسته ای

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

y = tf.keras.layers.BatchNormalization(momentum=0.9)(y)
# please adapt the input and output "y"s to whatever is appropriate in your context

پارامتر تکانه باید از مقدار پیش‌فرض 0.99 به 0.9 کاهش یابد زیرا مجموعه داده ما کوچک است. فعلا به این جزئیات اهمیت نده.

افزایش داده ها

با افزایش داده ها با تبدیل های آسان مانند چرخش چپ به راست تغییرات اشباع، چند درصد بیشتر به دست خواهید آورد:

4ed2958e09b487ca.png

ad795b70334e0d6b.png

انجام این کار در Tensorflow با tf.data.Dataset API بسیار آسان است. یک تابع تبدیل جدید برای داده های خود تعریف کنید:

def data_augment(image, label):
    image = tf.image.random_flip_left_right(image)
    image = tf.image.random_saturation(image, lower=0, upper=2)
    return image, label

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

dataset = dataset.repeat() # existing line
# insert this
if augment_data:
  dataset = dataset.map(data_augment, num_parallel_calls=AUTO)
dataset = dataset.shuffle(2048) # existing line

فراموش نکنید که افزایش داده را اختیاری کنید و کد لازم را اضافه کنید تا مطمئن شوید که فقط مجموعه داده آموزشی افزوده شده است . افزایش مجموعه داده اعتبارسنجی منطقی نیست.

دقت 80 درصد در 35 دوره اکنون باید در دسترس باشد.

راه حل

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

c3df49e90e5a654f.png Keras_Flowers_TPU_squeezenet.ipynb

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

  • 🤔 مدل های "سبک کاربردی" کراس
  • 🤓 معماری Squeezenet
  • 🤓 افزایش داده با tf.data.datset

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

8. Xception به خوبی تنظیم شده است

پیچیدگی های قابل تفکیک

روشی متفاوت برای اجرای لایه‌های کانولوشن اخیراً محبوبیت پیدا کرده است: پیچش‌های قابل تفکیک با عمق. من می دانم، این یک لقمه است، اما مفهوم آن بسیار ساده است. آنها در Tensorflow و Keras به عنوان tf.keras.layers.SeparableConv2D پیاده سازی شده اند.

یک کانولوشن قابل جداسازی نیز یک فیلتر را روی تصویر اجرا می کند اما از مجموعه وزن مجزایی برای هر کانال تصویر ورودی استفاده می کند. با یک "پیچیدگی 1x1" دنبال می شود، مجموعه ای از محصولات نقطه ای که منجر به مجموع وزنی کانال های فیلتر شده می شود. هر بار با وزن‌های جدید، به همان اندازه که لازم باشد، نوترکیبی وزنی کانال‌ها محاسبه می‌شود.

615720b803bf8dda.gif

تصویر: پیچیدگی های قابل تفکیک. فاز 1: کانولوشن با یک فیلتر جداگانه برای هر کانال. فاز 2: نوترکیبی خطی کانال ها. با یک مجموعه وزنه جدید تکرار می شود تا به تعداد کانال های خروجی مورد نظر برسد. فاز 1 نیز می تواند تکرار شود، هر بار با وزنه های جدید، اما در عمل به ندرت چنین است.

کانولوشن‌های جداشدنی در معماری‌های اخیر شبکه‌های کانولوشن استفاده می‌شوند: MobileNetV2، Xception، EfficientNet. به هر حال، MobileNetV2 همان چیزی است که قبلاً برای انتقال یادگیری استفاده می کردید.

آنها ارزان تر از پیچش های معمولی هستند و در عمل به همان اندازه موثر هستند. در اینجا شمارش وزن برای مثال نشان داده شده در بالا آمده است:

لایه کانولوشن: 4 x 4 x 3 x 5 = 240

لایه کانولوشن قابل جداسازی: 4 x 4 x 3 + 3 x 5 = 48 + 15 = 63

به عنوان تمرینی برای خواننده باقی می‌ماند تا تعداد ضرب‌های لازم برای اعمال هر سبک از مقیاس‌های لایه کانولوشن را به روشی مشابه محاسبه کند. پیچیدگی های قابل جداسازی کوچکتر هستند و از نظر محاسباتی بسیار مؤثرتر هستند.

دست در

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

c3df49e90e5a654f.png Keras Flowers transfer learning (playground).ipynb

هدف: دقت > 95% (نه، جدی، ممکن است!)

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

اطلاعات اضافی در مورد تنظیم دقیق

Xception در مدل های استاندارد از پیش آموزش دیده در tf.keras.application موجود است. فراموش نکنید که این بار تمام وزنه ها را قابل تمرین بگذارید.

pretrained_model = tf.keras.applications.Xception(input_shape=[*IMAGE_SIZE, 3],
                                                  include_top=False)
pretrained_model.trainable = True

برای به دست آوردن نتایج خوب هنگام تنظیم دقیق یک مدل، باید به نرخ یادگیری توجه کنید و از یک برنامه زمان‌بندی نرخ یادگیری با دوره افزایش استفاده کنید. مثل این:

9b1af213b2b36d47.png

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

در Keras، نرخ یادگیری از طریق یک callback مشخص می شود که در آن می توانید نرخ یادگیری مناسب را برای هر دوره محاسبه کنید. Keras نرخ یادگیری صحیح را برای هر دوره به بهینه ساز منتقل می کند.

def lr_fn(epoch):
  lr = ...
  return lr

lr_callback = tf.keras.callbacks.LearningRateScheduler(lr_fn, verbose=True)

model.fit(..., callbacks=[lr_callback])

راه حل

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

c3df49e90e5a654f.png 07_Keras_Flowers_TPU_xception_fine_tuned_best.ipynb

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

  • 🤔 پیچیدگی قابل تفکیک در عمق
  • 🤓 جدول نرخ یادگیری
  • 😈 تنظیم دقیق یک مدل از قبل آموزش دیده.

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

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

شما اولین شبکه عصبی کانولوشنال مدرن خود را ساخته اید و آن را با دقت + 90% آموزش داده اید و به لطف TPU ها تنها در چند دقیقه آموزش های متوالی را تکرار می کنید. این 4 "Kera on TPU codelabs" را به پایان می رساند:

TPU ها در عمل

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

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

HR.png

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

tensorflow logo.jpg
www.tensorflow.org