מבוא לחיתוך טנסור

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

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

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

במדריך זה תלמד כיצד להשתמש בממשקי ה- API של TensorFlow כדי:

  • חלץ פרוסות מטנזור
  • הכנס נתונים למדדים ספציפיים בטנזור

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

להכין

import tensorflow as tf
import numpy as np

חלץ פרוסות טנסור

בצע חיתוך טנזור דמוי tf.slice באמצעות tf.slice .

t1 = tf.constant([0, 1, 2, 3, 4, 5, 6, 7])

print(tf.slice(t1,
               begin=[1],
               size=[3]))
tf.Tensor([1 2 3], shape=(3,), dtype=int32)

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

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

print(t1[-3:])
tf.Tensor([5 6 7], shape=(3,), dtype=int32)

עבור טנסורים דו מימדיים, אתה יכול להשתמש במשהו כמו:

t2 = tf.constant([[0, 1, 2, 3, 4],
                  [5, 6, 7, 8, 9],
                  [10, 11, 12, 13, 14],
                  [15, 16, 17, 18, 19]])

print(t2[:-1, 1:3])
tf.Tensor(
[[ 1  2]
 [ 6  7]
 [11 12]], shape=(3, 2), dtype=int32)

אתה יכול להשתמש ב- tf.slice על טנזורים ממדיים גבוהים יותר.

t3 = tf.constant([[[1, 3, 5, 7],
                   [9, 11, 13, 15]],
                  [[17, 19, 21, 23],
                   [25, 27, 29, 31]]
                  ])

print(tf.slice(t3,
               begin=[1, 1, 0],
               size=[1, 1, 2]))
tf.Tensor([[[25 27]]], shape=(1, 1, 2), dtype=int32)

אתה יכול גם להשתמש ב- tf.strided_slice כדי לחלץ פרוסות של טנזורים על ידי 'מעבר' על ממדי הטנסור.

השתמש ב- tf.gather כדי לחלץ מדדים ספציפיים מציר יחיד של טנסור.

print(tf.gather(t1,
                indices=[0, 3, 6]))

# This is similar to doing

t1[::3]
tf.Tensor([0 3 6], shape=(3,), dtype=int32)
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([0, 3, 6], dtype=int32)>

tf.gather אינו דורש ריווח שווה של המדדים.

alphabet = tf.constant(list('abcdefghijklmnopqrstuvwxyz'))

print(tf.gather(alphabet,
                indices=[2, 0, 19, 18]))
tf.Tensor([b'c' b'a' b't' b's'], shape=(4,), dtype=string)

כדי לחלץ פרוסות ממספר צירים של טנסור, השתמש ב- tf.gather_nd . זה שימושי כאשר אתה רוצה לאסוף את האלמנטים של מטריצה ​​בניגוד רק לשורות או לעמודות שלה.

t4 = tf.constant([[0, 5],
                  [1, 6],
                  [2, 7],
                  [3, 8],
                  [4, 9]])

print(tf.gather_nd(t4,
                   indices=[[2], [3], [0]]))
tf.Tensor(
[[2 7]
 [3 8]
 [0 5]], shape=(3, 2), dtype=int32)

t5 = np.reshape(np.arange(18), [2, 3, 3])

print(tf.gather_nd(t5,
                   indices=[[0, 0, 0], [1, 2, 1]]))
tf.Tensor([ 0 16], shape=(2,), dtype=int64)
# Return a list of two matrices

print(tf.gather_nd(t5,
                   indices=[[[0, 0], [0, 2]], [[1, 0], [1, 2]]]))
tf.Tensor(
[[[ 0  1  2]
  [ 6  7  8]]

 [[ 9 10 11]
  [15 16 17]]], shape=(2, 2, 3), dtype=int64)
# Return one matrix

print(tf.gather_nd(t5,
                   indices=[[0, 0], [0, 2], [1, 0], [1, 2]]))
tf.Tensor(
[[ 0  1  2]
 [ 6  7  8]
 [ 9 10 11]
 [15 16 17]], shape=(4, 3), dtype=int64)

הכנס נתונים לטנסורים

השתמש ב- tf.scatter_nd כדי להוסיף נתונים בפרוסות / מדדים ספציפיים של טנסור. שים לב שהטנסור אליו אתה מכניס ערכים הוא מאותחל לאפס.

t6 = tf.constant([10])
indices = tf.constant([[1], [3], [5], [7], [9]])
data = tf.constant([2, 4, 6, 8, 10])

print(tf.scatter_nd(indices=indices,
                    updates=data,
                    shape=t6))
tf.Tensor([ 0  2  0  4  0  6  0  8  0 10], shape=(10,), dtype=int32)

שיטות כמו tf.scatter_nd הדורשות tf.scatter_nd אפסים מאותחל דומים tf.scatter_nd טנזור דלילים. אתה יכול להשתמש ב- tf.gather_nd וב- tf.scatter_nd כדי לחקות את התנהגותם של tf.scatter_nd דלילים.

שקול דוגמה שבה אתה בונה טנסור דליל בשתי שיטות אלה יחד.

# Gather values from one tensor by specifying indices

new_indices = tf.constant([[0, 2], [2, 1], [3, 3]])
t7 = tf.gather_nd(t2, indices=new_indices)

# Add these values into a new tensor

t8 = tf.scatter_nd(indices=new_indices, updates=t7, shape=tf.constant([4, 5]))

print(t8)
tf.Tensor(
[[ 0  0  2  0  0]
 [ 0  0  0  0  0]
 [ 0 11  0  0  0]
 [ 0  0  0 18  0]], shape=(4, 5), dtype=int32)

זה דומה ל:

t9 = tf.SparseTensor(indices=[[0, 2], [2, 1], [3, 3]],
                     values=[2, 11, 18],
                     dense_shape=[4, 5])

print(t9)
SparseTensor(indices=tf.Tensor(
[[0 2]
 [2 1]
 [3 3]], shape=(3, 2), dtype=int64), values=tf.Tensor([ 2 11 18], shape=(3,), dtype=int32), dense_shape=tf.Tensor([4 5], shape=(2,), dtype=int64))
# Convert the sparse tensor into a dense tensor

t10 = tf.sparse.to_dense(t9)

print(t10)
tf.Tensor(
[[ 0  0  2  0  0]
 [ 0  0  0  0  0]
 [ 0 11  0  0  0]
 [ 0  0  0 18  0]], shape=(4, 5), dtype=int32)

כדי להכניס נתונים tf.tensor_scatter_nd_add עם ערכים קיימים, השתמש ב- tf.tensor_scatter_nd_add .

t11 = tf.constant([[2, 7, 0],
                   [9, 0, 1],
                   [0, 3, 8]])

# Convert the tensor into a magic square by inserting numbers at appropriate indices

t12 = tf.tensor_scatter_nd_add(t11,
                               indices=[[0, 2], [1, 1], [2, 0]],
                               updates=[6, 5, 4])

print(t12)
tf.Tensor(
[[2 7 6]
 [9 5 1]
 [4 3 8]], shape=(3, 3), dtype=int32)

באופן דומה, השתמש ב- tf.tensor_scatter_nd_sub כדי להפחית ערכים tf.tensor_scatter_nd_sub עם ערכים קיימים מראש.

# Convert the tensor into an identity matrix

t13 = tf.tensor_scatter_nd_sub(t11,
                               indices=[[0, 0], [0, 1], [1, 0], [1, 1], [1, 2], [2, 1], [2, 2]],
                               updates=[1, 7, 9, -1, 1, 3, 7])

print(t13)
tf.Tensor(
[[1 0 0]
 [0 1 0]
 [0 0 1]], shape=(3, 3), dtype=int32)

השתמש ב- tf.tensor_scatter_nd_min כדי להעתיק ערכי מינימום מבחינה tf.tensor_scatter_nd_min ממגזר אחד למשנהו.

t14 = tf.constant([[-2, -7, 0],
                   [-9, 0, 1],
                   [0, -3, -8]])

t15 = tf.tensor_scatter_nd_min(t14,
                               indices=[[0, 2], [1, 1], [2, 0]],
                               updates=[-6, -5, -4])

print(t15)
tf.Tensor(
[[-2 -7 -6]
 [-9 -5  1]
 [-4 -3 -8]], shape=(3, 3), dtype=int32)

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

t16 = tf.tensor_scatter_nd_max(t14,
                               indices=[[0, 2], [1, 1], [2, 0]],
                               updates=[6, 5, 4])

print(t16)
tf.Tensor(
[[-2 -7  6]
 [-9  5  1]
 [ 4 -3 -8]], shape=(3, 3), dtype=int32)

המשך קריאה ומשאבים

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