Tokenisasi dengan Teks TF

Lihat di TensorFlow.org Jalankan di Google Colab Lihat di GitHub Unduh buku catatan Lihat model TF Hub

Ringkasan

Tokenization adalah proses memecah string menjadi token. Umumnya, token ini berupa kata, angka, dan/atau tanda baca. The tensorflow_text paket menyediakan sejumlah tokenizers tersedia untuk preprocessing teks yang dibutuhkan oleh model berbasis teks Anda. Dengan melakukan tokenisasi di grafik TensorFlow, Anda tidak perlu khawatir tentang perbedaan antara alur kerja pelatihan dan inferensi serta mengelola skrip prapemrosesan.

Panduan ini membahas banyak opsi tokenisasi yang disediakan oleh TensorFlow Text, kapan Anda mungkin ingin menggunakan satu opsi di atas opsi lainnya, dan bagaimana tokenizer ini dipanggil dari dalam model Anda.

Mempersiapkan

pip install -q tensorflow-text
import requests
import tensorflow as tf
import tensorflow_text as tf_text

API Pemisah

Antarmuka utama adalah Splitter dan SplitterWithOffsets yang memiliki metode tunggal split dan split_with_offsets . The SplitterWithOffsets varian (yang meluas Splitter ) termasuk pilihan untuk mendapatkan offset byte. Ini memungkinkan penelepon untuk mengetahui byte mana dalam string asli dari token yang dibuat.

The Tokenizer dan TokenizerWithOffsets adalah versi khusus dari Splitter yang menyediakan metode kemudahan tokenize dan tokenize_with_offsets masing-masing.

Umumnya, untuk setiap masukan N-dimensi, token kembali berada dalam N + 1 dimensi RaggedTensor dengan dimensi batin-paling token pemetaan ke string individu asli.

class Splitter {
  @abstractmethod
  def split(self, input)
}

class SplitterWithOffsets(Splitter) {
  @abstractmethod
  def split_with_offsets(self, input)
}

Ada juga Detokenizer antarmuka. Setiap tokenizer yang mengimplementasikan antarmuka ini dapat menerima tensor ragged berdimensi-N dari token, dan biasanya mengembalikan tensor berdimensi-N-1 atau tensor ragged yang memiliki token yang diberikan dirangkai bersama.

class Detokenizer {
  @abstractmethod
  def detokenize(self, input)
}

Tokenizer

Di bawah ini adalah rangkaian tokenizer yang disediakan oleh TensorFlow Text. Input string diasumsikan sebagai UTF-8. Harap tinjau Unicode panduan untuk mengkonversi string ke UTF-8.

Tokenizer seluruh kata

Tokenizer ini mencoba untuk membagi string dengan kata-kata, dan merupakan cara paling intuitif untuk membagi teks.

WhitespaceTokenizer

The text.WhitespaceTokenizer adalah tokenizer paling dasar yang membagi senar pada ICU didefinisikan karakter spasi (misalnya. Spasi, tab, baris baru). Ini sering kali bagus untuk membangun model prototipe dengan cepat.

tokenizer = tf_text.WhitespaceTokenizer()
tokens = tokenizer.tokenize(["What you know you can't explain, but you feel it."])
print(tokens.to_list())
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/util/dispatch.py:206: batch_gather (from tensorflow.python.ops.array_ops) is deprecated and will be removed after 2017-10-25.
Instructions for updating:
`tf.batch_gather` is deprecated, please use `tf.gather` with `batch_dims=-1` instead.
[[b'What', b'you', b'know', b'you', b"can't", b'explain,', b'but', b'you', b'feel', b'it.']]

Anda mungkin melihat kekurangan dari tokenizer ini adalah bahwa tanda baca disertakan dengan kata untuk membuat sebuah token. Untuk membagi kata-kata dan tanda baca dalam token terpisah, yang UnicodeScriptTokenizer harus digunakan.

UnicodeScriptTokenizer

The UnicodeScriptTokenizer membagi string berdasarkan batas-batas naskah Unicode. Kode skrip yang digunakan sesuai dengan nilai UScriptCode Komponen Internasional untuk Unicode (ICU). Lihat: http://icu-project.org/apiref/icu4c/uscript_8h.html

Dalam prakteknya, ini mirip dengan WhitespaceTokenizer dengan paling jelas perbedaan makhluk yang akan membagi tanda baca (USCRIPT_COMMON) dari teks-teks bahasa (misalnya. USCRIPT_LATIN, USCRIPT_CYRILLIC, dll) sementara juga memisahkan teks bahasa satu sama lain. Perhatikan bahwa ini juga akan membagi kata-kata kontraksi menjadi token terpisah.

tokenizer = tf_text.UnicodeScriptTokenizer()
tokens = tokenizer.tokenize(["What you know you can't explain, but you feel it."])
print(tokens.to_list())
[[b'What', b'you', b'know', b'you', b'can', b"'", b't', b'explain', b',', b'but', b'you', b'feel', b'it', b'.']]

Tokenizer subkata

Tokenizer subkata dapat digunakan dengan kosakata yang lebih kecil, dan memungkinkan model memiliki beberapa informasi tentang kata-kata baru dari subkata yang membuatnya.

Kita secara singkat mendiskusikan pilihan Subword tokenization bawah, tapi tutorial Subword tokenization berjalan lebih mendalam dan juga menjelaskan bagaimana untuk menghasilkan file vocab.

WordpieceTokenizer

Tokenisasi WordPiece adalah skema tokenisasi berbasis data yang menghasilkan satu set sub-token. Sub token ini mungkin sesuai dengan morfem linguistik, tetapi ini sering tidak terjadi.

WordpieceTokenizer mengharapkan input sudah dipecah menjadi token. Karena prasyarat ini, Anda akan sering ingin membagi menggunakan WhitespaceTokenizer atau UnicodeScriptTokenizer terlebih dahulu.

tokenizer = tf_text.WhitespaceTokenizer()
tokens = tokenizer.tokenize(["What you know you can't explain, but you feel it."])
print(tokens.to_list())
[[b'What', b'you', b'know', b'you', b"can't", b'explain,', b'but', b'you', b'feel', b'it.']]

Setelah string dibagi menjadi token, yang WordpieceTokenizer dapat digunakan untuk dibagi menjadi subtokens.

url = "https://github.com/tensorflow/text/blob/master/tensorflow_text/python/ops/test_data/test_wp_en_vocab.txt?raw=true"
r = requests.get(url)
filepath = "vocab.txt"
open(filepath, 'wb').write(r.content)
52382
subtokenizer = tf_text.UnicodeScriptTokenizer(filepath)
subtokens = tokenizer.tokenize(tokens)
print(subtokens.to_list())
[[[b'What'], [b'you'], [b'know'], [b'you'], [b"can't"], [b'explain,'], [b'but'], [b'you'], [b'feel'], [b'it.']]]

BertTokenizer

BertTokenizer mencerminkan implementasi asli tokenisasi dari makalah BERT. Ini didukung oleh WordpieceTokenizer, tetapi juga melakukan tugas tambahan seperti normalisasi dan tokenizing ke kata terlebih dahulu.

tokenizer = tf_text.BertTokenizer(filepath, token_out_type=tf.string, lower_case=True)
tokens = tokenizer.tokenize(["What you know you can't explain, but you feel it."])
print(tokens.to_list())
[[[b'what'], [b'you'], [b'know'], [b'you'], [b'can'], [b"'"], [b't'], [b'explain'], [b','], [b'but'], [b'you'], [b'feel'], [b'it'], [b'.']]]

KalimatTokenizer

SentencepieceTokenizer adalah tokenizer sub-token yang sangat dapat dikonfigurasi. Ini didukung oleh perpustakaan Sentencepiece. Seperti BertTokenizer, ini dapat mencakup normalisasi dan pemisahan token sebelum dipecah menjadi sub-token.

url = "https://github.com/tensorflow/text/blob/master/tensorflow_text/python/ops/test_data/test_oss_model.model?raw=true"
sp_model = requests.get(url).content
tokenizer = tf_text.SentencepieceTokenizer(sp_model, out_type=tf.string)
tokens = tokenizer.tokenize(["What you know you can't explain, but you feel it."])
print(tokens.to_list())
[[b'\xe2\x96\x81What', b'\xe2\x96\x81you', b'\xe2\x96\x81know', b'\xe2\x96\x81you', b'\xe2\x96\x81can', b"'", b't', b'\xe2\x96\x81explain', b',', b'\xe2\x96\x81but', b'\xe2\x96\x81you', b'\xe2\x96\x81feel', b'\xe2\x96\x81it', b'.']]

Pemisah lainnya

UnicodeCharTokenizer

Ini membagi string menjadi karakter UTF-8. Ini berguna untuk bahasa CJK yang tidak memiliki spasi antar kata.

tokenizer = tf_text.UnicodeCharTokenizer()
tokens = tokenizer.tokenize(["What you know you can't explain, but you feel it."])
print(tokens.to_list())
[[87, 104, 97, 116, 32, 121, 111, 117, 32, 107, 110, 111, 119, 32, 121, 111, 117, 32, 99, 97, 110, 39, 116, 32, 101, 120, 112, 108, 97, 105, 110, 44, 32, 98, 117, 116, 32, 121, 111, 117, 32, 102, 101, 101, 108, 32, 105, 116, 46]]

Outputnya adalah titik kode Unicode. Ini juga berguna untuk membuat ngram karakter, seperti bigram. Untuk mengubah kembali menjadi karakter UTF-8.

characters = tf.strings.unicode_encode(tf.expand_dims(tokens, -1), "UTF-8")
bigrams = tf_text.ngrams(characters, 2, reduction_type=tf_text.Reduction.STRING_JOIN, string_separator='')
print(bigrams.to_list())
[[b'Wh', b'ha', b'at', b't ', b' y', b'yo', b'ou', b'u ', b' k', b'kn', b'no', b'ow', b'w ', b' y', b'yo', b'ou', b'u ', b' c', b'ca', b'an', b"n'", b"'t", b't ', b' e', b'ex', b'xp', b'pl', b'la', b'ai', b'in', b'n,', b', ', b' b', b'bu', b'ut', b't ', b' y', b'yo', b'ou', b'u ', b' f', b'fe', b'ee', b'el', b'l ', b' i', b'it', b't.']]

HubModuleTokenizer

Ini adalah pembungkus di sekitar model yang diterapkan ke TF Hub untuk mempermudah panggilan karena TF Hub saat ini tidak mendukung tensor yang tidak rata. Memiliki model yang melakukan tokenisasi sangat berguna untuk bahasa CJK ketika Anda ingin membagi menjadi kata-kata, tetapi tidak memiliki ruang untuk menyediakan panduan heuristik. Saat ini, kami memiliki model segmentasi tunggal untuk bahasa Cina.

MODEL_HANDLE = "https://tfhub.dev/google/zh_segmentation/1"
segmenter = tf_text.HubModuleTokenizer(MODEL_HANDLE)
tokens = segmenter.tokenize(["新华社北京"])
print(tokens.to_list())
[[b'\xe6\x96\xb0\xe5\x8d\x8e\xe7\xa4\xbe', b'\xe5\x8c\x97\xe4\xba\xac']]

Mungkin sulit untuk melihat hasil string byte yang disandikan UTF-8. Dekode nilai daftar untuk membuat tampilan lebih mudah.

def decode_list(x):
  if type(x) is list:
    return list(map(decode_list, x))
  return x.decode("UTF-8")

def decode_utf8_tensor(x):
  return list(map(decode_list, x.to_list()))

print(decode_utf8_tensor(tokens))
[['新华社', '北京']]

SplitMergeTokenizer

The SplitMergeTokenizer & SplitMergeFromLogitsTokenizer memiliki tujuan target membelah string berdasarkan nilai yang diberikan yang menunjukkan di mana string harus split. Ini berguna saat membuat model segmentasi Anda sendiri seperti contoh Segmentasi sebelumnya.

Untuk SplitMergeTokenizer , nilai 0 digunakan untuk menunjukkan awal dari sebuah string baru, dan nilai 1 menunjukkan karakter adalah bagian dari string saat ini.

strings = ["新华社北京"]
labels = [[0, 1, 1, 0, 1]]
tokenizer = tf_text.SplitMergeTokenizer()
tokens = tokenizer.tokenize(strings, labels)
print(decode_utf8_tensor(tokens))
[['新华社', '北京']]

The SplitMergeFromLogitsTokenizer mirip, tapi bukannya menerima logit pasangan nilai dari jaringan saraf yang memprediksi jika masing-masing karakter harus dipecah menjadi string baru atau digabung menjadi satu saat ini.

strings = [["新华社北京"]]
labels = [[[5.0, -3.2], [0.2, 12.0], [0.0, 11.0], [2.2, -1.0], [-3.0, 3.0]]]
tokenizer = tf_text.SplitMergeFromLogitsTokenizer()
tokenizer.tokenize(strings, labels)
print(decode_utf8_tensor(tokens))
[['新华社', '北京']]

Pemisah Regex

The RegexSplitter mampu string segmen di breakpoints sewenang-wenang didefinisikan oleh ekspresi reguler yang disediakan.

splitter = tf_text.RegexSplitter("\s")
tokens = splitter.split(["What you know you can't explain, but you feel it."], )
print(tokens.to_list())
[[b'What', b'you', b'know', b'you', b"can't", b'explain,', b'but', b'you', b'feel', b'it.']]

Offset

Saat membuat tokenisasi string, seringkali diinginkan untuk mengetahui dari mana asal string asli token tersebut. Untuk alasan ini, setiap tokenizer yang menerapkan TokenizerWithOffsets memiliki metode tokenize_with_offsets yang akan mengembalikan offset byte bersama dengan token. Start_offsets mencantumkan byte dalam string asli setiap token dimulai, dan end_offsets mencantumkan byte segera setelah titik di mana setiap token berakhir. Untuk membingkai ulang, offset awal inklusif dan offset akhir eksklusif.

tokenizer = tf_text.UnicodeScriptTokenizer()
(tokens, start_offsets, end_offsets) = tokenizer.tokenize_with_offsets(['Everything not saved will be lost.'])
print(tokens.to_list())
print(start_offsets.to_list())
print(end_offsets.to_list())
[[b'Everything', b'not', b'saved', b'will', b'be', b'lost', b'.']]
[[0, 11, 15, 21, 26, 29, 33]]
[[10, 14, 20, 25, 28, 33, 34]]

Detokenisasi

Tokenizers yang melaksanakan Detokenizer memberikan detokenize metode yang mencoba untuk menggabungkan string. Ini memiliki kemungkinan menjadi lossy, sehingga string yang didetokenisasi mungkin tidak selalu sama persis dengan string asli yang telah diberi token sebelumnya.

tokenizer = tf_text.UnicodeCharTokenizer()
tokens = tokenizer.tokenize(["What you know you can't explain, but you feel it."])
print(tokens.to_list())
strings = tokenizer.detokenize(tokens)
print(strings.numpy())
[[87, 104, 97, 116, 32, 121, 111, 117, 32, 107, 110, 111, 119, 32, 121, 111, 117, 32, 99, 97, 110, 39, 116, 32, 101, 120, 112, 108, 97, 105, 110, 44, 32, 98, 117, 116, 32, 121, 111, 117, 32, 102, 101, 101, 108, 32, 105, 116, 46]]
[b"What you know you can't explain, but you feel it."]

Data TF

TF Data adalah API yang kuat untuk membuat saluran input untuk model pelatihan. Tokenizer berfungsi seperti yang diharapkan dengan API.

docs = tf.data.Dataset.from_tensor_slices([['Never tell me the odds.'], ["It's a trap!"]])
tokenizer = tf_text.WhitespaceTokenizer()
tokenized_docs = docs.map(lambda x: tokenizer.tokenize(x))
iterator = iter(tokenized_docs)
print(next(iterator).to_list())
print(next(iterator).to_list())
[[b'Never', b'tell', b'me', b'the', b'odds.']]
[[b"It's", b'a', b'trap!']]