Xem trên TensorFlow.org | Chạy trong Google Colab | Xem nguồn trên GitHub | Tải xuống sổ ghi chép |
Khi làm việc trên các ứng dụng ML như phát hiện đối tượng và NLP, đôi khi cần phải làm việc với các phần phụ (lát cắt) của tensor. Ví dụ: nếu kiến trúc mô hình của bạn bao gồm định tuyến, trong đó một lớp có thể kiểm soát ví dụ đào tạo nào được chuyển đến lớp tiếp theo. Trong trường hợp này, bạn có thể sử dụng các thao tác cắt tensor để tách các tensor ra và đặt chúng lại với nhau theo đúng thứ tự.
Trong các ứng dụng NLP, bạn có thể sử dụng phương pháp cắt lớp căng để thực hiện việc che chữ trong khi đào tạo. Ví dụ: bạn có thể tạo dữ liệu đào tạo từ danh sách các câu bằng cách chọn một chỉ mục từ để tạo dấu hiệu trong mỗi câu, lấy từ đó làm nhãn, sau đó thay thế từ đã chọn bằng mã thông báo mặt nạ.
Trong hướng dẫn này, bạn sẽ học cách sử dụng các API TensorFlow để:
- Trích xuất các lát từ tensor
- Chèn dữ liệu tại các chỉ số cụ thể trong một tensor
Hướng dẫn này giả định bạn đã quen với lập chỉ mục tensor. Đọc các phần lập chỉ mục của hướng dẫn Tensor và TensorFlow NumPy trước khi bắt đầu với hướng dẫn này.
Thành lập
import tensorflow as tf
import numpy as np
Trích xuất các lát tensor
Thực hiện cắt tensor giống NumPy bằng 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)
Ngoài ra, bạn có thể sử dụng một cú pháp Pythonic khác. Lưu ý rằng các lát tensor cách đều nhau trong phạm vi start-stop.
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)
Đối với bộ căng 2 chiều, bạn có thể sử dụng một số thứ như:
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)
Bạn cũng có thể sử dụng tf.slice
trên các máy căng kích thước cao hơn.
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)
Bạn cũng có thể sử dụng tf.strided_slice
để trích xuất các lát của tensor bằng cách 'sải bước' trên các kích thước tensor.
Sử dụng tf.gather
để trích xuất các chỉ số cụ thể từ một trục đơn của tensor.
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
không yêu cầu các chỉ số phải cách đều nhau.
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)
Để trích xuất các lát từ nhiều trục của tensor, hãy sử dụng tf.gather_nd
. Điều này hữu ích khi bạn muốn thu thập các phần tử của ma trận thay vì chỉ các hàng hoặc cột của nó.
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)
Chèn dữ liệu vào tensors
Sử dụng tf.scatter_nd
để chèn dữ liệu tại các lát / chỉ số cụ thể của tensor. Lưu ý rằng tensor mà bạn chèn các giá trị không được khởi tạo.
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)
Các phương thức như tf.scatter_nd
yêu cầu các tensor khởi tạo bằng 0 tương tự như các bộ khởi tạo tensor thưa thớt. Bạn có thể sử dụng tf.gather_nd
và tf.scatter_nd
để bắt chước hành vi của các hoạt động tensor thưa thớt.
Hãy xem xét một ví dụ trong đó bạn xây dựng một tensor thưa thớt bằng cách sử dụng hai phương pháp này kết hợp với nhau.
# 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)
Điều này tương tự như:
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)
Để chèn dữ liệu vào tensor với các giá trị tồn tại trước, hãy sử dụng 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)
Tương tự, sử dụng tf.tensor_scatter_nd_sub
để trừ các giá trị từ tensor với các giá trị tồn tại trước.
# 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)
Sử dụng tf.tensor_scatter_nd_min
để sao chép các giá trị tối thiểu của phần tử từ tensor này sang tensor khác.
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)
Tương tự, sử dụng tf.tensor_scatter_nd_max
để sao chép các giá trị lớn nhất của phần tử từ tensor này sang tensor khác.
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)
Đọc thêm và tài nguyên
Trong hướng dẫn này, bạn đã học cách sử dụng các hoạt động cắt tensor có sẵn với TensorFlow để kiểm soát tốt hơn các phần tử trong tensor của bạn.
Kiểm tra các hoạt động cắt có sẵn với TensorFlow NumPy chẳng hạn như
tf.experimental.numpy.take_along_axis
vàtf.experimental.numpy.take
.Ngoài ra, hãy xem hướng dẫn Tensor và hướng dẫn Variable .