Ragged Tensor qui représente des données de longueur variable introduites dans TensorFlow 2.1 ou version ultérieure, mais si vous essayez d'écrire avec de la colle Tensor ordinaire, il existe plusieurs J'en suis accro. Cette fois, l'édition de traitement de fenêtre qui semble être utilisée pour le traitement du signal. Une image avec une certaine largeur de temps est décalée petit à petit pour extraire une forme d'onde qui se situe dans la plage de l'image.
Considérez `` x '' comme un lot et découpez une courte section de forme d'onde pour chaque ligne de données. La longueur des données varie. Ici, la largeur du cadre est définie sur 2 et la position de découpe est décalée de 1. "[3, 1, 4, 1]" est comme "[[3, 1], [1, 4], [4, 1]]".
Pour le Tensor '' habituel, il existe une fonction pratique appelée [tf.signal.frame](https://www.tensorflow.org/api_docs/python/tf/signal/frame), mais malheureusement ` Il ne peut pas être utilisé pour
RaggedTensor ''.
x = tf.ragged.constant([[3, 1, 4, 1], [], [5, 9, 2], [6], []])
print(tf.signal.frame(x, 2, 1)) # NG
# ValueError: TypeError: object of type 'RaggedTensor' has no len()
print(tf.signal.frame(x.to_tensor(), 2, 1)) #Cela fonctionne, mais beaucoup de 0 supplémentaires sortent
# tf.Tensor(
# [[[3 1]
# [1 4]
# [4 1]]
#
# [[0 0]
# [0 0]
# [0 0]]
#
# [[5 9]
# [9 2]
# [2 0]]
#
# [[6 0]
# [0 0]
# [0 0]]
#
# [[0 0]
# [0 0]
# [0 0]]], shape=(5, 3, 2), dtype=int32)
Basé sur x.values '', qui représente les valeurs qui sont aplaties hors de la dimension du lot, et la longueur et le décalage de chaque ligne obtenue à partir de
RaggedTensor ''.
print(x.values) #Tenseur avec valeurs
# tf.Tensor([3 1 4 1 5 9 2 6], shape=(8,), dtype=int32)
print(x.row_starts()) #Index de départ (offset) de chaque ligne en valeurs
# tf.Tensor([0 4 4 7 8], shape=(5,), dtype=int64)
print(x.row_lengths()) #Longueur de chaque ligne
# tf.Tensor([4 0 3 1 0], shape=(5,), dtype=int64)
Pour chaque ligne de x '', considérez à partir de quel index de
x.values`` les valeurs doivent être extraites (*).
--La ligne 0 est `` [0, 1], [1, 2], [2, 3] ''
Tout d'abord, si vous créez un RaggedTensor
qui a le premier index de (*)
s = x.row_starts()
e = s + x.row_lengths() - 1
r = tf.ragged.range(s, e)
print(r)
# <tf.RaggedTensor [[0, 1, 2], [], [4, 5], [], []]>
De plus, si vous combinez ceux qui ont été avancés par un index, vous pouvez voir où dans x.values
vous devez amener les valeurs pour le résultat attendu après le traitement de la fenêtre. Les résultats correspondent au bulletin précédent (*).
ind = tf.stack([r, r+1], axis=2)
print(ind)
# <tf.RaggedTensor [[[0, 1], [1, 2], [2, 3]], [], [[4, 5], [5, 6]], [], []]>
Après cela, vous pouvez utiliser tf.gather ()
pour obtenir les valeurs de x.values
en fonction de l'index entré dans ```ind``.
ret = tf.gather(x.values, ind)
print(ret)
# <tf.RaggedTensor [[[3, 1], [1, 4], [4, 1]], [], [[5, 9], [9, 2]], [], []]>
La façon de faire «e» et «ind» est un peu différente, mais l'idée générale est la même. La diffusion est utilisée pour créer «ind». Pour cela, une dimension de longueur 1 est ajoutée à la fin comme `` r [:,:, tf.newaxis] ''.
len_frame = 3
s = x.row_starts()
e = s + x.row_lengths() + 1 - len_frame
r = tf.ragged.range(s, e)
ind = r[:, :, tf.newaxis] + tf.range(0, len_frame, dtype="int64")
ret = tf.gather(x.values, ind)
print(ret)
# <tf.RaggedTensor [[[3, 1, 4], [1, 4, 1]], [], [[5, 9, 2]], [], []]>
Bien sûr, il peut être utilisé même lorsque `` len_frame = 2 ''.
Ce n'est pas grave si vous modifiez la taille de pas de `` r ''.
len_frame = 2
shift_frame = 2
s = x.row_starts()
e = s + x.row_lengths() + 1 - len_frame
r = tf.ragged.range(s, e, shift_frame)
ind = r[:, :, tf.newaxis] + tf.range(0, len_frame, dtype="int64")
ret = tf.gather(x.values, ind)
print(ret)
# <tf.RaggedTensor [[[3, 1], [4, 1]], [], [[5, 9]], [], []]>
Vous pouvez également utiliser `` shift_frame = 1 ''.
Par exemple, en audio stéréo, les valeurs L et R sont stockées sous forme de paire.
x = tf.ragged.constant([[[3, 2], [1, 7], [4, 1], [1, 8]], [], [[5, 2], [9, 8], [2, 1]], [[6, 8]], []])
En fait, cela fonctionne exactement de la même manière qu'avant.
len_frame = 2
shift_frame = 1
s = x.row_starts()
e = s + x.row_lengths() + 1 - len_frame
r = tf.ragged.range(s, e, shift_frame)
ind = r[:, :, tf.newaxis] + tf.range(0, len_frame, dtype="int64")
ret = tf.gather(x.values, ind)
print(ret)
# <tf.RaggedTensor [[[[3, 2], [1, 7]], [[1, 7], [4, 1]], [[4, 1], [1, 8]]], [], [[[5, 2], [9, 8]], [[9, 8], [2, 1]]], [], []]>
Le nombre de dimensions a tellement augmenté que je ne peux pas dire si ça va juste en le regardant, mais ça devrait aller ...
Recommended Posts