Tensör dilimlemeye giriş

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

Nesne algılama ve NLP gibi ML uygulamaları üzerinde çalışırken bazen tensörlerin alt bölümleri (dilimleri) ile çalışmak gerekir. Örneğin, model mimariniz yönlendirme içeriyorsa, burada bir katman hangi eğitim örneğinin sonraki katmana yönlendirileceğini kontrol edebilir. Bu durumda, tensörleri bölmek ve doğru sırayla tekrar bir araya getirmek için tensör dilimleme işlemlerini kullanabilirsiniz.

NLP uygulamalarında, eğitim sırasında kelime maskeleme yapmak için tensör dilimlemeyi kullanabilirsiniz. Örneğin, her cümlede maskelenecek bir kelime dizini seçerek, kelimeyi etiket olarak çıkararak ve ardından seçilen kelimeyi bir maske simgesiyle değiştirerek bir cümle listesinden eğitim verileri oluşturabilirsiniz.

Bu kılavuzda, TensorFlow API'lerini aşağıdakiler için nasıl kullanacağınızı öğreneceksiniz:

  • Bir tensörden dilimleri ayıklayın
  • Bir tensörde belirli indekslerde veri ekleme

Bu kılavuz, tensör indekslemeye aşina olduğunuzu varsayar. Bu kılavuza başlamadan önce Tensor ve TensorFlow NumPy kılavuzlarının indeksleme bölümlerini okuyun.

Kurmak

import tensorflow as tf
import numpy as np

Tensör dilimlerini ayıklayın

tf.slice kullanarak tf.slice benzeri tensör dilimleme gerçekleştirin.

t1 = tf.constant([0, 1, 2, 3, 4, 5, 6, 7])

print(tf.slice(t1,
               begin=[1],
               size=[3]))
tutucu2 l10n-yer
tf.Tensor([1 2 3], shape=(3,), dtype=int32)

Alternatif olarak, daha Pythonic bir sözdizimi kullanabilirsiniz. Tensör dilimlerinin bir start-stop aralığında eşit aralıklarla yerleştirildiğini unutmayın.

print(t1[1:4])
tutucu4 l10n-yer
tf.Tensor([1 2 3], shape=(3,), dtype=int32)

print(t1[-3:])
tutucu6 l10n-yer
tf.Tensor([5 6 7], shape=(3,), dtype=int32)

2 boyutlu tensörler için şöyle bir şey kullanabilirsiniz:

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])
tutucu8 l10n-yer
tf.Tensor(
[[ 1  2]
 [ 6  7]
 [11 12]], shape=(3, 2), dtype=int32)

tf.slice daha yüksek boyutlu tensörlerde de kullanabilirsiniz.

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]))
tutucu10 l10n-yer
tf.Tensor([[[25 27]]], shape=(1, 1, 2), dtype=int32)

Ayrıca, tensör boyutları üzerinde 'uzun adımlarla' geçerek tensör dilimlerini çıkarmak için tf.strided_slice kullanabilirsiniz.

Bir tensörün tek bir ekseninden belirli indeksleri çıkarmak için tf.gather kullanın.

print(tf.gather(t1,
                indices=[0, 3, 6]))

# This is similar to doing

t1[::3]
tutucu12 l10n-yer
tf.Tensor([0 3 6], shape=(3,), dtype=int32)
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([0, 3, 6], dtype=int32)>

tf.gather , dizinlerin eşit aralıklı olmasını gerektirmez.

alphabet = tf.constant(list('abcdefghijklmnopqrstuvwxyz'))

print(tf.gather(alphabet,
                indices=[2, 0, 19, 18]))
tutucu14 l10n-yer
tf.Tensor([b'c' b'a' b't' b's'], shape=(4,), dtype=string)

Bir tensörün birden çok ekseninden dilimleri çıkarmak için tf.gather_nd kullanın. Bu, yalnızca satırları veya sütunları yerine bir matrisin öğelerini toplamak istediğinizde kullanışlıdır.

t4 = tf.constant([[0, 5],
                  [1, 6],
                  [2, 7],
                  [3, 8],
                  [4, 9]])

print(tf.gather_nd(t4,
                   indices=[[2], [3], [0]]))
tutucu16 l10n-yer
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)

Tensörlere veri ekleme

Bir tensörün belirli dilimlerine/endekslerine veri eklemek için tf.scatter_nd kullanın. Değer eklediğiniz tensörün sıfır başlatılmış olduğuna dikkat edin.

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))
tutucu24 l10n-yer
tf.Tensor([ 0  2  0  4  0  6  0  8  0 10], shape=(10,), dtype=int32)

Sıfır başlatılmış tensörler gerektiren tf.scatter_nd gibi yöntemler, seyrek tensör başlatıcılara benzer. Seyrek tensör işlemlerinin davranışını taklit etmek için tf.gather_nd ve tf.scatter_nd kullanabilirsiniz.

Bu iki yöntemi birlikte kullanarak seyrek bir tensör oluşturduğunuz bir örnek düşünün.

# 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)
tutucu27 l10n-yer
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)

Bu şuna benzer:

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))
yer tutucu30 l10n-yer
# 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)

Önceden var olan değerlere sahip bir tensöre veri eklemek için tf.tensor_scatter_nd_add kullanın.

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)
tutucu33 l10n-yer
tf.Tensor(
[[2 7 6]
 [9 5 1]
 [4 3 8]], shape=(3, 3), dtype=int32)

Benzer şekilde, önceden var olan değerlere sahip bir tensörden değerleri çıkarmak için tf.tensor_scatter_nd_sub kullanın.

# 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)
tutucu35 l10n-yer
tf.Tensor(
[[1 0 0]
 [0 1 0]
 [0 0 1]], shape=(3, 3), dtype=int32)

Öğe bazında minimum değerleri bir tf.tensor_scatter_nd_min diğerine kopyalamak için tf.tensor_scatter_nd_min kullanın.

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)
tutucu37 l10n-yer
tf.Tensor(
[[-2 -7 -6]
 [-9 -5  1]
 [-4 -3 -8]], shape=(3, 3), dtype=int32)

Benzer şekilde, eleman bazında maksimum değerleri bir tf.tensor_scatter_nd_max diğerine kopyalamak için tf.tensor_scatter_nd_max kullanın.

t16 = tf.tensor_scatter_nd_max(t14,
                               indices=[[0, 2], [1, 1], [2, 0]],
                               updates=[6, 5, 4])

print(t16)
tutucu39 l10n-yer
tf.Tensor(
[[-2 -7  6]
 [-9  5  1]
 [ 4 -3 -8]], shape=(3, 3), dtype=int32)

Daha fazla okuma ve kaynaklar

Bu kılavuzda, tensörlerinizdeki öğeler üzerinde daha hassas kontrol uygulamak için TensorFlow'da bulunan tensör dilimleme işlemlerini nasıl kullanacağınızı öğrendiniz.