بلاگ

کدنویسی کارآمد در تنسورفلو 2.0: روش ایده آل و تغییرات

کدنویسی کارآمد در تنسورفلو 2.0: روش ایده آل  و تغییرات

به خاطر نیاز به بازنویسی برخی از کتابخونه ها تصمیم گرفتم یکم سر موارد تنسورفلو ۲ رو مطالعه کنم و در این راستا توی رپو مربوطه میتونید برخی از نتایج رو ببینید.

https://github.com/moaminsharifi/SeqGAN

مشکل کجا بود؟

برخی از مقالات با استفاده از tensorflow 1.x و پایتون 2.7 پیاده سازی ها رو انجام داده بودند و نه به بهترین شیوه ممکن از مفاهیم کلاس و شی گرایی و موارد دیگر پایتون استفاده کرده بودند تقریبا یک سال بعد از رلیز نهایی نسخه دوم تنسورفلو مسئله بزرگی به وجود اومد. چطوری کد های نسخه یک رو توی نسخه دوم اجرا کنیم؟

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

خیلی از مواردی که در نسخه اول به سادگی امکان پذیر بودند در نسخه دوم عملا وجود ندارد با گشتن متوجه شدم یک پست از تیم تنسورفلو هستش تصمیم گرفتم برای یادگیری خودم این رو ترجمه کنم.

و هر موردی که به نظرم هم میرسه بهش اضافه کنم.

وارد ترجمه بشیم:

Effective TensorFlow 2.0: Best Practices and What’s Changed

در مقاله اخیر ما ذکر کردیم که تنسورفلو ۲ باز طراحی شده با توجه به تمرکز بر بهره وری توسعه دهندگان (productivity) , سادگی (simplicity) و راحتی از استفاده (ease of use).

برای اینکه نگاهی دقیق به تغییرات داشته باشیم  و روش های ایده آل (best practices) بررسی کنید راهنمای Effective TensorFlow 2.0 را در گیتهاب . در این مقاله یک خلاصه سریع از محتوایی که انجا پیدا میکنید ارائه می دهیم.

 

یک خلاصه مختصر از تغییرات اصلی

 

تغییرات زیادی در نسخه دوم تنسورفلو وجود دارد  تا کاربران بهره وری بیشتری داشته باشند, شامل حذف API اضافی,  ساخت API سازگار تر (Unified RNNs, Unified Optimizers) و ادغام (integrating) بهتر با ران تایم پایتون با Eager execution.

خیلی از  RFC ها ـ درخواست نظر های عمومی برای مواردی ـ ( اگر که تازه وارد هستید اونها رو بررسی کنید) توضیح دادند تغییرات و افکار پشت ساختن نسخه دوم تنسورفلو. 

 

تمیز سازی API

خیلی از API ( رابط کاربری برنامه نویسی) از بین رفته اند یا جا به جا شدند در  TF 2.0 و برسی جایگزین شدند با معادلاتشان در نسخه دوم -  tf.summary, tf.keras.metrics, and tf.keras.optimizers .  ساده ترین راه برای ایجاد این تغییر اسم ها استفاده از  v2 upgrade script است.

** اضافات مترجم:

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

 

Eager execution - اجرای مشتاقانه (؟)

در Tensorflow 1.x ( نسخه های اول تنسورفلو) نیازمند این بود که کاربران به صورت دستی تنظیم کنند یک abstract syntax tree یا همان گراف اجرای دستورات را با فراخوانی api  های  tf.*  انجام میداد. نیازمند این بود که کاربران به صورت دستی abstract syntax tree را فرستادن ( passing)  خروجی و وردی تنسور ها به session.run  کامپایل کند.

در مقابل نسخه دوم Tensorflow به صورت eagerly  (اشتیاق) (مانند کاری که پایتون به صورت عادی انجام میدهد) اجرا میشود. در نسخه دوم  تنسورفلو گراف ها و sessions باید شبیه جزئیات تغییرات باشند. 

 

No more globals - نه به (فضا نام های ) گلوبال 

تنسورفلو نسخه اول به شدت به فضا نام های global متکی بودش. وقتی که شما tf.Variable() را فراخوانی میکردید, آن ممکن است که در یک گراف پیش فرض قرار دهد  و ممکن است آنجا باقی بماند حتی اگر شما در پایتون دسترسی به متغیر را از دست بدهید ( ** مثلا متغیر بعد از اجرای اون تابع در استک پاک شود).

 

در Tensorflow 2.0  تمام این مکانیزم ها از بین رفتن (‌Variables 2.0 RFC) به نفع مکانیزم پیشفرض: حواستون به متغیرها باشه اگر که پیگیری یک tf.Variable را از دست دهید توسط garbage collector جمع آوری میشود.

 

Functions, not sessions - بله به فانکشن نه به سشن

یک فراخوانی session.run تقریبا شبیه یک فراخوانی تابع است: شما ورودی و تابعی که باید اجرا شود را تعیین می کنید و یک سری خروجی میگیرید. در نسخه دوم تنسورفلو شما با استفاده از decorate ( اشاره دارد به python decorator) یک تابع پایتون با استفاده از tf.function  میتونید بسازید  JIT compilation را که تنسورفلو اجرا میکند آن را توی یک گراف انفرادی (Functions 2.0 RFC).

این مکانیزم به تنسورفلو ۲ اجازه میدهد تمام قابلیت های حالت گراف را برسد:

  • کارایی: این توابع میتوانند بهینه شوند  (node pruning, kernel fusion, etc.)
  • قابلیت حمل (Portability) : این توابع میتوانند خروجی گرفته شوند یا مجددا بارگزاری شوند exported/reimported (SavedModel 2.0 RFC) این اجازه را میدهد به کاربران که مجددا  استفاده کنند و به اشتراک بگذارند توابع TensorFlow را.

با قدرت آزادانه   intersperse کد پایتون و تنسورفلو شما میتوانید بهره ببرید از سودمندی بیانگری پایتون. (** اینجا منظور این است که هم خدا رو دارید هم خرما رو ). اما نسخه پرتابل تنسورفلو اجرا میشود  بدون توجه به مفسر پایتون , موبایل , سی پلاس پلاس و جاوا اسکریپت. برای کمک به کاربران که که از بازنویسی کدهایشان وقتی که @tf.function  استفاده میکنند , AutoGraph  ساختار پایتون رو به ساختار معادل در تنسورفلو تبدیل میکند.

این راهنما رو برای جزئیات بیشتر ببینید.

 

** تا اینجا درباره تغییرات از نسخه اول به نسخه دوم صحبت کردیم حالا درباره نسخه دوم و بخش اینکه چطوری بهتر و شیوا تر بنویسیم صحبت میکنه مقاله.

 

پیشنهادات برای شیوایی کد در تنسورفلو 2.0

**بازنویسی کدتان به توابع کوچک تر -**Refactor your code into smaller functions

** واژه kitchen sink رو بهتره دربارش در گیت هاب بخونید.

یک الگوی استفاده توی نسخه اول تنسورفلو استراتژی kitchen sink بودش, جایی که  همه نوع احتمال محاسباتی امکان پذیر بودش سپس tensor های انتخابی توسط  session.run اجرا میشدش. توی نسخه دوم تنسورفلو کاربران باید کد خودشون رو بازنویسی کنند به توابع کوچک تر بر اساس نیاز. به صورت کلی نیازی نیستش که توابع کوچک تر را با استفاده از دکریتور tf.function کنید بلکه از tf.function رو برای پردازش های سطح بالا استفاده کنید برای مثال یک بخش از آموزش یا  forward pass مدلتان.

 

استفاده از لایه های کراس و مدل ها برای مدیریت متغیرها - Use Keras layers and models to manage variables

مدل ها و لایه های کراس به شما متغیرها و متغیرهای آموزشی خوبی رو پیشنهاد میدهند  که به صورت بازگشتی (recursively) تمام تغییر های وابسته را جمع آوری میکند. با این کار مدیریت متغیر های محلی از جایی که استفاده می شود راحتر میشود.لایه ها / مدل کراس ارث بری شده (inherit) است از tf.train.Checkpointable و ادغام (integrated) با @tf.function که با این کار امکان چک پوینت یا خروجی مدل از اشیای کراس امکان پذیر میکند. شما هیچ الزامی به استفاده از API  های fit() کراس برای بهره وری از این اقدام نمیباشد.

 

راهنما را برای جزئیات بیشتر ببینید

ترکیب tf.data.Datasets و @tf.function

وقتی پیشمایش می کنید روی داده هایی که در حافظه ( RAM‌ ) قرار میگیرند میتونید راحت باشید از استفاده از پیمایش پایتونی. در غیر این صورت ( وقتی حجم داده ها در RAM قرار نگیرد) tf.data.Dataset بهترین راه برای جریان داده های آموزشی از دیسک ( HDD یا SSD ) است. دیتاست ها قابل پیشمایش iterables (not iterators) و مثل بقیه قابل پیشماش های (iterables) پایتون توی حالت اشتقاق Eager استفاده کرد. شما میتوانید به صورت کامل دیتاست ناهمزمان (async)  با ویژگی های prefetching/streaming  با wrapping کدتان در tf.function استفاده کنید. ( یکم خط بدی شدش منظور اینه که با استفاده از tf.function این قابلیت ها رو دارید.) که جایگزین پیشمایش پایتونی شما با معادل عملیات گراف با استفاده از AutoGraph است.

 

اگر که شما از API .fit کراس استفاده میکنید نیازی نیست نگران پیمایش دیتاست خود باشد.

 

بهره گیری از فواید AutoGraph در کنترل جریان پایتون

Take advantage of AutoGraph with Python control flow

قابلیت AutoGraph به ما این امکان را میدهد کنترل جریان داده های وابسته  را به معادل گرافشون تبدیل مثل مثل tf.cond  و  tf.while_loop .

یک جایی که کنترل جریان داده های وابسته نمایان میشود در مدل های ترتیبی (sequence models) است. tf.keras.layers.RNN یک رپ (wrap) از سلول RNN است که این اجازه را میدهد که چه به صورت استاتیک یا داینامک بازشگت را unroll کرد. (** بهتره که این مورد رو کد و راهنما رو بخونید چون برای خودمم خیلی واضح نیستش) برای مثال شما میتونید داینامیک unroll رو به صورت زیر باز پیاده سازی کنید:

راهنما را برای جزئیات بیشتر ببینید.

 

 

استفاده از tf.metrics برای جمع اوری داده ها و tf.summary برای لاگ انها

Use tf.metrics to aggregate data and tf.summary to log it

در نهایت یک مجموع از سیمبل های  tf.summary به زودی می آیند. شما میتوانید نسخه دوم tf.summary را با استفاده :

 

راهنما را برای جزئیات بیشتر ببینید.

قدم های بعدی

این مقاله یک خلاصه سریع از راهنمای کارآمدی در TF  2.0 بود ( اگر به این مباحث علاقندید برید بخونیدش تا بیشتر یاد بگیرید) همچنین برای یادگیری بیشتر در زمینه تنسورفلوی ۲ این مقالات اخیر رو پیشنهاد میدهدم ( ** به زبان انگلیسی و از منبع)

منبع اصلی: https://blog.tensorflow.org/2019/02/effective-tensorflow-20-best-practices.html