این صفحه به‌وسیله ‏Cloud Translation API‏ ترجمه شده است.
Switch to English

اشکال زدایی اشکال در تعداد عددی در برنامه های TensorFlow با استفاده از Debugger V2 TensorBoard

وقایع فاجعه آمیز که شامل NaN ها هستند ، ممکن است در طول یک برنامه TensorFlow اتفاق بیفتد ، و فرایندهای آموزش مدل را فلج کند. علت اصلی چنین وقایع اغلب مبهم است ، به خصوص برای مدل هایی با اندازه و پیچیدگی غیر بدیهی. برای ساده تر کردن اشکال زدایی در این نوع اشکالات مدل ، TensorBoard 2.3+ (همراه با TensorFlow 2.3+) یک داشبورد تخصصی به نام Debugger V2 ارائه می دهد. در اینجا نحوه استفاده از این ابزار را با استفاده از یک اشکال واقعی شامل NaN ها در یک شبکه عصبی که در TensorFlow نوشته شده است نشان می دهیم.

تکنیک های نشان داده شده در این آموزش برای سایر انواع فعالیت های اشکال زدایی مانند بازرسی اشکال تانسور در زمان اجرا در برنامه های پیچیده کاربرد دارد. این آموزش به دلیل فرکانس نسبتاً زیاد وقوع آنها روی NaN ها تمرکز دارد.

مشاهده اشکال

کد منبع برنامه TF2 که در صورت اشکال زدایی در GitHub موجود است . این برنامه همچنین در بسته لوله tensorflow (نسخه 2.3 و بالاتر) بسته بندی شده است و می توان از طریق آن فراخوانی شد:

 python -m tensorflow.python.debug.examples.v2.debug_mnist_v2
 

این برنامه TF2 یک درک چند لایه (MLP) ایجاد می کند و آن را برای تشخیص تصاویر MNIST آموزش می دهد. این مثال به صورت هدفمند از API سطح پایین TF2 برای تعریف سازه های لایه های سفارشی ، عملکرد از دست دادن و حلقه آموزش استفاده می کند ، زیرا احتمال وجود اشکالات NaN بیشتر هنگام استفاده از این API انعطاف پذیر اما دارای خطای بیشتر نسبت به زمان استفاده آسانتر است. برای استفاده اما API های سطح بالا کمی انعطاف پذیر مانند tf.keras .

این برنامه بعد از هر مرحله تمرین ، دقت تست را چاپ می کند. در کنسول می بینیم که دقت تست پس از اولین قدم در یک سطح نزدیک به احتمال (0.1 پوند) گیر می کند. این مطمئناً چگونگی رفتار مدل انتظار نمی رود: ما انتظار داریم که با افزایش مرحله ، دقت به تدریج به 1.0 (100٪) نزدیک شود.

 Accuracy at step 0: 0.216
Accuracy at step 1: 0.098
Accuracy at step 2: 0.098
Accuracy at step 3: 0.098
...
 

حدس تحصیل شده این است که این مشکل ناشی از بی ثباتی عددی مانند NaN یا بی نهایت است. با این حال ، چگونه این مسئله را تأیید می کنیم که واقعاً اینگونه است و چگونه عملیات TensorFlow (op) را که مسئول تولید ناپایداری عددی است ، می یابیم؟ برای پاسخ به این سؤالات ، بیایید برنامه اشکال را با Debugger V2 تنظیم کنیم.

ابزار دقیق کد TensorFlow با Debugger V2

tf.debugging.experimental.enable_dump_debug_info() نقطه ورود API Debugger V2 است. این برنامه یک برنامه TF2 با یک خط کد دارد. به عنوان مثال ، اضافه کردن خط زیر در نزدیکی آغاز برنامه ، باعث می شود که اطلاعات اشکال زدایی به فهرست (logdir) در / tmp / tfdbg2_logdir در فهرست ثبت شود. اطلاعات اشکال زدایی جنبه های مختلف زمان اجرای TensorFlow را در بر می گیرد. در TF2 ، تاریخچه کاملی از اجرای مشتاق ، ساختمان گرافیکی انجام شده توسط @ tf.function ، اجرای نمودارها ، مقادیر تانسور حاصل از وقایع اعدام و همچنین مکان کد (آثار پشته پایتون) از آن وقایع را شامل می شود. . غنای اطلاعات اشکال زدایی ، کاربران را قادر می سازد تا در مورد اشکالات مبهم محدود شوند.

 tf.debugging.experimental.enable_dump_debug_info(
    logdir="/tmp/tfdbg2_logdir",
    tensor_debug_mode="FULL_HEALTH",
    circular_buffer_size=-1)
 

آرگومان tensor_debug_mode کنترل می کند که Debugger V2 چه اطلاعاتی را از هر تانسور مشتاق یا در نمودار استخراج می کند. "FULL_HEALTH" روشی است که اطلاعات زیر را درمورد هر تنشور از نوع شناور ضبط می کند (به عنوان مثال ، float32 که معمولاً دیده می شود و نوع dfype کمتر از متداول bfloat16):

  • DType
  • رتبه
  • تعداد کل عناصر
  • تفکیک عناصر از نوع شناور به دسته های زیر: متناهی منفی ( - ) ، صفر ( 0 ) ، متناهی مثبت ( + ) ، بی نهایت منفی ( -∞ ) ، بی نهایت مثبت ( +∞ ) و NaN .

حالت "FULL_HEALTH" برای اشکال زدایی اشکالات مربوط به NaN و بینهایت مناسب است. در زیر برای سایر tensor_debug_mode s پشتیبانی شده tensor_debug_mode .

آرگومان circular_buffer_size کنترل می کند که چگونه بسیاری از رویدادهای تانسور در لوژ ذخیره می شوند. این پیش فرض به 1000 می رسد ، که باعث می شود تا آخرین 1000 تنسور قبل از پایان برنامه TF2 سازنده در دیسک ذخیره شود. این رفتار پیش فرض با استفاده از قربانی کامل کامل اشکال زدایی داده ، اشکال زدایی را کاهش می دهد. اگر کامل بودن ترجیح داده شود ، مانند این حالت ، می توانیم با تنظیم آرگومان بر روی مقدار منفی ، بافر دایره ای را غیرفعال کنیم (مثلاً -1 در اینجا).

مثال enable_dump_debug_info() با عبور از پرچم های خط فرمان به آن ، enable_dump_debug_info() فراخوانی می کند. برای اجرای دوباره برنامه TF2 مشکل دار ما با استفاده از این ابزار دقیق اشکال زدایی ،

 python -m tensorflow.python.debug.examples.v2.debug_mnist_v2 \
    --dump_dir /tmp/tfdbg2_logdir --dump_tensor_debug_mode FULL_HEALTH
 

شروع Debugger V2 GUI در TensorBoard

اجرای برنامه با ابزار debugger ، logdir را در / tmp / tfdbg2_logdir ایجاد می کند. می توانیم TensorBoard را شروع کنیم و در logdir با آن اشاره کنیم:

 tensorboard --logdir /tmp/tfdbg2_logdir
 

در مرورگر وب ، به صفحه TensorBoard در http: // localhost: 6006 بروید. افزونه "Debugger V2" باید بصورت پیش فرض فعال شود و صفحه ای را نشان دهد که به صورت زیر است:

Debugger V2 تصویر نمای کامل

با استفاده از Debugger V2 GUI برای یافتن علت اصلی NaN ها

Debugger V2 GUI در TensorBoard در شش بخش سازماندهی شده است:

  • هشدارها : این بخش از سمت چپ حاوی لیستی از رویدادهای "هشدار" است که توسط اشکال زدایی در داده های اشکال زدایی از برنامه سازهای TensorFlow تولید شده است. هر هشدار نشان دهنده ناهنجاری خاصی است که توجه را جلب می کند. در مورد ما ، این بخش رویدادهای 499 NaN / with با رنگ برجسته صورتی و قرمز را برجسته می کند. این تصور ما را تأیید می کند که این مدل به دلیل وجود NaN ها و / یا بی نهایت در مقادیر داخلی تنش ، قادر به یادگیری نیست. ما به زودی به این هشدارها خواهیم پرداخت.
  • جدول زمانی زمان اجرای Python : این قسمت نیمه بالایی قسمت بالای وسط است. این تاریخچه کامل اجرای مشتاق گزینه ها و نمودارها را ارائه می دهد. هر جعبه جدول زمانی با حرف اولیه نام op یا نمودار مشخص می شود (به عنوان مثال ، "T" برای "TensorSliceDataset" ، "m" برای عملکرد "مدل" tf.function ). ما می توانیم با استفاده از دکمه های ناوبری و نوار پیمایش بالای جدول زمانی ، این جدول زمانی را مرور کنیم.
  • نمودار اجرای : این بخش در گوشه بالا و سمت راست رابط کاربری گرافیکی (GUI) واقع شده است ، وظیفه اشکال زدایی ما اصلی است. این شامل تاریخچه ای از تمام تنش های شناور dtype است که در نمودارها محاسبه می شود (یعنی توسط @tf-function ).
  • ساختار نمودار (نیمی از قسمت بالای قسمت بالا) ، منبع کد (بخش پایین سمت چپ) و Stack Trace (بخش پایین سمت راست) در ابتدا خالی هستند. هنگامی که با GUI تعامل می کنیم ، محتوای آنها جمع می شود. این سه بخش همچنین نقش مهمی در وظیفه اشکال زدایی ما ایفا خواهد کرد.

پس از اینکه خود را به سازمان UI گرایش دادیم ، بیایید مراحل زیر را برای رسیدن به دلیل ظاهر شدن NaNs برداریم. ابتدا در قسمت Alerts روی هشدار NaN / click کلیک کنید. این به طور خودکار لیستی از 600 تنسور گراف را در بخش اجرای نمودار جابجا می کند و بر روی شماره 88 تمرکز می کند ، که یک تانسور به نام "Log: 0" است که توسط یک Log (logarithm طبیعی) تولید شده است. یک رنگ برجسته صورتی و قرمز برجسته یک عنصر -∞ را در بین 1000 عنصر تانسور float32 2D نشان می دهد. این اولین تنسور در تاریخ زمان اجرای برنامه TF2 است که حاوی NaN یا بی نهایت است: تنسورهای محاسبه شده قبل از آن شامل NaN یا ∞ نیستند. بسیاری از (در واقع ، بیشتر) تنسورهایی که پس از آن محاسبه می شوند حاوی NaN هستند. ما می توانیم با پیمایش به بالا و پایین لیست اجرای نمودار ، این را تأیید کنیم. این مشاهدات یک اشاره قوی را نشان می دهد که Log op منبع ناپایداری عددی در این برنامه TF2 است.

Debugger V2: هشدارهای نان / بی نهایت و لیست اجرای نمودار

چرا این Log op یک -it می کند؟ پاسخ به این سؤال مستلزم بررسی ورودی به گزینه است. با کلیک بر روی نام تانسور ("ورود: 0") تجسم ساده اما آموزنده ای از مجاورت Log op را در نمودار TensorFlow در بخش Graph Structure ارائه می دهیم. توجه داشته باشید جهت بالا به پایین جریان اطلاعات. خود عملكرد با جسورانه در وسط نشان داده شده است. بلافاصله بالاتر از آن ، می توانیم ببینیم که یک Place Placeer op یک و تنها ورودی را برای Log به Log فراهم می کند. تانسور تولید شده توسط این ورود به سیستم در لیست گرافیک نمودار کجاست؟ با استفاده از رنگ پس زمینه زرد به عنوان یک کمک بصری ، می توانیم مشاهده کنیم که logits:0 tensor دو ردیف بالاتر از تانسور Log:0 است ، یعنی در ردیف 85.

Debugger V2: نمای ساختار نمودار و ردیابی به تانسور ورودی

یک نگاه دقیق تر به شکست عددی تانسور "logits: 0" در ردیف 85 نشان می دهد که چرا مصرف کننده آن Log:0 a -∞ را تولید می کند: در بین 1000 عنصر "logits: 0" ، یک عنصر دارای ارزش 0 است. -∞ نتیجه محاسبه لگاریتم طبیعی 0 است! اگر به نحوی بتوانیم اطمینان حاصل کنیم که Log op فقط در معرض ورودی های مثبت قرار می گیرد ، می توانیم از وقوع NaN / prevent جلوگیری کنیم. این کار را می توان با استفاده از قطع (به عنوان مثال ، با استفاده از tf.clip_by_value () ) در Tencor logits Place Place انجام داد.

ما به حل اشکال نزدیکتر می شویم ، اما هنوز کاملاً انجام نشده است. برای استفاده از رفع ، باید بدانیم که در کد منبع پایتون Log OP و ورودی Placeholder آن از کجا سرچشمه گرفته است. Debugger V2 برای ردیابی نمودارهای گرافیکی و وقایع اجرای برنامه ، از پشتیبانی کلاس اول پشتیبانی می کند. هنگامی که در نمودار Executions روی Tensor Log:0 کلیک کردیم ، قسمت Stack Trace با اثری از پشته اصلی ایجاد Log log جمع شد. رد پشته تا حدودی بزرگ است زیرا شامل فریم های زیادی از کد داخلی TensorFlow است (به عنوان مثال gen_math_ops.py و dumping_callback.py) ، که با اطمینان می توان اکثر کارهای اشکال زدایی را نادیده گرفت. قاب مورد علاقه خط 216 از debug_mnist_v2.py است (یعنی پرونده پایتون که در واقع سعی در رفع اشکال آن داریم). با کلیک بر روی "خط 204" نمای مربوط به خط کد مربوطه در بخش Source Code نمایش داده می شود.

Debugger V2: کد منبع و رد پشته

این در نهایت ما را به کد منبع مبدل می کند که Log problematic log را از ورودی logs آن ایجاد کرده است. این تابع از دست دادن @tf.function متقاطع دسته ای سفارشی ما تزئین شده با عملکرد @tf.function و از این رو به یک نمودار @tf.function تبدیل شده است. گزینه "ورود" با نخستین ورودی ورودی به عملکرد ضرر مطابقت دارد. Log op با تماس tf.math.log () API ایجاد می شود.

رفع ارزش برای این اشکال چیزی شبیه به:

   diff = -(labels *
           tf.clip_by_value(tf.math.log(logits), 1e-6, 1.))
 

این عدم ثبات عددی را در این برنامه TF2 برطرف می کند و باعث می شود MLP با موفقیت آموزش یابد. روش دیگر ممکن برای رفع ناپایداری عددی استفاده از tf.keras.losses.CategoricalCrossentropy .

این نتیجه سفر ما از مشاهده یک اشکال مدل TF2 تا بروز یک تغییر کد است که به رفع اشکال می انجامد و به کمک ابزار Debugger V2 کمک می کند و این باعث می شود دید کاملی به تاریخچه مشتاق و نمودار اجرای برنامه TF2 سازنده از جمله خلاصه های عددی ارائه شود. مقادیر تانسور و ارتباط بین گزینه ها ، تنشورها و کد منبع اصلی آنها.

سازگاری سخت افزاری Debugger V2

Debugger V2 از سخت افزار آموزش اصلی شامل CPU و GPU پشتیبانی می کند. آموزش چند GPU با tf.distributed.MirroredStrategy نیز پشتیبانی می شود. پشتیبانی TPU هنوز در مرحله اولیه است و نیاز به تماس دارد

 tf.config.set_soft_device_placement(True)
 

قبل از تماس با enable_dump_debug_info() . این ممکن است محدودیت های دیگری نیز در TPU داشته باشد. اگر با استفاده از Debugger V2 با مشکل روبرو شدید ، اشکالات را در صفحه شماره GitHub ما گزارش دهید.

سازگاری API از Debugger V2

Debugger V2 در سطح نسبتاً کم پشته نرم افزار TensorFlow پیاده سازی می شود و از این رو با tf.keras ، tf.data و سایر API های ساخته شده در بالای سطوح پایین تر TensorFlow سازگار است. Debugger V2 با TF1 با عقب سازگار است ، اگرچه جدول زمانی اجرای Eager برای اجرای اشکال زدایی های ایجاد شده توسط برنامه TF1 خالی خواهد بود.

نکات مربوط به کاربرد API

سوالی که اغلب در مورد این API اشکال زدایی پرسیده می شود این است که در کد enable_dump_debug_info() باید تماس را برای enable_dump_debug_info() . به طور معمول ، برنامه API باید در اسرع وقت در برنامه TF2 شما ، ترجیحا پس از خطوط واردات پایتون و قبل از شروع ساخت و اجرای نمودار فراخوانی شود. این کار با پوشش کامل تمام گزینه ها و نمودارهایی که از مدل شما و آموزش آن استفاده می کنند ، اطمینان خواهد یافت.

tensor_debug_mode پشتیبانی شده در حال حاضر عبارتند از: NO_TENSOR ، CURT_HEALTH ، CONCISE_HEALTH ، FULL_HEALTH و SHAPE . آنها در مقدار اطلاعاتی که از هر تانسور استخراج می شود و عملکرد اصلی آن برای برنامه اشکال زدایی متفاوت است. لطفاً به بخش enable_dump_debug_info() کنید.

عملکرد بالا

API اشکال زدایی عملکرد اصلی را به برنامه سازهای TensorFlow معرفی می کند. سربار با توجه به tensor_debug_mode ، نوع سخت افزار و ماهیت برنامه ساز TensorFlow متفاوت است. به عنوان یک نقطه مرجع ، در یک GPU ، حالت NO_TENSOR در طول آموزش یک مدل ترانسفورماتور در اندازه دسته 64 ، سربار 15٪ اضافه می کند. درصد سربار برای سایر tensor_debug_mode بیشتر است: تقریباً 50٪ برای CURT_HEALTH ، CONCISE_HEALTH ، FULL_HEALTH و SHAPE حالت ها. در پردازنده ها ، سربار کمی پایین تر است. در TPU ها ، سربار در حال حاضر بالاتر است.

رابطه با سایر API های اشکال زدایی TensorFlow

توجه داشته باشید که TensorFlow ابزار و API های دیگری را برای اشکال زدایی ارائه می دهد. می توانید چنین API هایی را در زیر tf.debugging.* فضای نام در صفحه اسناد API مرور کنید. در میان این API ها که بیشتر مورد استفاده قرار می گیرد tf.print() . چه زمانی باید از Debugger V2 استفاده کرد و چه موقع باید از tf.print() استفاده کرد؟ tf.print() در مواردی که مناسب باشد مناسب است

  1. ما دقیقاً می دانیم که کدام طناب برای چاپ ،
  2. ما می دانیم که دقیقاً در کد منبع برای قرار دادن آن tf.print() ،
  3. تعداد چنین تنش زیاد نیست.

برای موارد دیگر (به عنوان مثال ، بررسی بسیاری از مقادیر تانسور ، بررسی مقادیر تانسور تولید شده توسط کد داخلی TensorFlow ، و جستجوی منشأ ناپایداری عددی همانطور که در بالا نشان دادیم) ، Debugger V2 راهی سریعتر برای اشکال زدایی فراهم می کند. علاوه بر این ، Debugger V2 یک رویکرد یکپارچه برای بازرسی از تنشورهای مشتاق و نمودار ارائه می دهد. علاوه بر این ، اطلاعاتی در مورد ساختار نمودار و مکان های کد ، که فراتر از قابلیت tf.print() فراهم می کند.

API دیگری که می تواند برای اشکالزدایی درمورد موضوعات مربوط به tf.debugging.enable_check_numerics() و NaN استفاده شود tf.debugging.enable_check_numerics() . بر خلاف enable_dump_debug_info() ، enable_check_numerics() اطلاعات اشکال زدایی را روی دیسک ذخیره نمی کند. در عوض ، آن را صرفاً مانیتور ∞ و NaN در زمان اجرا TensorFlow می کند و به محض این که هر گزینه ای چنین مقادیر عددی بدی ایجاد کند ، در محل کد منبع خطا می کند. این عملکرد در مقایسه با enable_dump_debug_info() عملکرد پایین enable_dump_debug_info() ، اما اثری از سابقه اجرای برنامه را در اختیار ندارد و با رابط کاربری گرافیکی مانند Debugger V2 همراه نیست.