TensorFlow.orgで表示 | GoogleColabで実行 | GitHubで表示 | ノートブックをダウンロード | TFハブモデルを参照してください |
概要
トークン化は、文字列をトークンに分割するプロセスです。通常、これらのトークンは単語、数字、句読点です。 tensorflow_text
パッケージには、テキストベースのモデルで必要なテキストを前処理に利用可能なトークナイザの数を提供します。 TensorFlowグラフでトークン化を実行することにより、トレーニングワークフローと推論ワークフローの違いや前処理スクリプトの管理について心配する必要がなくなります。
このガイドでは、TensorFlow Textが提供する多くのトークン化オプション、あるオプションを別のオプションで使用する場合、およびこれらのトークナイザーがモデル内からどのように呼び出されるかについて説明します。
設定
pip install -q tensorflow-text
import requests
import tensorflow as tf
import tensorflow_text as tf_text
スプリッターAPI
主なインターフェイスは、 Splitter
とSplitterWithOffsets
単方法有するsplit
とsplit_with_offsets
。 SplitterWithOffsets
(拡張バリアントSplitter
)バイトオフセットを取得するためのオプションが含まれています。これにより、呼び出し元は、作成されたトークンが元の文字列のどのバイトから作成されたかを知ることができます。
Tokenizer
とTokenizerWithOffsets
専門のバージョンであるSplitter
便利な方法を提供するtokenize
及びtokenize_with_offsets
それぞれ。
一般に、任意のN次元の入力のために、返されるトークンは、N + 1次元にあるRaggedTensor元の個々のストリングにマッピングトークンの最も内側の寸法を有します。
class Splitter {
@abstractmethod
def split(self, input)
}
class SplitterWithOffsets(Splitter) {
@abstractmethod
def split_with_offsets(self, input)
}
ありDetokenizer
インターフェースが。このインターフェースを実装するトークナイザーは、トークンのN次元の不規則なテンソルを受け入れることができ、通常、指定されたトークンが一緒に組み立てられたN-1次元のテンソルまたは不規則なテンソルを返します。
class Detokenizer {
@abstractmethod
def detokenize(self, input)
}
トークナイザー
以下は、TensorFlowTextが提供する一連のトークナイザーです。文字列入力はUTF-8であると想定されています。確認してくださいUnicodeのガイドをUTF-8に文字列を変換します。
単語全体のトークナイザー
これらのトークナイザーは、文字列を単語ごとに分割しようとします。これは、テキストを分割するための最も直感的な方法です。
WhitespaceTokenizer
text.WhitespaceTokenizer
ICU定義された空白文字(例えばスペース、タブ、改行)で文字列を分割し、最も基本的なトークナイザです。これは、プロトタイプモデルをすばやく構築するのに適していることがよくあります。
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.']]
このトークナイザーの欠点は、トークンを構成する単語に句読点が含まれていることです。別のトークンに単語や句読点を分割するには、 UnicodeScriptTokenizer
使用する必要があります。
UnicodeScriptTokenizer
UnicodeScriptTokenizer
Unicodeのスクリプトの境界に基づいて文字列を分割します。使用されるスクリプトコードは、International Components for Unicode(ICU)UScriptCode値に対応しています。参照: http://icu-project.org/apiref/icu4c/uscript_8h.html
実際には、これはと似てWhitespaceTokenizer
もお互いに言語のテキストを分離しながら(例えば。USCRIPT_LATIN、USCRIPT_CYRILLIC、など)は、最も明白な違いは、それは言語のテキストから句読点(USCRIPT_COMMON)を分割することであることで。これにより、縮約語も別々のトークンに分割されることに注意してください。
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'.']]
サブワードトークナイザー
サブワードトークナイザーは、より小さな語彙で使用でき、モデルがそれを作成するサブワードからの新しい単語に関する情報を持つことができます。
当社は、以下に簡単にサブワードトークン化オプションを議論するが、サブワードトークン化のチュートリアルでは、より深くなり、また、単語ファイルを生成する方法について説明します。
WordpieceTokenizer
WordPieceトークン化は、一連のサブトークンを生成するデータ駆動型のトークン化スキームです。これらのサブトークンは言語形態素に対応している場合がありますが、そうでない場合がよくあります。
WordpieceTokenizerは、入力がすでにトークンに分割されていることを想定しています。このための前提条件で、あなたは多くの場合、使用して分割することになるでしょうWhitespaceTokenizer
またはUnicodeScriptTokenizer
事前に。
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.']]
文字列をトークンに分割された後、 WordpieceTokenizer
サブトークンに分割するために使用することができます。
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は、BERTペーパーからのトークン化の元の実装を反映しています。これはWordpieceTokenizerに支えられていますが、最初に単語への正規化やトークン化などの追加タスクも実行します。
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'.']]]
SentencepieceTokenizer
SentencepieceTokenizerは、高度に構成可能なサブトークントークナイザーです。これは、Sentencepieceライブラリによってサポートされています。 BertTokenizerと同様に、サブトークンに分割する前に、正規化とトークン分割を含めることができます。
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'.']]
その他のスプリッター
UnicodeCharTokenizer
これにより、文字列がUTF-8文字に分割されます。単語間にスペースがないCJK言語に役立ちます。
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]]
出力はUnicodeコードポイントです。これは、バイグラムなどの文字ngramを作成する場合にも役立ちます。 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
これは、TF Hubが現在不規則なテンソルをサポートしていないため、呼び出しを容易にするためにTFHubにデプロイされたモデルのラッパーです。モデルにトークン化を実行させることは、単語に分割したいがヒューリスティックガイドを提供するスペースがない場合にCJK言語で特に役立ちます。現時点では、中国語の単一のセグメンテーションモデルがあります。
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']]
UTF-8でエンコードされたバイト文字列の結果を表示するのは難しい場合があります。リスト値をデコードして、見やすくします。
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
SplitMergeTokenizer
& SplitMergeFromLogitsTokenizer
、文字列を分割すべき場所を示す提供された値に基づいて文字列を分割の標的目的を持っています。これは、前のセグメンテーションの例のように独自のセグメンテーションモデルを構築するときに役立ちます。
SplitMergeTokenizer
、0の値は、新しい文字列の開始を示すために使用され、1の値は、文字が現在の文字列の一部であることを示しています。
strings = ["新华社北京"]
labels = [[0, 1, 1, 0, 1]]
tokenizer = tf_text.SplitMergeTokenizer()
tokens = tokenizer.tokenize(strings, labels)
print(decode_utf8_tensor(tokens))
[['新华社', '北京']]
SplitMergeFromLogitsTokenizer
似ていますが、代わりに各文字が新しい文字列に分割したり、現在の1にマージする必要があるかどうかを予測ニューラルネットワークからロジット値のペアを受け入れます。
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))
[['新华社', '北京']]
RegexSplitter
RegexSplitter
提供正規表現によって定義された任意のブレークポイントでセグメント列することができます。
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.']]
オフセット
文字列をトークン化する場合、元の文字列のどこからトークンが発生したかを知りたいことがよくあります。このため、実装の各トークナイザのためTokenizerWithOffsets
トークンと一緒にバイトオフセットを返しますtokenize_with_offsets方法があります。 start_offsetsは、各トークンが開始する元の文字列のバイトを一覧表示し、end_offsetsは、各トークンが終了するポイントの直後のバイトを一覧表示します。リフレッシングするには、開始オフセットは包括的であり、終了オフセットは排他的です。
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]]
トークン化解除
実装のトークナイザDetokenizer
提供detokenize
文字列を結合しようとする試みの方法を。これは損失を被る可能性があるため、トークン化解除された文字列は、トークン化された元の文字列と常に正確に一致するとは限りません。
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."]
TFデータ
TF Dataは、モデルをトレーニングするための入力パイプラインを作成するための強力なAPIです。トークナイザーは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!']]