יסודות התאמה אישית: טנזורים ופעולות

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

זהו מדריך מבוא של TensorFlow שמראה כיצד:

  • ייבא את החבילה הנדרשת
  • צור והשתמש בטנסורים
  • השתמש בהאצת GPU
  • הדגימו tf.data.Dataset

ייבוא ​​TensorFlow

כדי להתחיל, ייבא את מודול tensorflow . החל מ-TensorFlow 2, ביצוע להוט מופעל כברירת מחדל. זה מאפשר חזית אינטראקטיבית יותר ל- TensorFlow, שעל פרטיו נדון הרבה יותר מאוחר.

import tensorflow as tf

טנזורים

Tensor הוא מערך רב מימדי. בדומה לאובייקטי ndarray , לאובייקטי tf.Tensor יש סוג נתונים וצורה. בנוסף, tf.Tensor s יכולים להימצא בזיכרון מאיץ (כמו GPU). TensorFlow מציעה ספרייה עשירה של פעולות ( tf.add , tf.matmul , tf.linalg.inv וכו') שצורכות ומייצרות tf.Tensor s. פעולות אלו ממירות אוטומטית סוגי Python מקוריים, לדוגמה:

print(tf.add(1, 2))
print(tf.add([1, 2], [3, 4]))
print(tf.square(5))
print(tf.reduce_sum([1, 2, 3]))

# Operator overloading is also supported
print(tf.square(2) + tf.square(3))
tf.Tensor(3, shape=(), dtype=int32)
tf.Tensor([4 6], shape=(2,), dtype=int32)
tf.Tensor(25, shape=(), dtype=int32)
tf.Tensor(6, shape=(), dtype=int32)
tf.Tensor(13, shape=(), dtype=int32)

לכל tf.Tensor יש צורה וסוג נתונים:

x = tf.matmul([[1]], [[2, 3]])
print(x)
print(x.shape)
print(x.dtype)
tf.Tensor([[2 3]], shape=(1, 2), dtype=int32)
(1, 2)
<dtype: 'int32'>

ההבדלים הברורים ביותר בין מערכי NumPy ל- tf.Tensor s הם:

  1. ניתן לגבות טנזורים בזיכרון מאיץ (כמו GPU, TPU).
  2. הטנזורים אינם ניתנים לשינוי.

תאימות NumPy

המרה בין TensorFlow tf.Tensor s ל- ndarray היא קלה:

  • פעולות TensorFlow ממירות אוטומטית את NumPy ndarrays ל Tensors.
  • פעולות NumPy ממירות אוטומטית את Tensors ל-NumPy ndarrays.

הטנסורים מומרים במפורש ל-NumPy ndarrays באמצעות שיטת .numpy() שלהם. המרות אלו בדרך כלל זולות מכיוון שהמערך וה- tf.Tensor חולקים את ייצוג הזיכרון הבסיסי, אם אפשר. עם זאת, שיתוף הייצוג הבסיסי אינו תמיד אפשרי מכיוון שה- tf.Tensor עשוי להתארח בזיכרון GPU בעוד שמערכים NumPy תמיד מגובים בזיכרון מארח, וההמרה כוללת העתקה מ-GPU לזיכרון המארח.

import numpy as np

ndarray = np.ones([3, 3])

print("TensorFlow operations convert numpy arrays to Tensors automatically")
tensor = tf.multiply(ndarray, 42)
print(tensor)


print("And NumPy operations convert Tensors to numpy arrays automatically")
print(np.add(tensor, 1))

print("The .numpy() method explicitly converts a Tensor to a numpy array")
print(tensor.numpy())
TensorFlow operations convert numpy arrays to Tensors automatically
tf.Tensor(
[[42. 42. 42.]
 [42. 42. 42.]
 [42. 42. 42.]], shape=(3, 3), dtype=float64)
And NumPy operations convert Tensors to numpy arrays automatically
[[43. 43. 43.]
 [43. 43. 43.]
 [43. 43. 43.]]
The .numpy() method explicitly converts a Tensor to a numpy array
[[42. 42. 42.]
 [42. 42. 42.]
 [42. 42. 42.]]

האצת GPU

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

x = tf.random.uniform([3, 3])

print("Is there a GPU available: "),
print(tf.config.list_physical_devices("GPU"))

print("Is the Tensor on GPU #0:  "),
print(x.device.endswith('GPU:0'))
Is there a GPU available: 
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
Is the Tensor on GPU #0:  
True

שמות מכשירים

המאפיין Tensor.device מספק שם מחרוזת מלא של המכשיר המארח את תוכן הטנזור. שם זה מקודד פרטים רבים, כגון מזהה של כתובת הרשת של המארח שבו מופעלת תוכנית זו וההתקן בתוך המארח הזה. זה נדרש להפעלה מבוזרת של תוכנית TensorFlow. המחרוזת מסתיימת ב- GPU:<N> אם הטנזור ממוקם על ה- N -th GPU במארח.

מיקום מכשיר מפורש

ב-TensorFlow, מיקום מתייחס לאופן שבו פעולות בודדות מוקצות (מוצבות על) התקן לביצוע. כאמור, כאשר אין הנחיה מפורשת מסופקת, TensorFlow מחליטה אוטומטית איזה מכשיר לבצע פעולה ומעתיקה טנסורים לאותו מכשיר, במידת הצורך. עם זאת, ניתן למקם את פעולות TensorFlow במפורש במכשירים ספציפיים באמצעות מנהל ההקשרים tf.device , לדוגמה:

import time

def time_matmul(x):
  start = time.time()
  for loop in range(10):
    tf.matmul(x, x)

  result = time.time()-start

  print("10 loops: {:0.2f}ms".format(1000*result))

# Force execution on CPU
print("On CPU:")
with tf.device("CPU:0"):
  x = tf.random.uniform([1000, 1000])
  assert x.device.endswith("CPU:0")
  time_matmul(x)

# Force execution on GPU #0 if available
if tf.config.list_physical_devices("GPU"):
  print("On GPU:")
  with tf.device("GPU:0"): # Or GPU:1 for the 2nd GPU, GPU:2 for the 3rd etc.
    x = tf.random.uniform([1000, 1000])
    assert x.device.endswith("GPU:0")
    time_matmul(x)
On CPU:
10 loops: 91.47ms
On GPU:
10 loops: 388.16ms

מערכי נתונים

סעיף זה משתמש ב- tf.data.Dataset API כדי לבנות צינור להזנת נתונים למודל שלך. ה-API של tf.data.Dataset משמש לבניית צינורות קלט ביצועיים ומורכבים מחלקים פשוטים ניתנים לשימוש חוזר שיזין את לולאות ההדרכה או ההערכה של המודל שלך.

צור Dataset מקור

צור מערך נתונים מקור באמצעות אחת מפונקציות היצרן כמו Dataset.from_tensors , Dataset.from_tensor_slices , או שימוש באובייקטים שקוראים מקבצים כמו TextLineDataset או TFRecordDataset . עיין במדריך מערך הנתונים של TensorFlow למידע נוסף.

ds_tensors = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6])

# Create a CSV file
import tempfile
_, filename = tempfile.mkstemp()

with open(filename, 'w') as f:
  f.write("""Line 1
Line 2
Line 3
  """)

ds_file = tf.data.TextLineDataset(filename)

החל טרנספורמציות

השתמש בפונקציות הטרנספורמציות כמו map , batch shuffle כדי להחיל טרנספורמציות על רשומות של מערך נתונים.

ds_tensors = ds_tensors.map(tf.square).shuffle(2).batch(2)

ds_file = ds_file.batch(2)

לְחַזֵר

אובייקטי tf.data.Dataset תומכים באיטרציה ללולאה על רשומות:

print('Elements of ds_tensors:')
for x in ds_tensors:
  print(x)

print('\nElements in ds_file:')
for x in ds_file:
  print(x)
Elements of ds_tensors:
tf.Tensor([1 9], shape=(2,), dtype=int32)
tf.Tensor([16  4], shape=(2,), dtype=int32)
tf.Tensor([25 36], shape=(2,), dtype=int32)

Elements in ds_file:
tf.Tensor([b'Line 1' b'Line 2'], shape=(2,), dtype=string)
tf.Tensor([b'Line 3' b'  '], shape=(2,), dtype=string)