مشاهده در TensorFlow.org | در Google Colab اجرا شود | مشاهده منبع در 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)
برای تانسورهای 2 بعدی، می توانید از چیزی مانند:
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 برای اعمال کنترل دقیق بر عناصر موجود در تانسور خود استفاده کنید.
عملیات برش موجود با TensorFlow NumPy مانند
tf.experimental.numpy.take_along_axis
وtf.experimental.numpy.take
کنید.همچنین راهنمای Tensor و راهنمای متغیر را بررسی کنید.