היכרות עם חיתוך טנסור

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

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

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

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

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

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

להכין

import tensorflow as tf
import numpy as np

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

בצע חיתוך טנזור דמוי NumPy באמצעות 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.gather_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 .

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 כדי להחסיר ערכים מטנזור עם ערכים קיימים.

# 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 כדי להעתיק ערכי מינימום מבחינת אלמנט מטנזור אחד לאחר.

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 כדי להעתיק ערכים מקסימליים מבחינת אלמנטים מטנסור אחד למשנהו.

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 כדי להפעיל שליטה עדינה יותר על האלמנטים בטנזורים שלך.