השתתפו בסימפוזיון נשים ב-ML ב-7 בדצמבר הירשמו עכשיו

היכרות עם Tensors

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

הצג באתר TensorFlow.org הפעל בגוגל קולאב צפה במקור ב-GitHub הורד מחברת
import tensorflow as tf
import numpy as np

טנזורים הם מערכים רב מימדיים עם סוג אחיד (הנקרא dtype ). אתה יכול לראות את כל dtypes הנתמכים ב- tf.dtypes.DType .

אם אתה מכיר את NumPy , טנסורים הם (בערך) כמו np.arrays .

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

יסודות

בואו ניצור כמה טנסורים בסיסיים.

הנה טנזור "סקלרי" או "דרגה 0". סקלאר מכיל ערך בודד וללא "צירים".

# This will be an int32 tensor by default; see "dtypes" below.
rank_0_tensor = tf.constant(4)
print(rank_0_tensor)
tf.Tensor(4, shape=(), dtype=int32)

טנזור "וקטור" או "דרג 1" הוא כמו רשימת ערכים. לוקטור יש ציר אחד:

# Let's make this a float tensor.
rank_1_tensor = tf.constant([2.0, 3.0, 4.0])
print(rank_1_tensor)
tf.Tensor([2. 3. 4.], shape=(3,), dtype=float32)

לטנזור "מטריקס" או "דרג 2" יש שני צירים:

# If you want to be specific, you can set the dtype (see below) at creation time
rank_2_tensor = tf.constant([[1, 2],
                             [3, 4],
                             [5, 6]], dtype=tf.float16)
print(rank_2_tensor)
tf.Tensor(
[[1. 2.]
 [3. 4.]
 [5. 6.]], shape=(3, 2), dtype=float16)
סקלר, צורה: [] וקטור, צורה: [3] מטריצה, צורה: [3, 2]
סקלרית, המספר 4השורה עם 3 חלקים, כל אחד מכיל מספר.רשת בגודל 3x2, כאשר כל תא מכיל מספר.

לטנזורים עשויים להיות יותר צירים; הנה טנזור עם שלושה צירים:

# There can be an arbitrary number of
# axes (sometimes called "dimensions")
rank_3_tensor = tf.constant([
  [[0, 1, 2, 3, 4],
   [5, 6, 7, 8, 9]],
  [[10, 11, 12, 13, 14],
   [15, 16, 17, 18, 19]],
  [[20, 21, 22, 23, 24],
   [25, 26, 27, 28, 29]],])

print(rank_3_tensor)
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)

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

טנזור בן 3 צירים, צורה: [3, 2, 5]

אתה יכול להמיר טנסור למערך NumPy באמצעות np.array או שיטת tensor.numpy :

np.array(rank_2_tensor)
array([[1., 2.],
       [3., 4.],
       [5., 6.]], dtype=float16)
rank_2_tensor.numpy()
array([[1., 2.],
       [3., 4.],
       [5., 6.]], dtype=float16)

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

  • מספרים מסובכים
  • מחרוזות

מחלקת הבסיס tf.Tensor דורשת שהטנסורים יהיו "מלבניים" --- כלומר, לאורך כל ציר, כל אלמנט הוא באותו גודל. עם זאת, ישנם סוגים מיוחדים של טנסורים שיכולים להתמודד עם צורות שונות:

  • טנזורים מרופטים (ראה RaggedTensor למטה)
  • טנסורים דלילים (ראה SparseTensor למטה)

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

a = tf.constant([[1, 2],
                 [3, 4]])
b = tf.constant([[1, 1],
                 [1, 1]]) # Could have also said `tf.ones([2,2])`

print(tf.add(a, b), "\n")
print(tf.multiply(a, b), "\n")
print(tf.matmul(a, b), "\n")
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[3 3]
 [7 7]], shape=(2, 2), dtype=int32)
print(a + b, "\n") # element-wise addition
print(a * b, "\n") # element-wise multiplication
print(a @ b, "\n") # matrix multiplication
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[3 3]
 [7 7]], shape=(2, 2), dtype=int32)

טנזורים משמשים בכל מיני פעולות (אופס).

c = tf.constant([[4.0, 5.0], [10.0, 1.0]])

# Find the largest value
print(tf.reduce_max(c))
# Find the index of the largest value
print(tf.argmax(c))
# Compute the softmax
print(tf.nn.softmax(c))
tf.Tensor(10.0, shape=(), dtype=float32)
tf.Tensor([1 0], shape=(2,), dtype=int64)
tf.Tensor(
[[2.6894143e-01 7.3105854e-01]
 [9.9987662e-01 1.2339458e-04]], shape=(2, 2), dtype=float32)

לגבי צורות

לטנזורים יש צורות. קצת אוצר מילים:

  • צורה : האורך (מספר האלמנטים) של כל אחד מהצירים של טנזור.
  • דירוג : מספר צירי טנזור. לסקלר יש דרגה 0, לוקטור יש דרגה 1, מטריצה ​​היא דרגה 2.
  • ציר או מימד : ממד מסוים של טנזור.
  • גודל : המספר הכולל של פריטים בטנזור, וקטור צורת המוצר.

לטנסור ולאובייקטים tf.TensorShape יש מאפיינים נוחים לגישה לאלה:

rank_4_tensor = tf.zeros([3, 2, 4, 5])
טנסור דרגה 4, צורה: [3, 2, 4, 5]
צורת טנזור היא כמו וקטור.טנזור 4 צירים
print("Type of every element:", rank_4_tensor.dtype)
print("Number of axes:", rank_4_tensor.ndim)
print("Shape of tensor:", rank_4_tensor.shape)
print("Elements along axis 0 of tensor:", rank_4_tensor.shape[0])
print("Elements along the last axis of tensor:", rank_4_tensor.shape[-1])
print("Total number of elements (3*2*4*5): ", tf.size(rank_4_tensor).numpy())
Type of every element: <dtype: 'float32'>
Number of axes: 4
Shape of tensor: (3, 2, 4, 5)
Elements along axis 0 of tensor: 3
Elements along the last axis of tensor: 5
Total number of elements (3*2*4*5):  120

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

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

יצירת אינדקס

אינדקס ציר בודד

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

  • האינדקסים מתחילים ב 0
  • מדדים שליליים סופרים לאחור מהסוף
  • נקודתיים, : , משמשים לפרוסות: start:stop:step
rank_1_tensor = tf.constant([0, 1, 1, 2, 3, 5, 8, 13, 21, 34])
print(rank_1_tensor.numpy())
[ 0  1  1  2  3  5  8 13 21 34]

אינדקס עם סקלרי מסיר את הציר:

print("First:", rank_1_tensor[0].numpy())
print("Second:", rank_1_tensor[1].numpy())
print("Last:", rank_1_tensor[-1].numpy())
First: 0
Second: 1
Last: 34

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

print("Everything:", rank_1_tensor[:].numpy())
print("Before 4:", rank_1_tensor[:4].numpy())
print("From 4 to the end:", rank_1_tensor[4:].numpy())
print("From 2, before 7:", rank_1_tensor[2:7].numpy())
print("Every other item:", rank_1_tensor[::2].numpy())
print("Reversed:", rank_1_tensor[::-1].numpy())
Everything: [ 0  1  1  2  3  5  8 13 21 34]
Before 4: [0 1 1 2]
From 4 to the end: [ 3  5  8 13 21 34]
From 2, before 7: [1 2 3 5 8]
Every other item: [ 0  1  3  8 21]
Reversed: [34 21 13  8  5  3  2  1  1  0]

אינדקס רב צירים

טנזורים בדרגה גבוהה יותר מתווספים לאינדקס על ידי העברת מדדים מרובים.

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

print(rank_2_tensor.numpy())
[[1. 2.]
 [3. 4.]
 [5. 6.]]

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

# Pull out a single value from a 2-rank tensor
print(rank_2_tensor[1, 1].numpy())
4.0

אתה יכול לעשות אינדקס באמצעות כל שילוב של מספרים שלמים ופרוסות:

# Get row and column tensors
print("Second row:", rank_2_tensor[1, :].numpy())
print("Second column:", rank_2_tensor[:, 1].numpy())
print("Last row:", rank_2_tensor[-1, :].numpy())
print("First item in last column:", rank_2_tensor[0, -1].numpy())
print("Skip the first row:")
print(rank_2_tensor[1:, :].numpy(), "\n")
Second row: [3. 4.]
Second column: [2. 4. 6.]
Last row: [5. 6.]
First item in last column: 2.0
Skip the first row:
[[3. 4.]
 [5. 6.]]

הנה דוגמה עם טנזור בן 3 צירים:

print(rank_3_tensor[:, :, 4])
tf.Tensor(
[[ 4  9]
 [14 19]
 [24 29]], shape=(3, 2), dtype=int32)
בחירת התכונה האחרונה בכל המיקומים בכל דוגמה באצווה
טנזור 3x2x5 עם כל הערכים באינדקס-4 של הציר האחרון שנבחר.הערכים שנבחרו ארוזים בטנזור בן 2 צירים.

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

מניפולציה של צורות

עיצוב מחדש של טנזור הוא תועלת רבה.

# Shape returns a `TensorShape` object that shows the size along each axis
x = tf.constant([[1], [2], [3]])
print(x.shape)
(3, 1)
# You can convert this object into a Python list, too
print(x.shape.as_list())
[3, 1]

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

# You can reshape a tensor to a new shape.
# Note that you're passing in a list
reshaped = tf.reshape(x, [1, 3])
print(x.shape)
print(reshaped.shape)
(3, 1)
(1, 3)

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

print(rank_3_tensor)
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)

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

# A `-1` passed in the `shape` argument says "Whatever fits".
print(tf.reshape(rank_3_tensor, [-1]))
tf.Tensor(
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27 28 29], shape=(30,), dtype=int32)

בדרך כלל השימוש הסביר היחיד ב- tf.reshape הוא לשלב או לפצל צירים סמוכים (או להוסיף/להסיר 1 שניות).

עבור טנזור זה בגודל 3x2x5, עיצוב מחדש ל-(3x2)x5 או 3x(2x5) הן דברים סבירים לעשות, מכיוון שהפרוסות אינן מתערבבות:

print(tf.reshape(rank_3_tensor, [3*2, 5]), "\n")
print(tf.reshape(rank_3_tensor, [3, -1]))
tf.Tensor(
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]
 [25 26 27 28 29]], shape=(6, 5), dtype=int32) 

tf.Tensor(
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]], shape=(3, 10), dtype=int32)
כמה עיצובים טובים.
טנזור 3x2x5אותם נתונים עוצבו מחדש ל-(3x2)x5אותם נתונים עוצבו מחדש ל-3x(2x5)

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

החלפת צירים ב- tf.reshape לא עובדת; אתה צריך tf.transpose בשביל זה.

# Bad examples: don't do this

# You can't reorder axes with reshape.
print(tf.reshape(rank_3_tensor, [2, 3, 5]), "\n") 

# This is a mess
print(tf.reshape(rank_3_tensor, [5, 6]), "\n")

# This doesn't work at all
try:
  tf.reshape(rank_3_tensor, [7, -1])
except Exception as e:
  print(f"{type(e).__name__}: {e}")
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]]

 [[15 16 17 18 19]
  [20 21 22 23 24]
  [25 26 27 28 29]]], shape=(2, 3, 5), dtype=int32) 

tf.Tensor(
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]
 [24 25 26 27 28 29]], shape=(5, 6), dtype=int32) 

InvalidArgumentError: Input to reshape is a tensor with 30 values, but the requested shape requires a multiple of 7 [Op:Reshape]
כמה עיצובים רעים.
אתה לא יכול לסדר מחדש את הצירים, השתמש ב-tf.transpose בשביל זהכל דבר שמערבב את פרוסות הנתונים יחד הוא כנראה שגוי.הצורה החדשה חייבת להתאים בדיוק.

אתה עלול להיתקל בצורות שלא צוינו במלואן. או שהצורה מכילה None (אורך ציר אינו ידוע) או שכל הצורה היא None (דרגת הטנזור אינה ידועה).

למעט tf.RaggedTensor , צורות כאלה יופיעו רק בהקשר של ממשקי ה-API הסמליים של TensorFlow הבונים גרפים:

עוד על DTypes

כדי לבדוק את סוג הנתונים של tf.Tensor השתמש במאפיין Tensor.dtype .

בעת יצירת tf.Tensor מאובייקט Python, תוכל לציין את סוג הנתונים.

אם לא, TensorFlow בוחר בסוג נתונים שיכול לייצג את הנתונים שלך. TensorFlow ממיר מספרים שלמים של Python ל- tf.int32 ומספרי נקודה צפה של Python ל- tf.float32 . אחרת TensorFlow משתמש באותם כללים שבהם משתמשת NumPy בעת המרה למערכים.

אתה יכול להטיל סוג לסוג.

the_f64_tensor = tf.constant([2.2, 3.3, 4.4], dtype=tf.float64)
the_f16_tensor = tf.cast(the_f64_tensor, dtype=tf.float16)
# Now, cast to an uint8 and lose the decimal precision
the_u8_tensor = tf.cast(the_f16_tensor, dtype=tf.uint8)
print(the_u8_tensor)
tf.Tensor([2 3 4], shape=(3,), dtype=uint8)

שידור

שידור הוא מושג שלקוח מהפיצ'ר המקביל ב-NumPy . בקיצור, בתנאים מסוימים, טנסורים קטנים יותר "נמתחים" אוטומטית כדי להתאים לטנסורים גדולים יותר בעת הפעלת פעולות משולבות עליהם.

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

x = tf.constant([1, 2, 3])

y = tf.constant(2)
z = tf.constant([2, 2, 2])
# All of these are the same computation
print(tf.multiply(x, 2))
print(x * y)
print(x * z)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)

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

במקרה זה מטריצה ​​3x1 מוכפלת מבחינת אלמנט במטריצה ​​1x4 כדי לייצר מטריצה ​​3x4. שימו לב כיצד ה-1 המוביל הוא אופציונלי: הצורה של y היא [4] .

# These are the same computations
x = tf.reshape(x,[3,1])
y = tf.range(1, 5)
print(x, "\n")
print(y, "\n")
print(tf.multiply(x, y))
tf.Tensor(
[[1]
 [2]
 [3]], shape=(3, 1), dtype=int32) 

tf.Tensor([1 2 3 4], shape=(4,), dtype=int32) 

tf.Tensor(
[[ 1  2  3  4]
 [ 2  4  6  8]
 [ 3  6  9 12]], shape=(3, 4), dtype=int32)
תוספת משודרת: a [3, 1] כפול [1, 4] נותן [3,4]
הוספת מטריצה ​​3x1 למטריצה ​​4x1 גורמת למטריצה ​​3x4

הנה אותה פעולה ללא שידור:

x_stretch = tf.constant([[1, 1, 1, 1],
                         [2, 2, 2, 2],
                         [3, 3, 3, 3]])

y_stretch = tf.constant([[1, 2, 3, 4],
                         [1, 2, 3, 4],
                         [1, 2, 3, 4]])

print(x_stretch * y_stretch)  # Again, operator overloading
tf.Tensor(
[[ 1  2  3  4]
 [ 2  4  6  8]
 [ 3  6  9 12]], shape=(3, 4), dtype=int32)

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

אתה רואה איך נראה השידור באמצעות tf.broadcast_to .

print(tf.broadcast_to(tf.constant([1, 2, 3]), [3, 3]))
tf.Tensor(
[[1 2 3]
 [1 2 3]
 [1 2 3]], shape=(3, 3), dtype=int32)

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

זה יכול להיות אפילו יותר מסובך. חלק זה בספרו של ג'ייק VanderPlas Python Data Science Handbook מציג עוד טריקים לשידור (שוב ב-NumPy).

tf.convert_to_tensor

רוב המבצעים, כמו tf.matmul ו- tf.reshape לוקחים טיעונים tf.Tensor . עם זאת, תבחין במקרה שלמעלה, אובייקטים של Python בצורת טנסורים מתקבלים.

רוב, אך לא כולם, מבצעים קוראים convert_to_tensor על ארגומנטים שאינם טנסור. יש רישום של המרות, ורוב מחלקות האובייקט כמו ndarray של ndarray , TensorShape , רשימות Python ו- tf.Variable כולן יומרו אוטומטית.

ראה tf.register_tensor_conversion_function לפרטים נוספים, ואם יש לך סוג משלך, תרצה להמיר אוטומטית לטנזור.

טנזורים מרופטים

טנזור עם מספרים משתנים של אלמנטים לאורך ציר כלשהו נקרא "מרופט". השתמש ב- tf.ragged.RaggedTensor לנתונים מרופטים.

לדוגמה, זה לא יכול להיות מיוצג כטנזור רגיל:

A tf.RaggedTensor , צורה: [4, None]
טנזור מרופט בן 2 צירים, לכל שורה יכול להיות אורך שונה.
ragged_list = [
    [0, 1, 2, 3],
    [4, 5],
    [6, 7, 8],
    [9]]
try:
  tensor = tf.constant(ragged_list)
except Exception as e:
  print(f"{type(e).__name__}: {e}")
ValueError: Can't convert non-rectangular Python sequence to Tensor.

במקום זאת צור tf.RaggedTensor באמצעות tf.ragged.constant :

ragged_tensor = tf.ragged.constant(ragged_list)
print(ragged_tensor)
<tf.RaggedTensor [[0, 1, 2, 3], [4, 5], [6, 7, 8], [9]]>

הצורה של tf.RaggedTensor תכיל כמה צירים עם אורכים לא ידועים:

print(ragged_tensor.shape)
(4, None)

טנסור מיתר

tf.string הוא dtype , כלומר אתה יכול לייצג נתונים כמחרוזות (מערכי בתים באורך משתנה) בטנסורים.

המיתרים הם אטומיים ואינם ניתנים לאינדקס כמו מחרוזות Python. אורך המיתר אינו אחד מצירי הטנזור. ראה tf.strings עבור פונקציות לתמרן אותן.

להלן טנזור מיתרים סקלרי:

# Tensors can be strings, too here is a scalar string.
scalar_string_tensor = tf.constant("Gray wolf")
print(scalar_string_tensor)
tf.Tensor(b'Gray wolf', shape=(), dtype=string)

ווקטור של מחרוזות:

וקטור של מחרוזות, צורה: [3,]
אורך המיתר אינו אחד מצירי הטנזור.
# If you have three string tensors of different lengths, this is OK.
tensor_of_strings = tf.constant(["Gray wolf",
                                 "Quick brown fox",
                                 "Lazy dog"])
# Note that the shape is (3,). The string length is not included.
print(tensor_of_strings)
tf.Tensor([b'Gray wolf' b'Quick brown fox' b'Lazy dog'], shape=(3,), dtype=string)

בתדפיס לעיל הקידומת b מציינת ש- tf.string dtype אינה מחרוזת unicode, אלא מחרוזת בתים. עיין במדריך Unicode למידע נוסף על עבודה עם טקסט Unicode ב-TensorFlow.

אם אתה מעביר תווי Unicode הם מקודדים utf-8.

tf.constant("🥳👍")
<tf.Tensor: shape=(), dtype=string, numpy=b'\xf0\x9f\xa5\xb3\xf0\x9f\x91\x8d'>

ניתן למצוא כמה פונקציות בסיסיות עם מחרוזות ב- tf.strings , כולל tf.strings.split .

# You can use split to split a string into a set of tensors
print(tf.strings.split(scalar_string_tensor, sep=" "))
tf.Tensor([b'Gray' b'wolf'], shape=(2,), dtype=string)
# ...but it turns into a `RaggedTensor` if you split up a tensor of strings,
# as each string might be split into a different number of parts.
print(tf.strings.split(tensor_of_strings))
<tf.RaggedTensor [[b'Gray', b'wolf'], [b'Quick', b'brown', b'fox'], [b'Lazy', b'dog']]>
שלושה מיתרים מפוצלים, צורה: [3, None]
פיצול מחרוזות מרובות מחזיר tf.RaggedTensor

ו- tf.string.to_number :

text = tf.constant("1 10 100")
print(tf.strings.to_number(tf.strings.split(text, " ")))
tf.Tensor([  1.  10. 100.], shape=(3,), dtype=float32)

למרות שאינך יכול להשתמש ב- tf.cast כדי להפוך טנזור מחרוזת למספרים, אתה יכול להמיר אותו לבייטים ולאחר מכן למספרים.

byte_strings = tf.strings.bytes_split(tf.constant("Duck"))
byte_ints = tf.io.decode_raw(tf.constant("Duck"), tf.uint8)
print("Byte strings:", byte_strings)
print("Bytes:", byte_ints)
Byte strings: tf.Tensor([b'D' b'u' b'c' b'k'], shape=(4,), dtype=string)
Bytes: tf.Tensor([ 68 117  99 107], shape=(4,), dtype=uint8)
# Or split it up as unicode and then decode it
unicode_bytes = tf.constant("アヒル 🦆")
unicode_char_bytes = tf.strings.unicode_split(unicode_bytes, "UTF-8")
unicode_values = tf.strings.unicode_decode(unicode_bytes, "UTF-8")

print("\nUnicode bytes:", unicode_bytes)
print("\nUnicode chars:", unicode_char_bytes)
print("\nUnicode values:", unicode_values)
Unicode bytes: tf.Tensor(b'\xe3\x82\xa2\xe3\x83\x92\xe3\x83\xab \xf0\x9f\xa6\x86', shape=(), dtype=string)

Unicode chars: tf.Tensor([b'\xe3\x82\xa2' b'\xe3\x83\x92' b'\xe3\x83\xab' b' ' b'\xf0\x9f\xa6\x86'], shape=(5,), dtype=string)

Unicode values: tf.Tensor([ 12450  12498  12523     32 129414], shape=(5,), dtype=int32)

ה- tf.string dtype משמש עבור כל נתוני הבתים הגולמיים ב-TensorFlow. מודול tf.io מכיל פונקציות להמרת נתונים אל וממנה, כולל פענוח תמונות וניתוח csv.

טנסורים דלילים

לפעמים, הנתונים שלך דלים, כמו חלל הטבעה רחב מאוד. TensorFlow תומך ב- tf.sparse.SparseTensor קשורות לאחסון נתונים דל ביעילות.

A tf.SparseTensor , צורה: [3, 4]
רשת 3x4, עם ערכים רק בשניים מהתאים.
# Sparse tensors store values by index in a memory-efficient manner
sparse_tensor = tf.sparse.SparseTensor(indices=[[0, 0], [1, 2]],
                                       values=[1, 2],
                                       dense_shape=[3, 4])
print(sparse_tensor, "\n")

# You can convert sparse tensors to dense
print(tf.sparse.to_dense(sparse_tensor))
SparseTensor(indices=tf.Tensor(
[[0 0]
 [1 2]], shape=(2, 2), dtype=int64), values=tf.Tensor([1 2], shape=(2,), dtype=int32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64)) 

tf.Tensor(
[[1 0 0 0]
 [0 0 2 0]
 [0 0 0 0]], shape=(3, 4), dtype=int32)