Pengantar pemotongan tensor

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHub Unduh buku catatan

Saat mengerjakan aplikasi ML seperti deteksi objek dan NLP, terkadang perlu bekerja dengan sub-bagian (slice) tensor. Misalnya, jika arsitektur model Anda menyertakan perutean, di mana satu lapisan mungkin mengontrol contoh pelatihan mana yang dirutekan ke lapisan berikutnya. Dalam hal ini, Anda dapat menggunakan operasi pengiris tensor untuk membagi tensor dan menyatukannya kembali dalam urutan yang benar.

Dalam aplikasi NLP, Anda dapat menggunakan tensor slicing untuk melakukan penyembunyian kata saat pelatihan. Misalnya, Anda dapat menghasilkan data pelatihan dari daftar kalimat dengan memilih indeks kata untuk disamarkan di setiap kalimat, mengeluarkan kata sebagai label, lalu mengganti kata yang dipilih dengan token topeng.

Dalam panduan ini, Anda akan mempelajari cara menggunakan TensorFlow API untuk:

  • Ekstrak irisan dari tensor
  • Masukkan data pada indeks tertentu dalam tensor

Panduan ini mengasumsikan keakraban dengan pengindeksan tensor. Baca bagian pengindeksan panduan Tensor dan TensorFlow NumPy sebelum memulai panduan ini.

Mempersiapkan

import tensorflow as tf
import numpy as np

Ekstrak irisan tensor

Lakukan pemotongan tensor seperti NumPy menggunakan 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)

Atau, Anda dapat menggunakan sintaks yang lebih Pythonic. Perhatikan bahwa irisan tensor ditempatkan secara merata pada rentang 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)

Untuk tensor 2 dimensi, Anda dapat menggunakan sesuatu seperti:

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)

Anda juga dapat menggunakan tf.slice pada tensor berdimensi lebih tinggi.

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)

Anda juga dapat menggunakan tf.strided_slice untuk mengekstrak irisan tensor dengan 'melangkah' di atas dimensi tensor.

Gunakan tf.gather untuk mengekstrak indeks tertentu dari sumbu tunggal 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 tidak memerlukan indeks untuk ditempatkan secara merata.

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)

Untuk mengekstrak irisan dari beberapa sumbu tensor, gunakan tf.gather_nd . Ini berguna saat Anda ingin mengumpulkan elemen matriks, bukan hanya baris atau kolomnya.

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)

Masukkan data ke dalam tensor

Gunakan tf.scatter_nd untuk menyisipkan data pada irisan/indeks tertentu dari sebuah tensor. Perhatikan bahwa tensor tempat Anda memasukkan nilai diinisialisasi nol.

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)

Metode seperti tf.scatter_nd yang membutuhkan tensor yang diinisialisasi nol mirip dengan inisialisasi tensor sparse. Anda dapat menggunakan tf.gather_nd dan tf.scatter_nd untuk meniru perilaku operasi sparse tensor.

Pertimbangkan contoh di mana Anda membuat tensor sparse menggunakan dua metode ini secara bersamaan.

# 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)

Ini mirip dengan:

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)

Untuk memasukkan data ke dalam tensor dengan nilai yang sudah ada sebelumnya, gunakan 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)

Demikian pula, gunakan tf.tensor_scatter_nd_sub untuk mengurangi nilai dari tensor dengan nilai yang sudah ada sebelumnya.

# 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)

Gunakan tf.tensor_scatter_nd_min untuk menyalin nilai minimum berdasarkan elemen dari satu tensor ke tensor lainnya.

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)

Demikian pula, gunakan tf.tensor_scatter_nd_max untuk menyalin nilai maksimum berdasarkan elemen dari satu tensor ke tensor lainnya.

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)

Bacaan lebih lanjut dan sumber daya

Dalam panduan ini, Anda mempelajari cara menggunakan operasi pemotongan tensor yang tersedia dengan TensorFlow untuk memberikan kontrol yang lebih baik atas elemen-elemen di tensor Anda.