ดูบน TensorFlow.org | ทำงานใน Google Colab | ดูแหล่งที่มาบน GitHub | ดาวน์โหลดโน๊ตบุ๊ค |
เมื่อทำงานกับแอปพลิเคชัน ML เช่น การตรวจจับวัตถุและ NLP บางครั้งจำเป็นต้องทำงานกับส่วนย่อย (ส่วน) ของเทนเซอร์ ตัวอย่างเช่น หากสถาปัตยกรรมแบบจำลองของคุณมีการกำหนดเส้นทาง โดยที่เลเยอร์หนึ่งอาจควบคุมว่าตัวอย่างการฝึกใดจะได้รับการกำหนดเส้นทางไปยังเลเยอร์ถัดไป ในกรณีนี้ คุณสามารถใช้ tensor slicing ops เพื่อแยกเทนเซอร์ออกและประกอบกลับเข้าที่ในลำดับที่ถูกต้อง
ในแอปพลิเคชัน NLP คุณสามารถใช้ตัวแบ่งเทนเซอร์เพื่อทำการปิดบังคำขณะฝึกได้ ตัวอย่างเช่น คุณสามารถสร้างข้อมูลการฝึกอบรมจากรายการประโยคโดยเลือกดัชนีคำที่จะมาสก์ในแต่ละประโยค นำคำออกมาเป็นป้ายกำกับ แล้วแทนที่คำที่เลือกด้วยโทเค็นการพราง
ในคู่มือนี้ คุณจะได้เรียนรู้วิธีใช้ TensorFlow API เพื่อ:
- แยกชิ้นจากเทนเซอร์
- แทรกข้อมูลที่ดัชนีเฉพาะในเทนเซอร์
คู่มือนี้จะถือว่าคุ้นเคยกับการจัดทำดัชนีเทนเซอร์ อ่านส่วนการจัดทำดัชนีของคู่มือ 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)
หรือคุณสามารถใช้ไวยากรณ์ Pythonic เพิ่มเติมได้ โปรดทราบว่าเทนเซอร์สไลซ์จะเว้นระยะห่างเท่าๆ กันในช่วงเริ่มต้น-หยุด
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
เพื่อแยกส่วนของเทนเซอร์โดย 'striding' เหนือมิติเทนเซอร์
ใช้ 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)ตัวยึดตำแหน่ง21
# 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
เพื่อเลียนแบบพฤติกรรมของ sparse tensor ops
ลองพิจารณาตัวอย่างที่คุณสร้างเมตริกซ์กระจัดกระจายโดยใช้สองวิธีนี้ร่วมกัน
# 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)ตัวยึดตำแหน่ง36
ใช้ 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)
อ่านเพิ่มเติมและทรัพยากร
ในคู่มือนี้ คุณได้เรียนรู้วิธีใช้ ops การแบ่งส่วนเทนเซอร์ที่มีอยู่ใน TensorFlow เพื่อควบคุมองค์ประกอบในเทนเซอร์ของคุณอย่างละเอียดยิ่งขึ้น
ตรวจสอบการแบ่งส่วนข้อมูลที่มีอยู่ใน TensorFlow NumPy เช่น
tf.experimental.numpy.take_along_axis
และtf.experimental.numpy.take
ตรวจดู คู่มือเทนเซอร์และคู่มือ ตัวแปร ด้วย