Bantuan melindungi Great Barrier Reef dengan TensorFlow pada Kaggle Bergabung Tantangan

Tensor kasar

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHubUnduh buku catatan

Dokumentasi API: tf.RaggedTensor tf.ragged

Mempersiapkan

import math
import tensorflow as tf

Gambaran

Data Anda datang dalam berbagai bentuk; tensor Anda juga harus. Tensor compang-camping adalah setara TensorFlow dari bersarang daftar variabel-panjang. Mereka memudahkan untuk menyimpan dan memproses data dengan bentuk yang tidak seragam, termasuk:

  • Fitur panjang variabel, seperti set aktor dalam film.
  • Kumpulan input berurutan dengan panjang variabel, seperti kalimat atau klip video.
  • Input hierarkis, seperti dokumen teks yang dibagi lagi menjadi beberapa bagian, paragraf, kalimat, dan kata.
  • Bidang individu dalam input terstruktur, seperti buffer protokol.

Apa yang dapat Anda lakukan dengan tensor compang-camping

Tensor compang-camping yang didukung oleh lebih dari seratus operasi TensorFlow, termasuk operasi matematika (seperti tf.add dan tf.reduce_mean ), operasi array (seperti tf.concat dan tf.tile ), ops manipulasi string (seperti tf.substr ), flow control operasi (seperti tf.while_loop dan tf.map_fn ), dan banyak lainnya:

digits = tf.ragged.constant([[3, 1, 4, 1], [], [5, 9, 2], [6], []])
words = tf.ragged.constant([["So", "long"], ["thanks", "for", "all", "the", "fish"]])
print(tf.add(digits, 3))
print(tf.reduce_mean(digits, axis=1))
print(tf.concat([digits, [[5, 3]]], axis=0))
print(tf.tile(digits, [1, 2]))
print(tf.strings.substr(words, 0, 2))
print(tf.map_fn(tf.math.square, digits))
<tf.RaggedTensor [[6, 4, 7, 4], [], [8, 12, 5], [9], []]>
tf.Tensor([2.25              nan 5.33333333 6.                nan], shape=(5,), dtype=float64)
<tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], [], [5, 3]]>
<tf.RaggedTensor [[3, 1, 4, 1, 3, 1, 4, 1], [], [5, 9, 2, 5, 9, 2], [6, 6], []]>
<tf.RaggedTensor [[b'So', b'lo'], [b'th', b'fo', b'al', b'th', b'fi']]>
<tf.RaggedTensor [[9, 1, 16, 1], [], [25, 81, 4], [36], []]>

Ada juga sejumlah metode dan operasi yang khusus untuk tensor kasar, termasuk metode pabrik, metode konversi, dan operasi pemetaan nilai. Untuk daftar ops didukung, lihat tf.ragged dokumentasi paket.

Tensor compang-camping yang didukung oleh banyak API TensorFlow, termasuk Keras , dataset , tf.function , SavedModels , dan tf.Example . Untuk informasi lebih lanjut, periksa bagian pada TensorFlow API di bawah ini.

Seperti halnya tensor normal, Anda dapat menggunakan pengindeksan gaya Python untuk mengakses irisan tertentu dari tensor yang tidak rata. Untuk informasi lebih lanjut, lihat bagian pada Indexing bawah.

print(digits[0])       # First row
tf.Tensor([3 1 4 1], shape=(4,), dtype=int32)
print(digits[:, :2])   # First two values in each row.
<tf.RaggedTensor [[3, 1], [], [5, 9], [6], []]>
print(digits[:, -2:])  # Last two values in each row.
<tf.RaggedTensor [[4, 1], [], [9, 2], [6], []]>

Dan seperti tensor normal, Anda dapat menggunakan aritmatika Python dan operator perbandingan untuk melakukan operasi elemen. Untuk informasi lebih lanjut, periksa bagian pada operator kelebihan beban di bawah ini.

print(digits + 3)
<tf.RaggedTensor [[6, 4, 7, 4], [], [8, 12, 5], [9], []]>
print(digits + tf.ragged.constant([[1, 2, 3, 4], [], [5, 6, 7], [8], []]))
<tf.RaggedTensor [[4, 3, 7, 5], [], [10, 15, 9], [14], []]>

Jika Anda perlu melakukan transformasi elementwise dengan nilai-nilai dari RaggedTensor , Anda dapat menggunakan tf.ragged.map_flat_values , yang mengambil fungsi ditambah satu atau lebih argumen, dan berlaku fungsi untuk mengubah RaggedTensor nilai 's.

times_two_plus_one = lambda x: x * 2 + 1
print(tf.ragged.map_flat_values(times_two_plus_one, digits))
<tf.RaggedTensor [[7, 3, 9, 3], [], [11, 19, 5], [13], []]>

Tensor compang-camping dapat dikonversi ke bersarang Python list dan NumPy array s:

digits.to_list()
[[3, 1, 4, 1], [], [5, 9, 2], [6], []]
digits.numpy()
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/ops/ragged/ragged_tensor.py:2063: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  return np.array(rows)
array([array([3, 1, 4, 1], dtype=int32), array([], dtype=int32),
       array([5, 9, 2], dtype=int32), array([6], dtype=int32),
       array([], dtype=int32)], dtype=object)

Membangun tensor yang tidak rata

Cara paling mudah untuk membangun sebuah tensor compang-camping menggunakan tf.ragged.constant , yang membangun RaggedTensor yang berhubungan dengan Python diberikan bersarang list atau NumPy array :

sentences = tf.ragged.constant([
    ["Let's", "build", "some", "ragged", "tensors", "!"],
    ["We", "can", "use", "tf.ragged.constant", "."]])
print(sentences)
<tf.RaggedTensor [[b"Let's", b'build', b'some', b'ragged', b'tensors', b'!'], [b'We', b'can', b'use', b'tf.ragged.constant', b'.']]>
paragraphs = tf.ragged.constant([
    [['I', 'have', 'a', 'cat'], ['His', 'name', 'is', 'Mat']],
    [['Do', 'you', 'want', 'to', 'come', 'visit'], ["I'm", 'free', 'tomorrow']],
])
print(paragraphs)
<tf.RaggedTensor [[[b'I', b'have', b'a', b'cat'], [b'His', b'name', b'is', b'Mat']], [[b'Do', b'you', b'want', b'to', b'come', b'visit'], [b"I'm", b'free', b'tomorrow']]]>

Tensor compang-camping juga dapat dibangun dengan pasangan nilai datar tensor dengan tensor baris-partisi yang menunjukkan bagaimana nilai-nilai harus dibagi ke dalam baris, menggunakan classmethods pabrik seperti tf.RaggedTensor.from_value_rowids , tf.RaggedTensor.from_row_lengths , dan tf.RaggedTensor.from_row_splits .

tf.RaggedTensor.from_value_rowids

Jika Anda tahu mana baris setiap nilai milik, maka Anda dapat membangun RaggedTensor menggunakan value_rowids tensor baris-partisi:

value_rowids tensor partisi baris

print(tf.RaggedTensor.from_value_rowids(
    values=[3, 1, 4, 1, 5, 9, 2],
    value_rowids=[0, 0, 0, 0, 2, 2, 3]))
<tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9], [2]]>

tf.RaggedTensor.from_row_lengths

Jika Anda tahu berapa lama setiap baris, maka Anda dapat menggunakan row_lengths tensor baris-partisi:

row_lengths tensor partisi baris

print(tf.RaggedTensor.from_row_lengths(
    values=[3, 1, 4, 1, 5, 9, 2],
    row_lengths=[4, 0, 2, 1]))
<tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9], [2]]>

tf.RaggedTensor.from_row_splits

Jika Anda tahu indeks di mana setiap baris dimulai dan berakhir, maka Anda dapat menggunakan row_splits tensor baris-partisi:

row_splits tensor partisi baris

print(tf.RaggedTensor.from_row_splits(
    values=[3, 1, 4, 1, 5, 9, 2],
    row_splits=[0, 4, 4, 6, 7]))
<tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9], [2]]>

Lihat tf.RaggedTensor dokumentasi kelas untuk daftar lengkap dari metode pabrik.

Apa yang dapat Anda simpan dalam tensor yang compang-camping

Seperti biasa Tensor s, nilai-nilai dalam RaggedTensor semua harus memiliki tipe yang sama; dan nilai-nilai semua harus berada di kedalaman nesting yang sama (pangkat tensor):

print(tf.ragged.constant([["Hi"], ["How", "are", "you"]]))  # ok: type=string, rank=2
<tf.RaggedTensor [[b'Hi'], [b'How', b'are', b'you']]>
print(tf.ragged.constant([[[1, 2], [3]], [[4, 5]]]))        # ok: type=int32, rank=3
<tf.RaggedTensor [[[1, 2], [3]], [[4, 5]]]>
try:
  tf.ragged.constant([["one", "two"], [3, 4]])              # bad: multiple types
except ValueError as exception:
  print(exception)
Can't convert Python sequence with mixed types to Tensor.
try:
  tf.ragged.constant(["A", ["B", "C"]])                     # bad: multiple nesting depths
except ValueError as exception:
  print(exception)
all scalar values must have the same nesting depth

Contoh kasus penggunaan

Contoh berikut menunjukkan bagaimana RaggedTensor s dapat digunakan untuk membangun dan menggabungkan unigram dan bigram embeddings untuk batch query variabel-panjang, dengan menggunakan spidol khusus untuk awal dan akhir dari setiap kalimat. Untuk rincian lebih lanjut tentang ops digunakan dalam contoh ini, periksa tf.ragged dokumentasi paket.

queries = tf.ragged.constant([['Who', 'is', 'Dan', 'Smith'],
                              ['Pause'],
                              ['Will', 'it', 'rain', 'later', 'today']])

# Create an embedding table.
num_buckets = 1024
embedding_size = 4
embedding_table = tf.Variable(
    tf.random.truncated_normal([num_buckets, embedding_size],
                       stddev=1.0 / math.sqrt(embedding_size)))

# Look up the embedding for each word.
word_buckets = tf.strings.to_hash_bucket_fast(queries, num_buckets)
word_embeddings = tf.nn.embedding_lookup(embedding_table, word_buckets)     # ①

# Add markers to the beginning and end of each sentence.
marker = tf.fill([queries.nrows(), 1], '#')
padded = tf.concat([marker, queries, marker], axis=1)                       # ②

# Build word bigrams and look up embeddings.
bigrams = tf.strings.join([padded[:, :-1], padded[:, 1:]], separator='+')   # ③

bigram_buckets = tf.strings.to_hash_bucket_fast(bigrams, num_buckets)
bigram_embeddings = tf.nn.embedding_lookup(embedding_table, bigram_buckets) # ④

# Find the average embedding for each sentence
all_embeddings = tf.concat([word_embeddings, bigram_embeddings], axis=1)    # ⑤
avg_embedding = tf.reduce_mean(all_embeddings, axis=1)                      # ⑥
print(avg_embedding)
tf.Tensor(
[[-0.14285272  0.02908629 -0.16327512 -0.14529026]
 [-0.4479212  -0.35615516  0.17110227  0.2522229 ]
 [-0.1987868  -0.13152348 -0.0325102   0.02125177]], shape=(3, 4), dtype=float32)

Contoh tensor kasar

Dimensi kasar dan seragam

Dimensi compang-camping adalah dimensi yang irisan mungkin memiliki panjang yang berbeda. Sebagai contoh, dalam (kolom) dimensi rt=[[3, 1, 4, 1], [], [5, 9, 2], [6], []] adalah compang-camping, karena irisan kolom ( rt[0, :] , ..., rt[4, :] ) memiliki panjang yang berbeda. Dimensi yang irisan semua memiliki panjang yang sama disebut dimensi seragam.

Dimensi terluar dari ragged tensor selalu seragam, karena terdiri dari satu irisan (dan, oleh karena itu, tidak ada kemungkinan untuk panjang irisan yang berbeda). Dimensi yang tersisa dapat berupa compang-camping atau seragam. Sebagai contoh, Anda mungkin menyimpan embeddings kata untuk setiap kata dalam batch kalimat menggunakan tensor compang-camping dengan bentuk [num_sentences, (num_words), embedding_size] , di mana tanda kurung di sekitar (num_words) menunjukkan bahwa dimensi yang compang-camping.

Penyematan kata menggunakan tensor kasar

Tensor yang tidak rata mungkin memiliki beberapa dimensi yang tidak rata. Misalnya, Anda bisa menyimpan batch dokumen teks terstruktur menggunakan tensor dengan bentuk [num_documents, (num_paragraphs), (num_sentences), (num_words)] (di mana lagi kurung digunakan untuk menunjukkan dimensi compang-camping).

Seperti tf.Tensor , pangkat dari tensor compang-camping adalah jumlah total dari dimensi (termasuk dimensi compang-camping dan seragam). Sebuah tensor berpotensi compang-camping adalah nilai yang mungkin baik tf.Tensor atau tf.RaggedTensor .

Saat mendeskripsikan bentuk RaggedTensor, dimensi kasar secara konvensional ditunjukkan dengan melampirkannya dalam tanda kurung. Misalnya, seperti yang Anda lihat di atas, bentuk sebuah RaggedTensor 3D yang embeddings toko kata untuk setiap kata dalam batch kalimat dapat ditulis sebagai [num_sentences, (num_words), embedding_size] .

The RaggedTensor.shape atribut mengembalikan tf.TensorShape untuk tensor compang-camping di mana dimensi compang-camping memiliki ukuran None :

tf.ragged.constant([["Hi"], ["How", "are", "you"]]).shape
TensorShape([2, None])

Metode tf.RaggedTensor.bounding_shape dapat digunakan untuk menemukan bentuk bounding ketat untuk diberikan RaggedTensor :

print(tf.ragged.constant([["Hi"], ["How", "are", "you"]]).bounding_shape())
tf.Tensor([2 3], shape=(2,), dtype=int64)

Kasar vs jarang

Sebuah tensor compang-camping seharusnya tidak dianggap sebagai jenis tensor jarang. Secara khusus, tensor jarang yang pengkodean efisien untuk tf.Tensor bahwa model data yang sama dalam format yang kompak; tapi tensor compang-camping adalah perluasan untuk tf.Tensor bahwa model kelas diperluas data. Perbedaan ini sangat penting ketika mendefinisikan operasi:

  • Menerapkan op ke tensor yang jarang atau padat harus selalu memberikan hasil yang sama.
  • Menerapkan op ke tensor yang tidak rata atau jarang dapat memberikan hasil yang berbeda.

Sebagai contoh ilustratif, mempertimbangkan bagaimana operasi array yang seperti concat , stack , dan tile yang ditetapkan untuk compang-camping vs jarang tensor. Tensor kasar yang digabungkan bergabung dengan setiap baris untuk membentuk satu baris dengan panjang gabungan:

Menggabungkan tensor compang-camping

ragged_x = tf.ragged.constant([["John"], ["a", "big", "dog"], ["my", "cat"]])
ragged_y = tf.ragged.constant([["fell", "asleep"], ["barked"], ["is", "fuzzy"]])
print(tf.concat([ragged_x, ragged_y], axis=1))
<tf.RaggedTensor [[b'John', b'fell', b'asleep'], [b'a', b'big', b'dog', b'barked'], [b'my', b'cat', b'is', b'fuzzy']]>

Namun, menggabungkan tensor jarang sama dengan menggabungkan tensor padat yang sesuai, seperti yang diilustrasikan oleh contoh berikut (di mana menunjukkan nilai yang hilang):

Menggabungkan tensor jarang

sparse_x = ragged_x.to_sparse()
sparse_y = ragged_y.to_sparse()
sparse_result = tf.sparse.concat(sp_inputs=[sparse_x, sparse_y], axis=1)
print(tf.sparse.to_dense(sparse_result, ''))
tf.Tensor(
[[b'John' b'' b'' b'fell' b'asleep']
 [b'a' b'big' b'dog' b'barked' b'']
 [b'my' b'cat' b'' b'is' b'fuzzy']], shape=(3, 5), dtype=string)

Misalnya lain mengapa perbedaan ini penting, mempertimbangkan definisi “nilai rata-rata dari setiap baris” untuk op seperti tf.reduce_mean . Untuk tensor yang tidak rata, nilai rata-rata untuk suatu baris adalah jumlah nilai baris dibagi dengan lebar baris. Tetapi untuk tensor jarang, nilai rata-rata untuk suatu baris adalah jumlah nilai baris dibagi dengan lebar keseluruhan tensor jarang (yang lebih besar dari atau sama dengan lebar baris terpanjang).

API TensorFlow

Keras

tf.keras adalah TensorFlow API tingkat tinggi untuk membangun dan melatih model pembelajaran yang mendalam. Tensor compang-camping dapat lulus sebagai masukan untuk model Keras oleh pengaturan ragged=True pada tf.keras.Input atau tf.keras.layers.InputLayer . Tensor kasar juga dapat dilewatkan di antara lapisan Keras, dan dikembalikan oleh model Keras. Contoh berikut menunjukkan model LSTM mainan yang dilatih menggunakan tensor kasar.

# Task: predict whether each sentence is a question or not.
sentences = tf.constant(
    ['What makes you think she is a witch?',
     'She turned me into a newt.',
     'A newt?',
     'Well, I got better.'])
is_question = tf.constant([True, False, True, False])

# Preprocess the input strings.
hash_buckets = 1000
words = tf.strings.split(sentences, ' ')
hashed_words = tf.strings.to_hash_bucket_fast(words, hash_buckets)

# Build the Keras model.
keras_model = tf.keras.Sequential([
    tf.keras.layers.Input(shape=[None], dtype=tf.int64, ragged=True),
    tf.keras.layers.Embedding(hash_buckets, 16),
    tf.keras.layers.LSTM(32, use_bias=False),
    tf.keras.layers.Dense(32),
    tf.keras.layers.Activation(tf.nn.relu),
    tf.keras.layers.Dense(1)
])

keras_model.compile(loss='binary_crossentropy', optimizer='rmsprop')
keras_model.fit(hashed_words, is_question, epochs=5)
print(keras_model.predict(hashed_words))
WARNING:tensorflow:Layer lstm will not use cuDNN kernels since it doesn't meet the criteria. It will use a generic GPU kernel as fallback when running on GPU.
Epoch 1/5
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/framework/indexed_slices.py:449: UserWarning: Converting sparse IndexedSlices(IndexedSlices(indices=Tensor("gradient_tape/sequential/lstm/RaggedToTensor/boolean_mask_1/GatherV2:0", shape=(None,), dtype=int32), values=Tensor("gradient_tape/sequential/lstm/RaggedToTensor/boolean_mask/GatherV2:0", shape=(None, 16), dtype=float32), dense_shape=Tensor("gradient_tape/sequential/lstm/RaggedToTensor/Shape:0", shape=(2,), dtype=int32))) to a dense Tensor of unknown shape. This may consume a large amount of memory.
  "shape. This may consume a large amount of memory." % value)
1/1 [==============================] - 2s 2s/step - loss: 3.1269
Epoch 2/5
1/1 [==============================] - 0s 18ms/step - loss: 2.1197
Epoch 3/5
1/1 [==============================] - 0s 19ms/step - loss: 2.0196
Epoch 4/5
1/1 [==============================] - 0s 20ms/step - loss: 1.9371
Epoch 5/5
1/1 [==============================] - 0s 18ms/step - loss: 1.8857
[[0.02800461]
 [0.00945962]
 [0.02283431]
 [0.00252927]]

tf.Contoh

tf.Example adalah standar protobuf pengkodean untuk data TensorFlow. Data dikodekan dengan tf.Example s sering mencakup fitur variabel-panjang. Sebagai contoh, kode berikut mendefinisikan batch empat tf.Example pesan dengan panjang fitur yang berbeda:

import google.protobuf.text_format as pbtext

def build_tf_example(s):
  return pbtext.Merge(s, tf.train.Example()).SerializeToString()

example_batch = [
  build_tf_example(r'''
    features {
      feature {key: "colors" value {bytes_list {value: ["red", "blue"]} } }
      feature {key: "lengths" value {int64_list {value: [7]} } } }'''),
  build_tf_example(r'''
    features {
      feature {key: "colors" value {bytes_list {value: ["orange"]} } }
      feature {key: "lengths" value {int64_list {value: []} } } }'''),
  build_tf_example(r'''
    features {
      feature {key: "colors" value {bytes_list {value: ["black", "yellow"]} } }
      feature {key: "lengths" value {int64_list {value: [1, 3]} } } }'''),
  build_tf_example(r'''
    features {
      feature {key: "colors" value {bytes_list {value: ["green"]} } }
      feature {key: "lengths" value {int64_list {value: [3, 5, 2]} } } }''')]

Anda dapat mengurai data yang dikodekan ini menggunakan tf.io.parse_example , yang membutuhkan tensor string serial dan kamus spesifikasi fitur, dan kembali kamus nama fitur pemetaan untuk tensor. Untuk membaca fitur variable-length ke tensor compang-camping, Anda hanya menggunakan tf.io.RaggedFeature dalam kamus spesifikasi fitur:

feature_specification = {
    'colors': tf.io.RaggedFeature(tf.string),
    'lengths': tf.io.RaggedFeature(tf.int64),
}
feature_tensors = tf.io.parse_example(example_batch, feature_specification)
for name, value in feature_tensors.items():
  print("{}={}".format(name, value))
colors=<tf.RaggedTensor [[b'red', b'blue'], [b'orange'], [b'black', b'yellow'], [b'green']]>
lengths=<tf.RaggedTensor [[7], [], [1, 3], [3, 5, 2]]>

tf.io.RaggedFeature juga dapat digunakan untuk membaca fitur dengan beberapa dimensi compang-camping. Untuk rincian, lihat dokumentasi API .

Kumpulan data

tf.data adalah API yang memungkinkan Anda untuk membangun jaringan pipa masukan kompleks dari yang sederhana, potongan dapat digunakan kembali. Struktur data intinya adalah tf.data.Dataset , yang merupakan urutan elemen, di mana setiap elemen terdiri dari satu atau lebih komponen.

# Helper function used to print datasets in the examples below.
def print_dictionary_dataset(dataset):
  for i, element in enumerate(dataset):
    print("Element {}:".format(i))
    for (feature_name, feature_value) in element.items():
      print('{:>14} = {}'.format(feature_name, feature_value))

Membangun Kumpulan Data dengan tensor kasar

Dataset dapat dibangun dari tensor compang-camping menggunakan metode yang sama yang digunakan untuk membangun mereka dari tf.Tensor s atau NumPy array s, seperti Dataset.from_tensor_slices :

dataset = tf.data.Dataset.from_tensor_slices(feature_tensors)
print_dictionary_dataset(dataset)
Element 0:
        colors = [b'red' b'blue']
       lengths = [7]
Element 1:
        colors = [b'orange']
       lengths = []
Element 2:
        colors = [b'black' b'yellow']
       lengths = [1 3]
Element 3:
        colors = [b'green']
       lengths = [3 5 2]

Batching dan unbatching Dataset dengan tensor kasar

Dataset dengan tensor compang-camping dapat batched (yang menggabungkan n elemen berturut-turut menjadi elemen tunggal) menggunakan Dataset.batch metode.

batched_dataset = dataset.batch(2)
print_dictionary_dataset(batched_dataset)
Element 0:
        colors = <tf.RaggedTensor [[b'red', b'blue'], [b'orange']]>
       lengths = <tf.RaggedTensor [[7], []]>
Element 1:
        colors = <tf.RaggedTensor [[b'black', b'yellow'], [b'green']]>
       lengths = <tf.RaggedTensor [[1, 3], [3, 5, 2]]>

Sebaliknya, dataset batched dapat diubah menjadi dataset datar menggunakan Dataset.unbatch .

unbatched_dataset = batched_dataset.unbatch()
print_dictionary_dataset(unbatched_dataset)
Element 0:
        colors = [b'red' b'blue']
       lengths = [7]
Element 1:
        colors = [b'orange']
       lengths = []
Element 2:
        colors = [b'black' b'yellow']
       lengths = [1 3]
Element 3:
        colors = [b'green']
       lengths = [3 5 2]

Batching Dataset dengan tensor non-ragged dengan panjang variabel

Jika Anda memiliki Dataset yang berisi tensor non-compang-camping, dan tensor panjang bervariasi di seluruh elemen, maka Anda dapat batch mereka tensor non-compang-camping dalam tensor compang-camping dengan menerapkan dense_to_ragged_batch transformasi:

non_ragged_dataset = tf.data.Dataset.from_tensor_slices([1, 5, 3, 2, 8])
non_ragged_dataset = non_ragged_dataset.map(tf.range)
batched_non_ragged_dataset = non_ragged_dataset.apply(
    tf.data.experimental.dense_to_ragged_batch(2))
for element in batched_non_ragged_dataset:
  print(element)
<tf.RaggedTensor [[0], [0, 1, 2, 3, 4]]>
<tf.RaggedTensor [[0, 1, 2], [0, 1]]>
<tf.RaggedTensor [[0, 1, 2, 3, 4, 5, 6, 7]]>

Mengubah Kumpulan Data dengan tensor kasar

Anda juga dapat membuat atau mengubah tensor compang-camping di dataset menggunakan Dataset.map :

def transform_lengths(features):
  return {
      'mean_length': tf.math.reduce_mean(features['lengths']),
      'length_ranges': tf.ragged.range(features['lengths'])}
transformed_dataset = dataset.map(transform_lengths)
print_dictionary_dataset(transformed_dataset)
Element 0:
   mean_length = 7
 length_ranges = <tf.RaggedTensor [[0, 1, 2, 3, 4, 5, 6]]>
Element 1:
   mean_length = 0
 length_ranges = <tf.RaggedTensor []>
Element 2:
   mean_length = 2
 length_ranges = <tf.RaggedTensor [[0], [0, 1, 2]]>
Element 3:
   mean_length = 3
 length_ranges = <tf.RaggedTensor [[0, 1, 2], [0, 1, 2, 3, 4], [0, 1]]>

tf.fungsi

tf.function adalah dekorator yang precomputes TensorFlow grafik untuk fungsi Python, yang secara substansial dapat meningkatkan kinerja kode TensorFlow Anda. Tensor compang-camping dapat digunakan secara transparan dengan @tf.function fungsi -decorated. Misalnya, fungsi berikut ini berfungsi dengan tensor yang tidak rata dan tidak kasar:

@tf.function
def make_palindrome(x, axis):
  return tf.concat([x, tf.reverse(x, [axis])], axis)
make_palindrome(tf.constant([[1, 2], [3, 4], [5, 6]]), axis=1)
<tf.Tensor: shape=(3, 4), dtype=int32, numpy=
array([[1, 2, 2, 1],
       [3, 4, 4, 3],
       [5, 6, 6, 5]], dtype=int32)>
make_palindrome(tf.ragged.constant([[1, 2], [3], [4, 5, 6]]), axis=1)
2021-09-22 20:36:51.018367: W tensorflow/core/grappler/optimizers/loop_optimizer.cc:907] Skipping loop optimization for Merge node with control input: RaggedConcat/assert_equal_1/Assert/AssertGuard/branch_executed/_9
<tf.RaggedTensor [[1, 2, 2, 1], [3, 3], [4, 5, 6, 6, 5, 4]]>

Jika Anda ingin secara eksplisit menentukan input_signature untuk tf.function , maka Anda dapat melakukannya dengan menggunakan tf.RaggedTensorSpec .

@tf.function(
    input_signature=[tf.RaggedTensorSpec(shape=[None, None], dtype=tf.int32)])
def max_and_min(rt):
  return (tf.math.reduce_max(rt, axis=-1), tf.math.reduce_min(rt, axis=-1))

max_and_min(tf.ragged.constant([[1, 2], [3], [4, 5, 6]]))
(<tf.Tensor: shape=(3,), dtype=int32, numpy=array([2, 3, 6], dtype=int32)>,
 <tf.Tensor: shape=(3,), dtype=int32, numpy=array([1, 3, 4], dtype=int32)>)

Fungsi konkret

Fungsi beton merangkum grafik ditelusuri individu yang dibangun oleh tf.function . Tensor kasar dapat digunakan secara transparan dengan fungsi konkret.

@tf.function
def increment(x):
  return x + 1

rt = tf.ragged.constant([[1, 2], [3], [4, 5, 6]])
cf = increment.get_concrete_function(rt)
print(cf(rt))
<tf.RaggedTensor [[2, 3], [4], [5, 6, 7]]>

Model Tersimpan

Sebuah SavedModel adalah program TensorFlow serial, termasuk kedua bobot dan perhitungan. Itu dapat dibangun dari model Keras atau dari model khusus. Dalam kedua kasus tersebut, tensor yang tidak rata dapat digunakan secara transparan dengan fungsi dan metode yang ditentukan oleh SavedModel.

Contoh: menyimpan model Keras

import tempfile

keras_module_path = tempfile.mkdtemp()
tf.saved_model.save(keras_model, keras_module_path)
imported_model = tf.saved_model.load(keras_module_path)
imported_model(hashed_words)
2021-09-22 20:36:52.069689: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
WARNING:absl:Function `_wrapped_model` contains input name(s) args_0 with unsupported characters which will be renamed to args_0_1 in the SavedModel.
INFO:tensorflow:Assets written to: /tmp/tmp114axtt7/assets
INFO:tensorflow:Assets written to: /tmp/tmp114axtt7/assets
<tf.Tensor: shape=(4, 1), dtype=float32, numpy=
array([[0.02800461],
       [0.00945962],
       [0.02283431],
       [0.00252927]], dtype=float32)>

Contoh: menyimpan model khusus

class CustomModule(tf.Module):
  def __init__(self, variable_value):
    super(CustomModule, self).__init__()
    self.v = tf.Variable(variable_value)

  @tf.function
  def grow(self, x):
    return x * self.v

module = CustomModule(100.0)

# Before saving a custom model, you must ensure that concrete functions are
# built for each input signature that you will need.
module.grow.get_concrete_function(tf.RaggedTensorSpec(shape=[None, None],
                                                      dtype=tf.float32))

custom_module_path = tempfile.mkdtemp()
tf.saved_model.save(module, custom_module_path)
imported_model = tf.saved_model.load(custom_module_path)
imported_model.grow(tf.ragged.constant([[1.0, 4.0, 3.0], [2.0]]))
INFO:tensorflow:Assets written to: /tmp/tmpnn4u8dy5/assets
INFO:tensorflow:Assets written to: /tmp/tmpnn4u8dy5/assets
<tf.RaggedTensor [[100.0, 400.0, 300.0], [200.0]]>

Operator kelebihan beban

The RaggedTensor overloads kelas standar Python aritmatika dan perbandingan operator, sehingga mudah untuk melakukan elementwise matematika dasar:

x = tf.ragged.constant([[1, 2], [3], [4, 5, 6]])
y = tf.ragged.constant([[1, 1], [2], [3, 3, 3]])
print(x + y)
<tf.RaggedTensor [[2, 3], [5], [7, 8, 9]]>

Karena operator yang kelebihan beban melakukan perhitungan elemen, input ke semua operasi biner harus memiliki bentuk yang sama atau dapat disiarkan ke bentuk yang sama. Dalam kasus penyiaran paling sederhana, skalar tunggal digabungkan secara elemen dengan setiap nilai dalam tensor yang tidak rata:

x = tf.ragged.constant([[1, 2], [3], [4, 5, 6]])
print(x + 3)
<tf.RaggedTensor [[4, 5], [6], [7, 8, 9]]>

Untuk pembahasan kasus yang lebih maju, memeriksa bagian tentang Penyiaran.

Tensor compang-camping membebani set yang sama operator seperti biasa Tensor s: operator unary - , ~ , dan abs() ; dan operator biner + , - , * , / , // , % , ** , & , | , ^ , == , < , <= , > , dan >= .

Pengindeksan

Tensor kasar mendukung pengindeksan gaya Python, termasuk pengindeksan dan pemotongan multidimensi. Contoh berikut menunjukkan pengindeksan ragged tensor dengan tensor ragged 2D dan 3D.

Contoh pengindeksan: tensor compang-camping 2D

queries = tf.ragged.constant(
    [['Who', 'is', 'George', 'Washington'],
     ['What', 'is', 'the', 'weather', 'tomorrow'],
     ['Goodnight']])
print(queries[1])                   # A single query
tf.Tensor([b'What' b'is' b'the' b'weather' b'tomorrow'], shape=(5,), dtype=string)
print(queries[1, 2])                # A single word
tf.Tensor(b'the', shape=(), dtype=string)
print(queries[1:])                  # Everything but the first row
<tf.RaggedTensor [[b'What', b'is', b'the', b'weather', b'tomorrow'], [b'Goodnight']]>
print(queries[:, :3])               # The first 3 words of each query
<tf.RaggedTensor [[b'Who', b'is', b'George'], [b'What', b'is', b'the'], [b'Goodnight']]>
print(queries[:, -2:])              # The last 2 words of each query
<tf.RaggedTensor [[b'George', b'Washington'], [b'weather', b'tomorrow'], [b'Goodnight']]>

Contoh pengindeksan: tensor compang-camping 3D

rt = tf.ragged.constant([[[1, 2, 3], [4]],
                         [[5], [], [6]],
                         [[7]],
                         [[8, 9], [10]]])
print(rt[1])                        # Second row (2D RaggedTensor)
<tf.RaggedTensor [[5], [], [6]]>
print(rt[3, 0])                     # First element of fourth row (1D Tensor)
tf.Tensor([8 9], shape=(2,), dtype=int32)
print(rt[:, 1:3])                   # Items 1-3 of each row (3D RaggedTensor)
<tf.RaggedTensor [[[4]], [[], [6]], [], [[10]]]>
print(rt[:, -1:])                   # Last item of each row (3D RaggedTensor)
<tf.RaggedTensor [[[4]], [[6]], [[7]], [[10]]]>

RaggedTensor s dukungan multidimensi pengindeksan dan mengiris dengan satu pembatasan: pengindeksan ke dimensi compang-camping tidak diperbolehkan. Kasus ini bermasalah karena nilai yang ditunjukkan mungkin ada di beberapa baris tetapi tidak di baris lainnya. Dalam kasus tersebut, itu tidak jelas apakah Anda harus (1) menaikkan IndexError ; (2) menggunakan nilai default; atau (3) lewati nilai itu dan kembalikan tensor dengan baris yang lebih sedikit daripada yang Anda mulai. Mengikuti prinsip-prinsip dari Python ( "Dalam menghadapi ambiguitas, menolak godaan untuk menebak"), operasi ini saat ini dianulir.

Konversi jenis tensor

The RaggedTensor mendefinisikan kelas metode yang dapat digunakan untuk mengkonversi antara RaggedTensor dan tf.Tensor s atau tf.SparseTensors :

ragged_sentences = tf.ragged.constant([
    ['Hi'], ['Welcome', 'to', 'the', 'fair'], ['Have', 'fun']])
# RaggedTensor -> Tensor
print(ragged_sentences.to_tensor(default_value='', shape=[None, 10]))
tf.Tensor(
[[b'Hi' b'' b'' b'' b'' b'' b'' b'' b'' b'']
 [b'Welcome' b'to' b'the' b'fair' b'' b'' b'' b'' b'' b'']
 [b'Have' b'fun' b'' b'' b'' b'' b'' b'' b'' b'']], shape=(3, 10), dtype=string)
# Tensor -> RaggedTensor
x = [[1, 3, -1, -1], [2, -1, -1, -1], [4, 5, 8, 9]]
print(tf.RaggedTensor.from_tensor(x, padding=-1))
<tf.RaggedTensor [[1, 3], [2], [4, 5, 8, 9]]>
#RaggedTensor -> SparseTensor
print(ragged_sentences.to_sparse())
SparseTensor(indices=tf.Tensor(
[[0 0]
 [1 0]
 [1 1]
 [1 2]
 [1 3]
 [2 0]
 [2 1]], shape=(7, 2), dtype=int64), values=tf.Tensor([b'Hi' b'Welcome' b'to' b'the' b'fair' b'Have' b'fun'], shape=(7,), dtype=string), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64))
# SparseTensor -> RaggedTensor
st = tf.SparseTensor(indices=[[0, 0], [2, 0], [2, 1]],
                     values=['a', 'b', 'c'],
                     dense_shape=[3, 3])
print(tf.RaggedTensor.from_sparse(st))
<tf.RaggedTensor [[b'a'], [], [b'b', b'c']]>

Mengevaluasi tensor yang tidak rata

Untuk mengakses nilai dalam tensor yang tidak rata, Anda dapat:

  1. Gunakan tf.RaggedTensor.to_list untuk mengkonversi tensor compang-camping untuk daftar Python bersarang.
  2. Gunakan tf.RaggedTensor.numpy untuk mengkonversi tensor compang-camping untuk array NumPy nilai-nilai yang bersarang NumPy array.
  3. Mendekomposisi tensor compang-camping menjadi komponen-komponennya, menggunakan tf.RaggedTensor.values dan tf.RaggedTensor.row_splits sifat, atau metode baris-paritioning seperti tf.RaggedTensor.row_lengths dan tf.RaggedTensor.value_rowids .
  4. Gunakan pengindeksan Python untuk memilih nilai dari tensor yang tidak rata.
rt = tf.ragged.constant([[1, 2], [3, 4, 5], [6], [], [7]])
print("Python list:", rt.to_list())
print("NumPy array:", rt.numpy())
print("Values:", rt.values.numpy())
print("Splits:", rt.row_splits.numpy())
print("Indexed value:", rt[1].numpy())
Python list: [[1, 2], [3, 4, 5], [6], [], [7]]
NumPy array: [array([1, 2], dtype=int32) array([3, 4, 5], dtype=int32)
 array([6], dtype=int32) array([], dtype=int32) array([7], dtype=int32)]
Values: [1 2 3 4 5 6 7]
Splits: [0 2 5 6 6 7]
Indexed value: [3 4 5]
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/ops/ragged/ragged_tensor.py:2063: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  return np.array(rows)

Penyiaran

Broadcasting adalah proses membuat tensor dengan bentuk yang berbeda memiliki bentuk yang kompatibel untuk operasi elemen. Untuk latar belakang lebih lanjut tentang penyiaran, lihat:

Langkah-langkah dasar untuk menyiarkan dua input x dan y memiliki bentuk yang kompatibel adalah:

  1. Jika x dan y tidak memiliki jumlah yang sama dari dimensi, kemudian tambahkan dimensi luar (dengan ukuran 1) sampai mereka lakukan.

  2. Untuk setiap dimensi di mana x dan y memiliki ukuran yang berbeda:

  • Jika x atau y memiliki ukuran 1 dalam dimensi d , kemudian ulangi nilai-nilai di seluruh dimensi d untuk mencocokkan ukuran input lain.
  • Jika tidak, meningkatkan pengecualian ( x dan y tidak disiarkan kompatibel).

Di mana ukuran tensor dalam dimensi seragam adalah satu angka (ukuran irisan melintasi dimensi itu); dan ukuran tensor dalam dimensi kasar adalah daftar panjang irisan (untuk semua irisan di dimensi tersebut).

Contoh penyiaran

# x       (2D ragged):  2 x (num_rows)
# y       (scalar)
# result  (2D ragged):  2 x (num_rows)
x = tf.ragged.constant([[1, 2], [3]])
y = 3
print(x + y)
<tf.RaggedTensor [[4, 5], [6]]>
# x         (2d ragged):  3 x (num_rows)
# y         (2d tensor):  3 x          1
# Result    (2d ragged):  3 x (num_rows)
x = tf.ragged.constant(
   [[10, 87, 12],
    [19, 53],
    [12, 32]])
y = [[1000], [2000], [3000]]
print(x + y)
<tf.RaggedTensor [[1010, 1087, 1012], [2019, 2053], [3012, 3032]]>
# x      (3d ragged):  2 x (r1) x 2
# y      (2d ragged):         1 x 1
# Result (3d ragged):  2 x (r1) x 2
x = tf.ragged.constant(
    [[[1, 2], [3, 4], [5, 6]],
     [[7, 8]]],
    ragged_rank=1)
y = tf.constant([[10]])
print(x + y)
<tf.RaggedTensor [[[11, 12], [13, 14], [15, 16]], [[17, 18]]]>
# x      (3d ragged):  2 x (r1) x (r2) x 1
# y      (1d tensor):                    3
# Result (3d ragged):  2 x (r1) x (r2) x 3
x = tf.ragged.constant(
    [
        [
            [[1], [2]],
            [],
            [[3]],
            [[4]],
        ],
        [
            [[5], [6]],
            [[7]]
        ]
    ],
    ragged_rank=2)
y = tf.constant([10, 20, 30])
print(x + y)
<tf.RaggedTensor [[[[11, 21, 31], [12, 22, 32]], [], [[13, 23, 33]], [[14, 24, 34]]], [[[15, 25, 35], [16, 26, 36]], [[17, 27, 37]]]]>

Berikut adalah beberapa contoh bentuk yang tidak disiarkan:

# x      (2d ragged): 3 x (r1)
# y      (2d tensor): 3 x    4  # trailing dimensions do not match
x = tf.ragged.constant([[1, 2], [3, 4, 5, 6], [7]])
y = tf.constant([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
try:
  x + y
except tf.errors.InvalidArgumentError as exception:
  print(exception)
Expected 'tf.Tensor(False, shape=(), dtype=bool)' to be true. Summarized data: b'Unable to broadcast: dimension size mismatch in dimension'
1
b'lengths='
4
b'dim_size='
2, 4, 1
# x      (2d ragged): 3 x (r1)
# y      (2d ragged): 3 x (r2)  # ragged dimensions do not match.
x = tf.ragged.constant([[1, 2, 3], [4], [5, 6]])
y = tf.ragged.constant([[10, 20], [30, 40], [50]])
try:
  x + y
except tf.errors.InvalidArgumentError as exception:
  print(exception)
Expected 'tf.Tensor(False, shape=(), dtype=bool)' to be true. Summarized data: b'Unable to broadcast: dimension size mismatch in dimension'
1
b'lengths='
2, 2, 1
b'dim_size='
3, 1, 2
# x      (3d ragged): 3 x (r1) x 2
# y      (3d ragged): 3 x (r1) x 3  # trailing dimensions do not match
x = tf.ragged.constant([[[1, 2], [3, 4], [5, 6]],
                        [[7, 8], [9, 10]]])
y = tf.ragged.constant([[[1, 2, 0], [3, 4, 0], [5, 6, 0]],
                        [[7, 8, 0], [9, 10, 0]]])
try:
  x + y
except tf.errors.InvalidArgumentError as exception:
  print(exception)
Expected 'tf.Tensor(False, shape=(), dtype=bool)' to be true. Summarized data: b'Unable to broadcast: dimension size mismatch in dimension'
2
b'lengths='
3, 3, 3, 3, 3
b'dim_size='
2, 2, 2, 2, 2

Pengkodean RaggedTensor

Tensor compang-camping dikodekan menggunakan RaggedTensor kelas. Secara internal, setiap RaggedTensor terdiri dari:

  • Sebuah values tensor, yang merangkai baris variabel-panjang ke dalam daftar pipih.
  • Sebuah row_partition , yang menunjukkan bagaimana nilai-nilai pipih dibagi menjadi baris.

Pengkodean RaggedTensor

The row_partition dapat disimpan menggunakan empat pengkodean yang berbeda:

  • row_splits adalah vektor bilangan bulat menentukan titik-titik perpecahan antara baris.
  • value_rowids adalah vektor bilangan bulat menentukan indeks baris untuk setiap nilai.
  • row_lengths adalah vektor bilangan bulat menentukan panjang setiap baris.
  • uniform_row_length adalah skalar bilangan bulat menentukan panjang tunggal untuk semua baris.

pengkodean baris_partisi

Integer skalar nrows juga dapat dimasukkan dalam row_partition encoding ke account untuk baris Trailing kosong dengan value_rowids atau baris kosong dengan uniform_row_length .

rt = tf.RaggedTensor.from_row_splits(
    values=[3, 1, 4, 1, 5, 9, 2],
    row_splits=[0, 4, 4, 6, 7])
print(rt)
<tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9], [2]]>

Pilihan pengkodean yang akan digunakan untuk partisi baris dikelola secara internal oleh tensor kasar untuk meningkatkan efisiensi dalam beberapa konteks. Secara khusus, beberapa keuntungan dan kerugian dari skema partisi baris yang berbeda adalah:

  • Efisien pengindeksan: The row_splits encoding memungkinkan konstan-waktu pengindeksan dan mengiris ke dalam tensor compang-camping.
  • Efisien Rangkaian: The row_lengths pengkodean lebih efisien ketika concatenating tensor compang-camping, karena panjang baris tidak berubah ketika dua tensor yang bersambung bersama-sama.
  • Ukuran encoding kecil: value_rowids pengkodean lebih efisien ketika menyimpan tensor compang-camping yang memiliki sejumlah besar baris kosong, karena ukuran tensor hanya bergantung pada jumlah total nilai. Di sisi lain, row_splits dan row_lengths pengkodean lebih efisien ketika menyimpan tensor compang-camping dengan baris lagi, karena mereka memerlukan hanya satu nilai skalar untuk setiap baris.
  • Kompatibilitas: The value_rowids skema sesuai dengan segmentasi format yang digunakan oleh operasi, seperti tf.segment_sum . The row_limits skema sesuai dengan format yang digunakan oleh ops seperti tf.sequence_mask .
  • Dimensi seragam: Seperti dibahas di bawah, yang uniform_row_length encoding digunakan untuk mengkodekan compang-camping tensor dengan dimensi yang seragam.

Beberapa dimensi compang-camping

Sebuah tensor compang-camping dengan beberapa dimensi compang-camping dikodekan dengan menggunakan bersarang RaggedTensor untuk values tensor. Setiap bersarang RaggedTensor menambahkan dimensi compang-camping tunggal.

Encoding tensor kasar dengan beberapa dimensi kasar (peringkat 2)

rt = tf.RaggedTensor.from_row_splits(
    values=tf.RaggedTensor.from_row_splits(
        values=[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
        row_splits=[0, 3, 3, 5, 9, 10]),
    row_splits=[0, 1, 1, 5])
print(rt)
print("Shape: {}".format(rt.shape))
print("Number of partitioned dimensions: {}".format(rt.ragged_rank))
<tf.RaggedTensor [[[10, 11, 12]], [], [[], [13, 14], [15, 16, 17, 18], [19]]]>
Shape: (3, None, None)
Number of partitioned dimensions: 2

Fungsi pabrik tf.RaggedTensor.from_nested_row_splits dapat digunakan untuk membangun sebuah RaggedTensor dengan beberapa dimensi compang-camping langsung dengan memberikan daftar row_splits tensor:

rt = tf.RaggedTensor.from_nested_row_splits(
    flat_values=[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
    nested_row_splits=([0, 1, 1, 5], [0, 3, 3, 5, 9, 10]))
print(rt)
<tf.RaggedTensor [[[10, 11, 12]], [], [[], [13, 14], [15, 16, 17, 18], [19]]]>

Peringkat compang-camping dan nilai datar

Rank compang-camping A tensor compang-camping adalah jumlah kali bahwa yang mendasari values tensor telah dipartisi (yaitu kedalaman bersarang RaggedTensor objek). The terdalam values tensor dikenal sebagai flat_values nya. Pada contoh berikut, conversations memiliki ragged_rank = 3, dan yang flat_values adalah 1D Tensor dengan 24 string:

# shape = [batch, (paragraph), (sentence), (word)]
conversations = tf.ragged.constant(
    [[[["I", "like", "ragged", "tensors."]],
      [["Oh", "yeah?"], ["What", "can", "you", "use", "them", "for?"]],
      [["Processing", "variable", "length", "data!"]]],
     [[["I", "like", "cheese."], ["Do", "you?"]],
      [["Yes."], ["I", "do."]]]])
conversations.shape
TensorShape([2, None, None, None])
assert conversations.ragged_rank == len(conversations.nested_row_splits)
conversations.ragged_rank  # Number of partitioned dimensions.
3
conversations.flat_values.numpy()
array([b'I', b'like', b'ragged', b'tensors.', b'Oh', b'yeah?', b'What',
       b'can', b'you', b'use', b'them', b'for?', b'Processing',
       b'variable', b'length', b'data!', b'I', b'like', b'cheese.', b'Do',
       b'you?', b'Yes.', b'I', b'do.'], dtype=object)

Dimensi bagian dalam seragam

Tensor compang-camping dengan dimensi batin seragam dikodekan dengan menggunakan multidimensi tf.Tensor untuk flat_values (yaitu, terdalam values ).

Pengkodean tensor kasar dengan dimensi bagian dalam yang seragam

rt = tf.RaggedTensor.from_row_splits(
    values=[[1, 3], [0, 0], [1, 3], [5, 3], [3, 3], [1, 2]],
    row_splits=[0, 3, 4, 6])
print(rt)
print("Shape: {}".format(rt.shape))
print("Number of partitioned dimensions: {}".format(rt.ragged_rank))
print("Flat values shape: {}".format(rt.flat_values.shape))
print("Flat values:\n{}".format(rt.flat_values))
<tf.RaggedTensor [[[1, 3], [0, 0], [1, 3]], [[5, 3]], [[3, 3], [1, 2]]]>
Shape: (3, None, 2)
Number of partitioned dimensions: 1
Flat values shape: (6, 2)
Flat values:
[[1 3]
 [0 0]
 [1 3]
 [5 3]
 [3 3]
 [1 2]]

Dimensi non-dalam yang seragam

Tensor compang-camping dengan dimensi non-batin seragam dikodekan oleh partisi baris dengan uniform_row_length .

Pengkodean tensor kasar dengan dimensi non-dalam yang seragam

rt = tf.RaggedTensor.from_uniform_row_length(
    values=tf.RaggedTensor.from_row_splits(
        values=[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
        row_splits=[0, 3, 5, 9, 10]),
    uniform_row_length=2)
print(rt)
print("Shape: {}".format(rt.shape))
print("Number of partitioned dimensions: {}".format(rt.ragged_rank))
<tf.RaggedTensor [[[10, 11, 12], [13, 14]], [[15, 16, 17, 18], [19]]]>
Shape: (2, 2, None)
Number of partitioned dimensions: 2