מבוא למשתנים

הצג באתר TensorFlow.org הפעל בגוגל קולאב צפה במקור ב-GitHub הורד מחברת

משתנה TensorFlow הוא הדרך המומלצת לייצג מצב משותף ומתמשך שהתוכנית שלך מבצעת מניפולציות. מדריך זה מכסה כיצד ליצור, לעדכן ולנהל מופעים של tf.Variable ב-TensorFlow.

משתנים נוצרים ועוקבים אחריהם באמצעות המחלקה tf.Variable . tf.Variable מייצג טנסור שניתן לשנות את ערכו על ידי הפעלת אופציות עליו. פעולות ספציפיות מאפשרות לך לקרוא ולשנות את הערכים של טנזור זה. ספריות ברמה גבוהה יותר כמו tf.keras משתמשות ב- tf.Variable לאחסון פרמטרי מודל.

להכין

מחברת זו דנה במיקום משתנה. אם אתה רוצה לראות באיזה מכשיר ממוקמים המשתנים שלך, בטל את ההערה בשורה זו.

import tensorflow as tf

# Uncomment to see where your variables get placed (see below)
# tf.debugging.set_log_device_placement(True)

צור משתנה

כדי ליצור משתנה, ספק ערך התחלתי. ל- tf.Variable יהיה אותו dtype כמו ערך האתחול.

my_tensor = tf.constant([[1.0, 2.0], [3.0, 4.0]])
my_variable = tf.Variable(my_tensor)

# Variables can be all kinds of types, just like tensors
bool_variable = tf.Variable([False, False, False, True])
complex_variable = tf.Variable([5 + 4j, 6 + 1j])

משתנה נראה ומתנהג כמו טנזור, ולמעשה הוא מבנה נתונים המגובה ב- tf.Tensor . כמו טנסורים, יש להם dtype וצורה, וניתן לייצא אותם ל-NumPy.

print("Shape: ", my_variable.shape)
print("DType: ", my_variable.dtype)
print("As NumPy: ", my_variable.numpy())
Shape:  (2, 2)
DType:  <dtype: 'float32'>
As NumPy:  [[1. 2.]
 [3. 4.]]

רוב פעולות הטנזור עובדות על משתנים כצפוי, אם כי לא ניתן לעצב מחדש משתנים.

print("A variable:", my_variable)
print("\nViewed as a tensor:", tf.convert_to_tensor(my_variable))
print("\nIndex of highest value:", tf.argmax(my_variable))

# This creates a new tensor; it does not reshape the variable.
print("\nCopying and reshaping: ", tf.reshape(my_variable, [1,4]))
A variable: <tf.Variable 'Variable:0' shape=(2, 2) dtype=float32, numpy=
array([[1., 2.],
       [3., 4.]], dtype=float32)>

Viewed as a tensor: tf.Tensor(
[[1. 2.]
 [3. 4.]], shape=(2, 2), dtype=float32)

Index of highest value: tf.Tensor([1 1], shape=(2,), dtype=int64)

Copying and reshaping:  tf.Tensor([[1. 2. 3. 4.]], shape=(1, 4), dtype=float32)

כפי שצוין לעיל, משתנים מגובים על ידי טנזורים. אתה יכול להקצות מחדש את הטנזור באמצעות tf.Variable.assign . הקצאת קריאה אינה assign (בדרך כלל) טנזור חדש; במקום זאת, נעשה שימוש חוזר בזיכרון הטנזור הקיים.

a = tf.Variable([2.0, 3.0])
# This will keep the same dtype, float32
a.assign([1, 2]) 
# Not allowed as it resizes the variable: 
try:
  a.assign([1.0, 2.0, 3.0])
except Exception as e:
  print(f"{type(e).__name__}: {e}")
ValueError: Cannot assign to variable Variable:0 due to variable shape (2,) and value shape (3,) are incompatible

אם אתה משתמש במשתנה כמו טנזור בפעולות, אתה בדרך כלל תפעל על הטנזור הגיבוי.

יצירת משתנים חדשים ממשתנים קיימים משכפלת את הטנסורים התומכים. שני משתנים לא יחלקו את אותו זיכרון.

a = tf.Variable([2.0, 3.0])
# Create b based on the value of a
b = tf.Variable(a)
a.assign([5, 6])

# a and b are different
print(a.numpy())
print(b.numpy())

# There are other versions of assign
print(a.assign_add([2,3]).numpy())  # [7. 9.]
print(a.assign_sub([7,9]).numpy())  # [0. 0.]
[5. 6.]
[2. 3.]
[7. 9.]
[0. 0.]

מחזורי חיים, מתן שמות וצפייה

ב-TensorFlow מבוסס Python, למופע tf.Variable יש מחזור חיים זהה לאובייקטים אחרים של Python. כאשר אין הפניות למשתנה הוא מובטל אוטומטית.

ניתן גם לתת שם למשתנים שיכולים לעזור לך לעקוב אחריהם ולפתור אותם. אתה יכול לתת לשני משתנים את אותו השם.

# Create a and b; they will have the same name but will be backed by
# different tensors.
a = tf.Variable(my_tensor, name="Mark")
# A new variable with the same name, but different value
# Note that the scalar add is broadcast
b = tf.Variable(my_tensor + 1, name="Mark")

# These are elementwise-unequal, despite having the same name
print(a == b)
tf.Tensor(
[[False False]
 [False False]], shape=(2, 2), dtype=bool)

שמות משתנים נשמרים בעת שמירה וטעינת דגמים. כברירת מחדל, משתנים במודלים ירכשו שמות משתנים ייחודיים באופן אוטומטי, כך שאינך צריך להקצות אותם בעצמך אלא אם כן אתה רוצה.

למרות שמשתנים חשובים להתמיינות, לא יהיה צורך להבדיל בין משתנים מסוימים. אתה יכול לכבות מעברי צבע עבור משתנה על ידי הגדרה של trainable ל-false בעת היצירה. דוגמה למשתנה שלא יזדקק להדרגות היא מונה צעדי אימון.

step_counter = tf.Variable(1, trainable=False)

הצבת משתנים וטנסורים

לביצועים טובים יותר, TensorFlow ינסה למקם טנזורים ומשתנים במכשיר המהיר ביותר התואם ל- dtype שלו. המשמעות היא שרוב המשתנים ממוקמים ב-GPU אם קיים כזה.

עם זאת, אתה יכול לעקוף זאת. בקטע זה, הצב טנזור צף ומשתנה על המעבד, גם אם GPU זמין. על ידי הפעלת רישום מיקום המכשיר (ראה הגדרה ), תוכל לראות היכן המשתנה ממוקם.

אם אתה מפעיל את המחברת הזו בקצה עורפי שונים עם ובלי GPU, תראה רישום שונה. שים לב שיש להפעיל את מיקום מכשיר הרישום בתחילת הפגישה.

with tf.device('CPU:0'):

  # Create some tensors
  a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
  b = tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
  c = tf.matmul(a, b)

print(c)
tf.Tensor(
[[22. 28.]
 [49. 64.]], shape=(2, 2), dtype=float32)

אפשר להגדיר את המיקום של משתנה או טנזור במכשיר אחד ולבצע את החישוב במכשיר אחר. זה יציג עיכוב, מכיוון שיש להעתיק נתונים בין המכשירים.

עם זאת, אתה עשוי לעשות זאת אם היו לך מספר עובדי GPU אבל אתה רוצה רק עותק אחד של המשתנים.

with tf.device('CPU:0'):
  a = tf.Variable([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
  b = tf.Variable([[1.0, 2.0, 3.0]])

with tf.device('GPU:0'):
  # Element-wise multiply
  k = a * b

print(k)
tf.Tensor(
[[ 1.  4.  9.]
 [ 4. 10. 18.]], shape=(2, 3), dtype=float32)

למידע נוסף על הדרכה מבוזרת, עיין במדריך שלנו .

הצעדים הבאים

כדי להבין כיצד משתמשים בדרך כלל במשתנים, עיין במדריך שלנו בנושא בידול אוטומטי .