جشنواره فطر سون لرن

تعریف TENSOR و اجرای برنامه در محیط TENSORFLOW - آموزش TENSORFLOW - قسمت دوم

دسته بندی: یادگیری ماشین
زمان مطالعه: 12 دقیقه
۱۵ فروردین ۱۳۹۹

تعریف TENSOR و اجرای برنامه در محیط TENSORFLOW:

به‌منظور فهم بهتر کدهای TENSORFLOW بایستی معنی برخی مفاهیم بکار گرفته شده در این فریم ورک را یادآوری کنیم: (این مفاهیم در در قسمت اول از سری آموزش TENSORFLOW مقاله‌ی مفاهیم TENSORFLOW: تنسور و گراف محاسباتی - آموزش TENSORFLOW - قسمت اول به‌طور کامل تشریح شده‌اند. منظور از TF در این تعاریف، همان TensorFlow است.)

TF.Graph: بیانگر مجموعه‌ای از عملیات انجام یافته تحت عنوان Tf.Operation است. هر گره‌ای از گراف نشان‌دهنده‌ی اجرای عملیاتی بر روی TENSORها است.

TF.Operation: مجموعه‌ی عملیات اصلی که برای اجرای الگوریتم تعریف‌‌ کرده‌ایم.

TF.Tensor: ساختار داده‌ای که به عنوان ورودی تعریف می‌شود و یا نتایج در آن ذخیره می‌شوند.

نام فریم ورک TENSORFLOW از TENSOR گرفته شده‌ است. یک TENSOR بردار یا ماتریس n بُعدی است که شامل هر نوع داده‌ای می‌تواند باشد. تمامی مقادیر یک TENSOR نوع داده‌ی یکسان با یک shape (شکل) مشخص دارند. shape ابعاد آرایه یا ماتریس داده است. ورودی (های) هر عملیات، به صورت TENSOR(هایی) و خروجی‌(های) عملیات در گراف محاسباتی نیز با ساختار داده‌ی TENSOR است. برای کار در محیط TENSORFLOW باید با زبان برنامه نویسی پایتون در سطح مقدماتی آشنایی داشته‌ باشید. (برای آشنایی به زبان برنامه نویسی پایتون می‌توانید از آموزش‌های ارائه شده در سایت استفاده کنید.)

TENSORFLOW قابلیت پشتیبانی اجرا بر روی چندین CPU و GPU را به طور موازی دارد. همین اجرای غیرمتمرکز بر روی دستگاه‌ها منجر به افزایش سرعت اجرای الگوریتم‌های یادگیری مانند یادگیری عمیق خواهد شد و دیگر نیاز نیست زمان طولانی بر روی آن صرف شود. برای کاربران ویندوز، TENSORFLOW دو نسخه‌ی مختلف تدارک دیده‌ است:

  • TENSORFLOW با قابلیت پشتیبانی از فقط CPU: اگر کامپیوتر شما روی پردازنده‌های گرافیکی NVIDIA اجرا نمی‌شود، تنها می‌توانید از این گزینه برای نصب استفاده کنید.
  • TENSORFLOW با قابلیت پشتیبانی از GPU: برای محاسبات سریع‌تر می‌توانید از این نسخه‌ی TENSORFLOW استفاده کنید. این نسخه در صورت نیاز به ظرفیت محاسباتی قوی کاربرد دارد.

فریم ورک TENSORFLOW روی سیستم‌عامل‌های مختلف قابلیت‌های متفاوت دارد. بهتر است برای درک بهتر این موضوع و نصب متناسب با سیستم خود به سایت TENSORFLOW مراجعه کرده و نسخه‌ی متناسب با دستگاه خود را نصب و اجرا کنید.

فهرست محتوای این مقاله

انواع TENSORدر فریم ورک TENSORFLOW:

تمام محاسبات در TENSORFLOW روی یک یا چند TENSOR انجام می‌شود. هر TENSOR یک شی‌ با سه ویژگی است:

  1. برچسب منحصر بفرد (name)
  2. بُعد (shape)
  3. نوع داده (dtype)

 

چهار نوع TENSOR که می‌توان ایجاد کرد:

  1. Variable
  2. Constant
  3. Placeholder
  4. Sparsetensor

در مقاله‌ی تعریف TENSOR و اجرای برنامه در محیط TENSORFLOW، سه مورد اول را بررسی خواهیم‌ کرد.

ایجاد یک تنسور N‌ بُعدی:

یک روش برای ساخت یک TENSOR استفاده از ()tf.constant است. نحوه‌ی تعریف و توضیحات را در زیر ببینید:

tf.constant(value, dtype, name = "")

arguments:

  • "value": Value of n dimension to define the tensor. Optional
  • "dtype": Define the type of data:

                           - `tf.string`: String variable

                           - `tf.float32`: Float variable

                           - `tf.int16`: Integer variable

  • "name": Name of the tensor. Optional. By default: `Const_1:0`

برای ساخت یک TENSOR صفر بُعدی (نرده‌ای، اسکالر) به شکل زیر عمل می‌کنیم. البته لازم به یادآوری است که برای استفاده از کتابخانه ی TENSORFLOW دستور import tensorflow as tf را پیش از نوشتن قطعه کدها در این محیط می‌نویسیم.:

import tensorflow as tf
## rank 0
# Default name
r1 = tf.constant(1, tf.int16) 
print(r1)
Tensor("Const:0", shape=(), dtype=int16)

TENSOR یک بُعدی به شکل زیر تعریف می‌شود:

## Rank1 
r1_vector = tf.constant([1,3,5], tf.int16)
print(r1_vector)
r2_boolean = tf.constant([True, True, False], tf.bool)
print(r2_boolean)
Tensor("Const_3:0", shape=(3,), dtype=int16) Tensor("Const_4:0", shape=(3,), dtype=bool)
در TENSORیک بُعدی shape شامل یک مقدار است. برای TENSOR دو بُعدی بایستی بعد هر سطر از داده را در یک براکت قرار داد و یک براکت باز و بسته، بیش از حالت تک بُعدی به داده افزود. مثال زیر را ببینید:
## Rank 2
r2_matrix = tf.constant([ [1, 2],
                          [3, 4] ],tf.int16)
print(r2_matrix)
Tensor("Const_5:0", shape=(2, 2), dtype=int16)

خروجی ماتریس شامل دو سطر و دو ستون است که با مقادیر 1، 2، 3، 4 پر شده‌ است.

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

## Rank 3
r3_matrix = tf.constant([ [[1, 2],
                           [3, 4], 
                           [5, 6]] ], tf.int16)
print(r3_matrix)
Tensor("Const_6:0", shape=(1, 3, 2), dtype=int16)

این ماتریس سه سطر و دو ستون دارد. می‌توان یک TENSOR یک بُعدی (1D) با 10 عنصر ایجاد کردکه با صفر پر شده‌ باشد (تابع ()tf.zeros).

# Create a vector of 0
print(tf.zeros(10))
Tensor("zeros:0", shape=(10,), dtype=float32)

دستور بعدی ماتریسی با ابعاد 10*10 که با 1 پر شده را ایجاد می‌کند (تابع ()tf.ones).

# Create a vector of 1
print(tf.ones([10, 10]))
Tensor("ones:0", shape=(10, 10), dtype=float32)

ماتریس m_shape را با سه سطر و دو ستون که با اعداد 10 تا 15 پر شده را، به شکل زیر تعریف می‌کنیم و با دستور  shape. ابعاد را استخراج می‌کنیم:

# Shape of tensor
m_shape = tf.constant([ [10, 11],
                        [12, 13],
                        [14, 15] ]                      
                     ) 
m_shape.shape	
TensorShape([Dimension(3), Dimension(2)])

حال با دستورات زیر به ترتیب به تعداد سطر، ستون و کل اندازه‌ی ماتریس m_shape، تنسوری که با یک پر شده‌ باشد، ایجاد می‌کنیم:

# Create a vector of ones with the same number of rows as m_shape
print(tf.ones(m_shape.shape[0]))
# Create a vector of ones with the same number of column as m_shape
print(tf.ones(m_shape.shape[1]))
# Create a vector of ones with the same number of m_shape.shape
print(tf.ones(m_shape.shape))

هر TENSOR تنها می‌تواند شامل داده‌های هم‌نوع باشد. با دستور زیر نوع داده را می‌توان برگرداند:

print(m_shape.dtype)
<dtype: 'int32'>
همچنین نوع داده‌ی TENSORFLOW را با متد ()tf.cast می‌توان تغییر داد. در قطعه کد زیر نوع داده‌ی اعشاری به صحیح تبدیل می‌شود.
# Change type of data
type_float = tf.constant(3.123456789, tf.float32)
type_int = tf.cast(type_float, dtype=tf.int32)
print(type_float.dtype)
print(type_int.dtype)
<dtype: 'float32'> <dtype: 'int32'>

اگر آرگومان مربوط به نوع داده حین ایجاد TENSOR، تعیین نشود، TENSORFLOW به‌طور خودکار نوع آن را تعریف می‌کند. به‌طور مثال اگر داده‌ی متن داشته باشید، نوع آن را string درنظر می‌گیرد.

متغیرها در TENSORFLOW(Variables):

نحوه‌ی تعریف مقادیر ثابت در TENSORFLOW را با ()tf.constant دیدید. در الگوریتم‌ها داده‌ها معمولاً در مقادیر متغیر‌اند و برای تعریف آن‌ها در TENSORFLOW از کلاس Variable استفاده می‌کنیم. این کلاس در گراف محاسباتی گره ای را مشخص می‌کند که مقادیر آن تغییر می‌کنند. برای ایجاد یک متغیر از متد ()tf.get_variable  استفاده می‌کنیم. در ادامه‌ی مقاله‌ی تعریف TENSOR و اجرای برنامه در محیط TENSORFLOW نحوه‌ی بکارگیری و تعریف پارامترهای این متد را می‌بینید.

tf.get_variable(name = "", values, dtype, initializer)

argument:

  •  "name = "" ": Name of the variable
  •  "values": Dimension of the tensor
  •  "dtype": Type of data. Optional
  •  "initializer": How to initialize the tensor. Optional

If initializer is specified, there is no need to include the `values` as the shape of `initializer` is used.

به عنوان مثال، کد زیر متغیر دو بُعدی با دو مقدار تصادفی ایجاد می‌کند. به طور پیش‌فرض، TENSORFLOW یک مقدار تصادفی را برمی‌گرداند. نام متغیر را var گذاشتیم:

# Create a Variable
## Create 2 Randomized values
var = tf.get_variable("var", [1, 2])
print(var.shape)
(1, 2)

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

var_init_1 = tf.get_variable("var_init_1", [1, 2], dtype=tf.int32, initializer=tf.zeros_initializer)
print(var_init_1.shape)	
(1, 2)

می‌توانید مقادیر یک TENSOR ثابت را به یک متغیر اختصاص دهید. یک TENSOR با مقادیر ثابت با متد ()tf.constant ایجاد و به عنوان مقداردهی اولیه‌ی TENSOR متغیر از آن استفاده می‌کنیم. مقادیر اولیه‌ی متغیر 10، 20، 30 و 40 است و TENSOR متغیر یک ماتریس 2*2 است:

# Create a 2x2 matrixtensor_const = tf.constant([[10, 20],
[30, 40]])
# Initialize the first value of the tensor equals to tensor_const
var_init_2 = tf.get_variable("var_init_2", dtype=tf.int32,  initializer=tensor_const)
print(var_init_2.shape)
(2, 2)

Placeholder در TENSORFLOW:

می‌دانیم که TENSORFLOW برای انجام محاسبات الگوریتم‌های یادگیری ماشین طراحی شده‌ است. ورودی الگوریتم‌های یادگیری ماشین به‌طور کلی شامل سه نوع است: یکی آن ورودی‌هایی است که توسط کاربر الگوریتم در میزان مشخصی تعریف می‌شوند: مثل نرخ یادگیری، تعداد تکرار مراحل و ... . دسته‌ی بعدی متغیرهایی است که الگوریتم یادگیری ماشین آن‌ها را برای بهینه‌سازی جواب نهایی می‌تواند تغییر دهد و در TENSORFLOW آن‌ها را با عبارت tf.variable تعیین می‌کنند. در TENSORFLOW داده‌هایی که به الگوریتم به عنوان ورودی عملیاتی داده می‌شوند با tf.placeholder تعریف می‌شوند. برای درک بهتر موضوع placeholder را مانند عمل رزرو میز در یک رستوران در نظر بگیرید. فرض کنید که میزی را برای پنج نفر رزرو کرده‌اید (تخصیص فضا)، ولی درخصوص اینکه چه کسانی را همراه خود به رستوران ببرید، موضوعی اختیاری است (متغیری است که شما به ان مقدار اختصاص خواهید داد.). قاعده‌ی کلی تعریف این نوع به شکل زیر است:

tf.placeholder(dtype,shape=None,name=None )

arguments:

  • "dtype": Type of data
  • "shape": dimension of the placeholder. Optional. By default, shape of the data
  • "name": Name of the placeholder. Optional
data_placeholder_a = tf.placeholder(tf.float32, name = "data_placeholder_a")
print(data_placeholder_a)
Tensor("data_placeholder_a:0", dtype=float32)

مفهوم  Session در TENSORFLOW:

هر Session (جلسه یا نشست) عملیات گراف را اجرا خواهد کرد. برای مقداردهی گراف با TENSORهای متغیر، باید یک نشست باز کنید و در داخل آن عملیاتی برای تولید خروجی اجرا کنید. بیایید برای درک بهتر این مفهوم را با تشریح مثال ساده‌ی ضرب دو عدد شروع کنیم.

import tensorflow as tf
# Variables definition
x = tf.constant(6)  
y = tf.constant(8)
# Operations definition
result = tf.multiply(x, y)
print(result)
Tensor("Mul=0", shape=(), dtype=int32)
همان‌طور که می‌بینید نتیجه‌‌ عددی برنمی‌گرداند و فقط شبکه‌ای از TENSOR ایجاد شده‌ است. برای درک بهتر مسأله مثال رانندگی با اتومبیل را در نظر بگیرید. مثل این است که تا اینجای کار فقط قطعات اتومبیل مونتاژ شده‌اند و برای رسیدن به هدف طراحی این اتومبیل یعنی حرکت کردن، باید آن را روشن کرد. همین کار در TENSORFLOW معادل استفاده از مفهومی تحت عنوان Session یا نشست یا جلسه است.
sess = tf.Session() 
output = sess.run(result)  
print(output)
48

پس از اجرای عملیات session ایجاد شده را با دستور ()sess.close خاتمه می‌دهیم تا منابع اختصاص یافته به این نشست آزاد شوند. همان‌طور که مشاهده نمودید مراحل شامل ایجاد TENSOR برای ورودی، تعریف عملیات ضرب روی آن‌ها، ایجاد سشن و چاپ خروجی است. همان‌طور که در مقاله‌ی قبلی اشاره کردیم، در TENSORFLOW عملیات در قالب یک گراف محاسباتی انجام می‌پذیرد. گراف محاسباتی مجموعه‌ای از یک سری عملیات ریاضی است که در یک ترتیب خاصی محاسبه می‌شوند. برای مثال محاسبه‌ی عبارت e=c*d که در آن c= a+b و d=b-1 به فرم گراف زیر است:

 

این گراف دو ورودی a و b را می‌گیرد و خروجی e را می‌دهد. هر گره در این گراف ورودی(ها)‌یی را می‌گیرد و محاسباتی را انجام می‌دهد و خروجی‌(ها) را به گره بعدی می‌دهد. می‌توان این گراف محاسباتی را در TENSORFLOW به شکل زیر ایجاد کرد.

a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
c = tf.add(a, b)
d = tf.sub(b, 1)
e = tf.mul(c, d)

در کد بالا شما placeholder ای تحت عنوان a ایجاد کرده‌اید و فضایی به اندازه‌ی اعشار 32 بیتی به آن اختصاص داده‌اید. حال مقدار این a (که ساختار داده‌ی TENSOR دارد) برابر مقداری است که شما به‌عنوان داده‌ی ورودی گراف محاسباتی (یا همان داده‌ی آموزشی یک الگوریتم یادگیری ماشین) به آن اختصاص می‌دهید و خروجی الگوریتم یادگیری ماشین را براساس آن ارزیابی می‌کنید. اینکه حین تعریف placeholder‌ها آن را 64 بیتی یا 32 یا 16 بیتی در نظر بگیرید بسته به این دارد که فضای مصرفی و زمان اجرای برنامه اولویت است یا دقت خروجی، که اگر 32 بیت در نظر بگیرید به توازنی میان این دو معیار دست یافته‌ایم.

 with tf.Session() as session:
    a_data, b_data = 3.0, 6.0
    #feed_dict={data_placeholder_a: data}: Feed the placeholder with data
    feed_dict = {a: a_data, b:b_data}
    output = session.run([e], feed_dict=feed_dict)
    print(output)

پس از ایجاد یک session برای این گراف محاسباتی، مقداری که برای یک placeholder در ورودی گرفته می‌شود از طریق آرگومان feed_dict به گراف محاسباتی ارسال می‌شود و پس از اجرا خروجی مورد نظر یعنی 45 چاپ می‌شود.

اجرا روی پردازنده یا کارت گرافیکی:

ما می‌توانیم برای اینکه به TENSORFLOW نشان دهیم که چه دستگاه‌هایی را روی کامپیوتر ما برای اجرا می‌تواند انتخاب کند از دستور زیر استفاده کنیم تا لیست CPU و GPU‌های موجود را داشته باشیم:

from tensorflow.python.client import device_libdef get_available_devices():
    local_device_protos = device_lib.list_local_devices()
    return [x.name for x in local_device_protos]print(get_available_devices())
['/device:CPU:0', '/device:XLA_CPU:0', '/device:XLA_GPU:0', '/device:GPU:0']
اگر خروجی بالا را داشتیم، به‌طورمثال GPU0 را انتخاب می‌کنیم و ضرب [3,3] در [2,2] را که حاصل 3*2+3*2=12 است را به شکل قطعه کد زیر محاسبه می‌کنیم:
with tf.Session() as sess:
with tf.device("/GPU:0"):
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],[2.]])
product = tf.matmul(matrix1, matrix2)
output = sess.run(product)
print(output)

با دستور with tf.Session() as sess می‌توان به پایتون این امکان را داد که منابع Session را به‌طور خودکار آزاد کند.

دستور زیر یک TENSOR تک بُعدی (1D) با 64 مقدار را مابین 5- و 5+ را ایجاد می‌کند:

n_values = 64
x = tf.linspace(-5.0, 5.0, n_values)
sess = tf.Session()
result = sess.run(x)
print(result)

علاوه بر دستور ()sess.run می‌توان از (x.eval(session=sess برای ارزیابی TENSOR هم استفاده کرد و فراموش نکنیم که در پایان ()sess.close را بنویسیم. همچنین می‌توان از یک نشست تعاملی (Interactive Session) به جای ()run. استفاده نمود:

جمع‌بندی:

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

چه امتیازی به این مقاله می دید؟
نویسنده المیرا ناصح

نظرات کاربران

babak karimi

اول ممنون از به اشتراک گذاری این مفاهیم…..دوم اینکه خواستم کامل امتیاز ستاره ها رو بدم ولی دستم خورد فکر میکنم یک ستاره ثبت شد….ولی نظرم رو امتیازه کامله…

ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :