1. بررسی اجمالی
در این آزمایشگاه با معماری کانولوشن مدرن آشنا می شوید و از دانش خود برای پیاده سازی یک convnet ساده اما موثر به نام "squeezenet" استفاده می کنید.
این آزمایشگاه شامل توضیحات نظری لازم در مورد شبکه های عصبی کانولوشن است و نقطه شروع خوبی برای توسعه دهندگان یادگیری عمیق است.
این آزمایشگاه قسمت 4 از سری "Keras on TPU" است. می توانید آنها را به ترتیب زیر یا به صورت مستقل انجام دهید.
- خطوط لوله داده با سرعت TPU: tf.data.Dataset و TFRecords
- اولین مدل کراس شما با آموزش انتقالی
- شبکه های عصبی کانولوشنال، با Keras و TPU
- [THIS LAB] convnet های مدرن، squeezenet، Xception، با Keras و TPU
چیزی که یاد خواهید گرفت
- برای تسلط بر سبک عملکردی Keras
- برای ساخت یک مدل با استفاده از معماری squeezenet
- برای استفاده از TPU ها به منظور آموزش سریع و تکرار معماری خود
- برای پیاده سازی افزایش داده ها با tf.data.dataset
- برای تنظیم دقیق یک مدل بزرگ از پیش آموزش دیده (Xception) روی TPU
بازخورد
اگر در این آزمایشگاه کد مشکلی مشاهده کردید، لطفاً به ما بگویید. بازخورد را می توان از طریق مسائل GitHub [ لینک بازخورد ] ارائه کرد.
2. شروع سریع Google Collaboratory
این آزمایشگاه از Google Collaboratory استفاده می کند و نیازی به تنظیم از طرف شما ندارد. Colaboratory یک پلت فرم نوت بوک آنلاین برای اهداف آموزشی است. آموزش رایگان CPU، GPU و TPU را ارائه می دهد.
میتوانید این نمونه دفترچه یادداشت را باز کنید و از چند سلول عبور کنید تا با Colaboratory آشنا شوید.
یک باطن TPU را انتخاب کنید
در منوی Colab، Runtime > Change runtime type و سپس TPU را انتخاب کنید. در این آزمایشگاه کد از یک TPU (واحد پردازش تنسور) قدرتمند استفاده میکنید که برای آموزش سختافزاری تسریع شده پشتیبانی میشود. اتصال به زمان اجرا به طور خودکار در اولین اجرا انجام می شود، یا می توانید از دکمه "اتصال" در گوشه سمت راست بالا استفاده کنید.
اجرای نوت بوک
با کلیک بر روی یک سلول و استفاده از Shift-ENTER سلول ها را یکی یکی اجرا کنید. همچنین می توانید کل نوت بوک را با Runtime > Run all اجرا کنید
فهرست مطالب
همه نوت بوک ها دارای فهرست مطالب هستند. می توانید آن را با استفاده از فلش سیاه سمت چپ باز کنید.
سلول های پنهان
برخی از سلول ها فقط عنوان خود را نشان می دهند. این یک ویژگی نوت بوک مخصوص Colab است. می توانید روی آنها دوبار کلیک کنید تا کد داخل آن را ببینید اما معمولاً چندان جالب نیست. به طور معمول توابع پشتیبانی یا تجسم. هنوز باید این سلول ها را اجرا کنید تا توابع داخل آن تعریف شوند.
احراز هویت
این امکان برای Colab وجود دارد که به سطلهای خصوصی Google Cloud Storage شما دسترسی داشته باشد، مشروط بر اینکه با یک حساب مجاز احراز هویت کنید. قطعه کد بالا یک فرآیند احراز هویت را راه اندازی می کند.
3. [INFO] واحدهای پردازش تانسور (TPU) چیست؟
به طور خلاصه
کد آموزش مدل بر روی 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 ها برای ساخت و بهینه سازی یک طبقه بندی گل با سرعت های تعاملی (دقیقه در هر دوره آموزشی) استفاده خواهیم کرد.
چرا TPU ها؟
پردازندههای گرافیکی مدرن حول محورهای قابل برنامهریزی سازماندهی شدهاند، معماری بسیار انعطافپذیری که به آنها اجازه میدهد تا کارهای مختلفی مانند رندر سه بعدی، یادگیری عمیق، شبیهسازی فیزیکی و غیره را انجام دهند. واحد ضرب ماتریس و برتری در هر کاری که ضرب ماتریس بزرگ غالب است، مانند شبکه های عصبی.
تصویر: یک لایه شبکه عصبی متراکم به عنوان ضرب ماتریس، با دستهای از هشت تصویر که در یک شبکه عصبی پردازش میشوند. لطفاً ضرب در یک خط x ستون را اجرا کنید تا بررسی کنید که واقعاً مجموع وزنی تمام مقادیر پیکسل های یک تصویر را انجام می دهد. لایههای کانولوشنال را میتوان به صورت ضربهای ماتریسی نیز نشان داد، اگرچه کمی پیچیدهتر است ( توضیح در اینجا، در بخش 1 ).
سخت افزار
MXU و VPU
یک هسته TPU v2 از یک واحد ضرب ماتریس (MXU) ساخته شده است که ضرب ماتریس را اجرا می کند و یک واحد پردازش برداری (VPU) برای همه کارهای دیگر مانند فعال سازی، سافت مکس و غیره. VPU محاسبات float32 و int32 را انجام می دهد. از سوی دیگر، MXU در فرمت ممیز شناور با دقت ترکیبی 16-32 بیتی کار می کند.
نقطه شناور دقیق مخلوط و bfloat16
MXU ضرب های ماتریس را با استفاده از ورودی های bfloat16 و خروجی های float32 محاسبه می کند. انباشته های میانی با دقت float32 انجام می شود.
آموزش شبکه عصبی معمولاً در برابر نویز ایجاد شده توسط کاهش دقت ممیز شناور مقاوم است. مواردی وجود دارد که نویز حتی به همگرایی بهینه ساز کمک می کند. دقت ممیز شناور 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 پیاده سازی کند و این ضرب ماتریس را در یک حرکت پردازش کند.
تصویر: آرایه سیستولیک MXU. عناصر محاسباتی چند انباشته هستند. مقادیر یک ماتریس در آرایه بارگذاری می شوند (نقاط قرمز). مقادیر ماتریس دیگر از طریق آرایه جریان می یابد (نقاط خاکستری). خطوط عمودی مقادیر را به بالا منتشر می کنند. خطوط افقی مجموع جزئی را منتشر می کنند. به عنوان یک تمرین به کاربر سپرده می شود تا تأیید کند که با جریان داده در آرایه، نتیجه ضرب ماتریس از سمت راست را دریافت می کنید.
علاوه بر آن، در حالی که محصولات نقطه ای در یک MXU محاسبه می شوند، مبالغ میانی به سادگی بین واحدهای محاسباتی مجاور جریان می یابد. آنها نیازی به ذخیره و بازیابی در/از حافظه یا حتی یک فایل رجیستر ندارند. نتیجه نهایی این است که معماری آرایه سیستولیک TPU دارای مزیت چگالی و توان قابل توجهی است، و همچنین مزیت سرعت غیر قابل چشم پوشی نسبت به GPU، هنگام محاسبه ضرب ماتریس دارد.
Cloud TPU
هنگامی که یک " Cloud TPU v2" را در Google Cloud Platform درخواست می کنید، یک ماشین مجازی (VM) دریافت می کنید که دارای یک برد TPU متصل به PCI است. برد TPU دارای چهار تراشه TPU دو هسته ای است. هر هسته TPU دارای یک VPU (واحد پردازش برداری) و یک MXU 128x128 (واحد ضرب ماتریکس) است. سپس این "Cloud TPU" معمولاً از طریق شبکه به VM درخواست کننده متصل می شود. بنابراین تصویر کامل به این صورت است:
تصویر: ماشین مجازی شما با یک شتاب دهنده "Cloud TPU" متصل به شبکه. "Cloud TPU" خود از یک VM با یک برد TPU متصل به PCI با چهار تراشه TPU دو هسته ای بر روی آن ساخته شده است.
غلاف های TPU
در مراکز داده گوگل، TPU ها به یک اتصال محاسباتی با کارایی بالا (HPC) متصل هستند که می تواند آنها را به عنوان یک شتاب دهنده بسیار بزرگ جلوه دهد. گوگل آنها را پاد می نامد و می توانند تا 512 هسته TPU v2 یا 2048 هسته TPU v3 را در بر گیرند.
تصویر: یک غلاف TPU v3. بردها و قفسه های TPU از طریق اتصال HPC متصل می شوند.
در طول آموزش، شیب ها بین هسته های TPU با استفاده از الگوریتم کاهش همه رد و بدل می شوند ( توضیح خوبی در مورد همه کاهش در اینجا ). مدلی که آموزش می بیند می تواند با آموزش در اندازه های بزرگ از سخت افزار بهره مند شود.
تصویر: همگام سازی گرادیان ها در طول آموزش با استفاده از الگوریتم کاهش همه جانبه در شبکه HPC مش حلقوی دوبعدی Google TPU.
نرم افزار
آموزش اندازه دسته بزرگ
اندازه دسته ای ایده آل برای TPU ها 128 مورد داده در هر هسته TPU است، اما سخت افزار در حال حاضر می تواند استفاده خوبی از 8 مورد داده در هر هسته TPU نشان دهد. به یاد داشته باشید که یک Cloud TPU دارای 8 هسته است.
در این آزمایشگاه کد، از Keras API استفاده خواهیم کرد. در Keras، دسته ای که مشخص می کنید اندازه دسته جهانی برای کل TPU است. دسته های شما به طور خودکار به 8 تقسیم می شوند و روی 8 هسته TPU اجرا می شوند.
برای نکات عملکردی بیشتر به راهنمای عملکرد TPU مراجعه کنید. برای اندازههای دستهای بسیار بزرگ، ممکن است در برخی از مدلها به مراقبت خاصی نیاز باشد، برای جزئیات بیشتر به LARSOptimizer مراجعه کنید.
زیر کاپوت: XLA
برنامه های تنسورفلو نمودارهای محاسباتی را تعریف می کنند. TPU به طور مستقیم کد پایتون را اجرا نمی کند، بلکه نمودار محاسباتی تعریف شده توسط برنامه تنسورفلو شما را اجرا می کند. در زیر هود، کامپایلری به نام XLA (کامپایلر جبر خطی تسریع شده) نمودار Tensorflow گره های محاسباتی را به کد ماشین TPU تبدیل می کند. این کامپایلر همچنین بسیاری از بهینهسازیهای پیشرفته را روی کد و چیدمان حافظه شما انجام میدهد. با ارسال کار به TPU، کامپایل به طور خودکار انجام می شود. شما مجبور نیستید XLA را به صراحت در زنجیره ساخت خود قرار دهید.
تصویر: برای اجرا بر روی 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, ... )
شبکه عصبی متراکم
این ساده ترین شبکه عصبی برای طبقه بندی تصاویر است. از "نورون" ساخته شده است که در لایه ها چیده شده اند. لایه اول داده های ورودی را پردازش می کند و خروجی های آن را به لایه های دیگر تغذیه می کند. به آن "متراکم" می گویند زیرا هر نورون به تمام نورون های لایه قبلی متصل است.
شما می توانید با صاف کردن مقادیر RGB تمام پیکسل های آن در یک بردار طولانی و استفاده از آن به عنوان ورودی، یک تصویر را به چنین شبکه ای وارد کنید. این بهترین تکنیک برای تشخیص تصویر نیست، اما بعداً آن را بهبود خواهیم داد.
نورون ها، فعال سازی ها، RELU
یک "نورون" مجموع وزنی همه ورودی های خود را محاسبه می کند، مقداری به نام "سوگیری" را اضافه می کند و نتیجه را از طریق به اصطلاح "تابع فعال سازی" تغذیه می کند. وزن و سوگیری در ابتدا ناشناخته است. آنها به صورت تصادفی مقداردهی اولیه می شوند و با آموزش شبکه عصبی بر روی بسیاری از داده های شناخته شده "یاد می گیرند".
محبوب ترین تابع فعال سازی RELU برای واحد خطی اصلاح شده نام دارد. این یک تابع بسیار ساده است همانطور که در نمودار بالا می بینید.
فعال سازی سافت مکس
شبکه بالا با یک لایه 5 نورونی به پایان می رسد زیرا ما گل ها را به 5 دسته (رز، لاله، قاصدک، دیزی، آفتابگردان) طبقه بندی می کنیم. نورون ها در لایه های میانی با استفاده از تابع فعال سازی کلاسیک RELU فعال می شوند. در آخرین لایه، می خواهیم اعدادی بین 0 و 1 را محاسبه کنیم که نشان دهنده احتمال گل رز، لاله و غیره است. برای این کار از یک تابع فعال سازی به نام softmax استفاده می کنیم.
اعمال softmax بر روی یک بردار با گرفتن نمایی هر عنصر و سپس نرمال سازی بردار انجام می شود، معمولاً با استفاده از هنجار L1 (مجموع مقادیر مطلق) به طوری که مجموع مقادیر به 1 می رسد و می توان آنها را به عنوان احتمال تفسیر کرد.
از دست دادن آنتروپی متقابل
اکنون که شبکه عصبی ما پیشبینیهایی را از تصاویر ورودی تولید میکند، باید میزان خوب بودن آنها را اندازهگیری کنیم، یعنی فاصله بین آنچه که شبکه به ما میگوید و پاسخهای صحیح، که اغلب «برچسبها» نامیده میشوند. به یاد داشته باشید که ما برچسب های درستی برای تمام تصاویر موجود در مجموعه داده داریم.
هر فاصله ای کار می کند، اما برای مشکلات طبقه بندی، به اصطلاح "فاصله آنتروپی متقابل" موثرترین است. ما این را تابع خطا یا "از دست دادن" خود می نامیم:
نزول گرادیان
"آموزش" شبکه عصبی در واقع به معنای استفاده از تصاویر و برچسب های آموزشی برای تنظیم وزن ها و سوگیری ها به گونه ای است که تابع تلفات متقابل آنتروپی را به حداقل برساند. در اینجا نحوه کار آن است.
آنتروپی متقاطع تابعی از وزن ها، بایاس ها، پیکسل های تصویر تمرینی و کلاس شناخته شده آن است.
اگر مشتقات جزئی آنتروپی متقاطع را نسبت به همه وزنها و همه بایاسها محاسبه کنیم، یک "gradient" به دست میآوریم که برای تصویر، برچسب و ارزش فعلی وزنها و بایاسها محاسبه میشود. به یاد داشته باشید که ما میتوانیم میلیونها وزن و سوگیری داشته باشیم، بنابراین محاسبه گرادیان کار زیادی به نظر میرسد. خوشبختانه، تنسورفلو این کار را برای ما انجام می دهد. ویژگی ریاضی یک گرادیان این است که به سمت بالا اشاره می کند. از آنجایی که می خواهیم به جایی برویم که آنتروپی متقاطع کم است، در جهت مخالف می رویم. وزن ها و سوگیری ها را با کسری از گرادیان به روز می کنیم. سپس همین کار را بارها و بارها با استفاده از دسته های بعدی تصاویر و برچسب های آموزشی در یک حلقه آموزشی انجام می دهیم. امیدواریم که این به جایی برسد که آنتروپی متقاطع حداقل باشد، اگرچه هیچ چیزی منحصر به فرد بودن این حداقل را تضمین نمی کند.
مینی بچینگ و تکانه
شما میتوانید گرادیان خود را فقط بر روی یک تصویر مثال محاسبه کنید و وزنها و بایاسها را فوراً بهروزرسانی کنید، اما انجام این کار روی دستهای از مثلاً 128 تصویر، گرادیانی به دست میدهد که محدودیتهای اعمالشده توسط تصاویر نمونههای مختلف را بهتر نشان میدهد و بنابراین احتمالاً همگرا میشود. به سمت راه حل سریعتر اندازه مینی بچ یک پارامتر قابل تنظیم است.
این تکنیک، که گاهی اوقات "نزول گرادیان تصادفی" نامیده میشود، یک مزیت عملیتر دیگر نیز دارد: کار با دستهها همچنین به معنای کار با ماتریسهای بزرگتر است و معمولاً بهینهسازی آنها روی GPU و TPU آسانتر است.
با این حال، همگرایی همچنان می تواند کمی آشفته باشد و حتی اگر بردار گرادیان صفر باشد، می تواند متوقف شود. آیا این بدان معناست که ما حداقلی را پیدا کرده ایم؟ نه همیشه. یک مولفه گرادیان می تواند بر روی حداقل یا حداکثر صفر باشد. با یک بردار گرادیان با میلیونها عنصر، اگر همه آنها صفر باشند، احتمال اینکه هر صفر با یک حداقل و هیچ یک از آنها به نقطه حداکثر مطابقت داشته باشد بسیار کم است. در فضایی با ابعاد مختلف، نقاط زین بسیار رایج هستند و ما نمی خواهیم در آنها توقف کنیم.
تصویر: یک نقطه زین. گرادیان 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] شبکه های عصبی کانولوشنال
به طور خلاصه
اگر تمام عبارات پررنگ در پاراگراف بعدی قبلاً برای شما شناخته شده است، می توانید به تمرین بعدی بروید. اگر به تازگی با شبکه های عصبی کانولوشنال شروع کرده اید، لطفاً ادامه مطلب را بخوانید.
تصویر: فیلتر کردن یک تصویر با دو فیلتر متوالی از 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'])
شبکه های عصبی کانولوشن 101
در لایهای از یک شبکه کانولوشن، یک «نرون» مجموع وزنی پیکسلها را درست بالای آن، فقط در ناحیه کوچکی از تصویر انجام میدهد. این یک سوگیری اضافه می کند و مجموع را از طریق یک تابع فعال سازی تغذیه می کند، درست همانطور که یک نورون در یک لایه متراکم منظم انجام می دهد. سپس این عمل در کل تصویر با استفاده از وزن های مشابه تکرار می شود. به یاد داشته باشید که در لایه های متراکم، هر نورون وزن مخصوص به خود را داشت. در اینجا، یک "پچ" از وزن ها در هر دو جهت روی تصویر می لغزند (یک "پیچیدگی"). مقدار خروجی به اندازه پیکسل های تصویر است (هر چند در لبه ها مقداری padding لازم است). این یک عملیات فیلتر است، با استفاده از فیلتر 4x4x3=48 وزن.
با این حال، 48 وزنه کافی نخواهد بود. برای افزودن درجات آزادی بیشتر، همین عمل را با یک مجموعه وزنه جدید تکرار می کنیم. این مجموعه جدیدی از خروجی های فیلتر را تولید می کند. بیایید آن را یک "کانال" از خروجی ها بر اساس قیاس با کانال های R,G,B در تصویر ورودی بنامیم.
دو (یا بیشتر) مجموعه وزن را می توان با افزودن یک بعد جدید به عنوان یک تانسور خلاصه کرد. این شکل کلی تانسور وزنه را برای یک لایه کانولوشن به ما می دهد. از آنجایی که تعداد کانالهای ورودی و خروجی پارامتر هستند، میتوانیم لایههای کانولوشنال را انباشته و زنجیرهای کنیم.
تصویر: یک شبکه عصبی کانولوشن "مکعب" داده را به "مکعب" دیگر داده تبدیل می کند.
پیچیدگی های راه راه، حداکثر تجمع
با انجام کانولوشن ها با گام 2 یا 3، می توانیم مکعب داده به دست آمده را در ابعاد افقی آن نیز کوچک کنیم. دو روش متداول برای انجام این کار وجود دارد:
- پیچیدگی راه راه: یک فیلتر کشویی مانند بالا اما با گام> 1
- حداکثر ادغام: یک پنجره کشویی که عملیات MAX را اعمال می کند (معمولاً در وصله های 2x2 که هر 2 پیکسل تکرار می شود)
تصویر: لغزاندن پنجره محاسباتی با 3 پیکسل منجر به مقادیر کمتر خروجی می شود. کانولوشن های راه راه یا حداکثر ادغام (حداکثر در یک پنجره 2x2 کشویی با گام 2) راهی برای کوچک کردن مکعب داده در ابعاد افقی است.
C طبقهبندیکننده متحرک
در نهایت، یک سر طبقه بندی را با صاف کردن آخرین مکعب داده و تغذیه آن از طریق یک لایه متراکم و فعال شده با softmax متصل می کنیم. یک طبقه بندی کانولوشنال معمولی می تواند به شکل زیر باشد:
تصویر: یک طبقهبندی کننده تصویر با استفاده از لایههای کانولوشنال و سافت مکس. از فیلترهای 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. [اطلاعات جدید] معماری های کانولوشنال مدرن
به طور خلاصه
تصویر: یک "ماژول" کانولوشن. چه چیزی در این مرحله بهترین است؟ یک لایه 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)
سایر ترفندهای ارزان قیمت
فیلترهای کوچک 3x3
در این تصویر، نتیجه دو فیلتر 3*3 متوالی را مشاهده می کنید. سعی کنید نقاط داده ای را که در نتیجه نقش داشته اند ردیابی کنید: این دو فیلتر 3x3 متوالی ترکیبی از یک منطقه 5x5 را محاسبه می کنند. این دقیقاً همان ترکیبی نیست که یک فیلتر 5x5 محاسبه می کند، اما ارزش امتحان کردن را دارد زیرا دو فیلتر 3x3 متوالی ارزان تر از یک فیلتر 5x5 منفرد هستند.
پیچش 1x1
از نظر ریاضی، یک کانولوشن "1x1" ضرب در یک ثابت است، مفهوم چندان مفیدی نیست. با این حال، در شبکههای عصبی کانولوشن، به یاد داشته باشید که فیلتر روی یک مکعب داده اعمال میشود، نه فقط یک تصویر دو بعدی. بنابراین، یک فیلتر "1x1" مجموع وزنی یک ستون 1x1 از داده ها را محاسبه می کند (تصویر را ببینید) و همانطور که آن را روی داده ها می کشید، ترکیبی خطی از کانال های ورودی به دست خواهید آورد. این در واقع مفید است. اگر کانالها را بهعنوان نتایج عملیات فیلتر کردن فردی در نظر بگیرید، بهعنوان مثال فیلتری برای «گوشهای نوکدار»، فیلتری دیگر برای «سبیلها» و سومی برای «چشمهای شکاف»، یک لایه کانولوشنال «1x1» در حال محاسبه چندگانه خواهد بود. ترکیبات خطی ممکن از این ویژگی ها، که ممکن است هنگام جستجوی یک "گربه" مفید باشد. علاوه بر این، لایه های 1x1 از وزنه های کمتری استفاده می کنند.
7. Squeezenet
یک راه ساده برای کنار هم قرار دادن این ایده ها در مقاله "Squeezenet" به نمایش گذاشته شده است. نویسندگان یک طرح ماژول کانولوشن بسیار ساده را پیشنهاد می کنند که تنها از لایه های کانولوشنال 1x1 و 3x3 استفاده می کند.
تصویر: معماری squeezenet بر اساس "ماژول های آتش". آنها یک لایه 1x1 را جایگزین می کنند که داده های دریافتی را در بعد عمودی "فشرده" می کند و به دنبال آن دو لایه کانولوشن 1x1 و 3x3 موازی که عمق داده ها را دوباره "بسط" می دهد.
دست در
در نوت بوک قبلی خود ادامه دهید و یک شبکه عصبی کانولوشنال الهام گرفته از squeezenet بسازید. شما باید کد مدل را به "سبک عملکردی" Keras تغییر دهید.
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 کاهش یابد زیرا مجموعه داده ما کوچک است. فعلا به این جزئیات اهمیت نده.
افزایش داده ها
شما با افزایش داده ها با تحولات آسان مانند تلنگر چپ و راست اشباع ، چند درصد بیشتر به دست می آورید:
این کار در TensorFlow با API tf.data.dataset بسیار آسان است. یک تابع تحول جدید را برای داده های خود تعریف کنید:
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 دوره باید در دسترس باشد.
راه حل
در اینجا نوت بوک راه حل است. اگر گیر کرده اید می توانید از آن استفاده کنید.
Keras_Flowers_TPU_squeezenet.ipynb
آنچه را پوشش داده ایم
- 🤔 مدل های "سبک کاربردی"
- 🤓 معماری Squeezenet
- 🤓 افزایش داده با tf.data.datset
لطفاً لحظه ای از این لیست چک را در ذهن خود طی کنید.
8. Xception خوب تنظیم شده است
پیچش های قابل تفکیک
اخیراً یک روش متفاوت برای اجرای لایه های حلقوی محبوبیت زیادی پیدا کرده است: پیچیدگی های قابل تفکیک. می دانم ، این یک لقمه است ، اما مفهوم بسیار ساده است. آنها در Tensorflow و Keras به عنوان tf.keras.layers.SeparableConv2D
اجرا می شوند.
یک حلقوی قابل جدا شدن همچنین یک فیلتر را روی تصویر اجرا می کند اما از مجموعه ای از وزنهای مشخص برای هر کانال از تصویر ورودی استفاده می کند. این با "1x1 Convolution" دنبال می شود ، یک سری از محصولات DOT که منجر به جمع وزنی کانال های فیلتر شده می شود. هر بار با وزنهای جدید ، به عنوان بسیاری از نوترکیب های وزنی کانال ها در صورت لزوم محاسبه می شوند.
تصویر: پیچش های قابل تفکیک. فاز 1: پیچش با یک فیلتر جداگانه برای هر کانال. فاز 2: نوترکیب خطی کانال ها. با مجموعه جدیدی از وزنه ها تکرار می شود تا تعداد مورد نظر کانال های خروجی حاصل شود. فاز 1 نیز می تواند تکرار شود ، با وزن های جدید هر بار اما در عمل به ندرت چنین است.
از پیچش های جداگانه در جدیدترین معماری های شبکه های حلقوی استفاده می شود: mobilenetv2 ، xception ، کارآمد. به هر حال ، mobilenetv2 همان چیزی است که قبلاً برای یادگیری انتقال استفاده کرده اید.
آنها ارزان تر از پیچش های معمولی هستند و به نظر می رسد که در عمل به همان اندازه مؤثر هستند. در اینجا تعداد وزن برای مثال نشان داده شده در بالا آمده است:
لایه حلقوی: 4 x 4 x 3 x 5 = 240
لایه حلقوی جداگانه: 4 x 4 x 3 + 3 x 5 = 48 + 15 = 63
این به عنوان یک تمرین برای خواننده باقی مانده است تا از تعداد ضرب های مورد نیاز برای استفاده از هر سبک از مقیاس لایه های حلقوی به روشی مشابه محاسبه کند. پیچش های قابل تفکیک کوچکتر و بسیار محاسباتی مؤثر هستند.
دست در
از نوت بوک زمین بازی "انتقال یادگیری" مجدداً راه اندازی کنید اما این بار Xception را به عنوان مدل از پیش آموزش انتخاب کنید. Xception فقط از پیچیدگی های قابل تفکیک استفاده می کند. تمام وزن ها را قابل آموزش بگذارید. ما به جای استفاده از لایه های از پیش آموزش داده شده به این ترتیب ، وزن های از پیش آموزش داده شده را روی داده های خود تنظیم خواهیم کرد.
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
برای به دست آوردن نتایج خوب هنگام تنظیم دقیق یک مدل ، باید به نرخ یادگیری توجه کنید و از یک برنامه نرخ یادگیری با یک دوره رمپ استفاده کنید. مثل این:
شروع با نرخ یادگیری استاندارد ، وزن های از پیش آموزش داده شده مدل را مختل می کند. شروع به تدریج آنها را حفظ می کند تا زمانی که مدل روی داده های شما بسته شود ، قادر به تغییر آنها به روشی معقول است. پس از سطح شیب دار ، می توانید با یک میزان یادگیری ثابت یا به صورت نمایی در حال فروپاشی ادامه دهید.
در کروس ، نرخ یادگیری از طریق پاسخ به تماس مشخص می شود که در آن می توانید نرخ یادگیری مناسب را برای هر دوره محاسبه کنید. Keras نرخ یادگیری صحیح را برای هر دوره به بهینه ساز منتقل می کند.
def lr_fn(epoch):
lr = ...
return lr
lr_callback = tf.keras.callbacks.LearningRateScheduler(lr_fn, verbose=True)
model.fit(..., callbacks=[lr_callback])
راه حل
در اینجا نوت بوک راه حل است. اگر گیر کرده اید می توانید از آن استفاده کنید.
07_Keras_Flowers_TPU_xception_fine_tuned_best.ipynb
آنچه را پوشش داده ایم
- 🤔 حلقوی عمیق
- 🤓 برنامه های نرخ یادگیری
- 😈 تنظیم دقیق یک مدل از پیش آموزش داده شده.
لطفاً لحظه ای از این لیست چک را در ذهن خود طی کنید.
9. تبریک!
شما اولین شبکه عصبی مدرن Convolutional خود را ساخته اید و آن را به 90 ٪ + دقت آموزش داده اید ، که فقط در چند دقیقه به لطف TPU ها در آموزش های پیاپی تکرار می شود. این نتیجه 4 "کروس در CodeLabs TPU" است:
- خطوط لوله داده سرعت TPU: tf.data.dataset و tfrecords
- اولین مدل Keras شما ، با یادگیری انتقال
- شبکه های عصبی Convolutional ، با Keras و TPU
- [این آزمایشگاه] Convnets مدرن ، Squeezenet ، Xception ، با Keras و TPU
TPU در عمل
TPU ها و GPU ها در پلت فرم Cloud AI موجود هستند:
- در یادگیری عمیق VM
- در نوت بوک های پلت فرم AI
- در مشاغل آموزش پلت فرم AI
سرانجام ، ما عاشق بازخورد هستیم. لطفاً اگر چیزی را در این آزمایشگاه می بینید یا فکر می کنید باید بهبود یابد ، به ما بگویید. بازخورد را می توان از طریق مسائل GitHub [ پیوند بازخورد ] ارائه داد.
|