TensorFlow Text 一文读懂

不念不忘少年蓝@ 2024-04-18 11:34 90阅读 0赞

官网:https://github.com/tensorflow/text

引言Introduction

TensorFlow Text提供了一组与TensorFlow 2.0共同使用的文本相关类和操作。这个库可以基于文本模型,定期执行预处理,以及核心TensorFlow不提供的序列建模的功能。

在文本预处理中使用这些操作的好处是它们在TensorFlow Graph中完成,因此无需担心训练中的标记化与推测的标记化或管理预处理脚本不同。

安装 Installation

  1. pip install -U tensorflow-text

Eager Execution

TensorFlow Text兼容TensorFlow eager模式和graph模式

  1. import tensorflow as tf
  2. import tensorflow_text as text
  3. tf.enable_eager_execution()

编码 Unicode

大多数操作所期望的字符串编码方式都是UTF-8。 如果使用了不同的编码方式,则可以使用核心tensorflow的转码操作将字符串转码为UTF-8。如果输入的结构无效,也可以使用相同的操作将字符串强制转换为结构有效的UTF-8。

  1. docs = tf.constant([u'Everything not saved will be lost.'.encode('UTF-16-BE'),
  2. u'Sad☹'.encode('UTF-16-BE')])
  3. utf8_docs = tf.strings.unicode_transcode(docs, input_encoding='UTF-16-BE',
  4. output_encoding='UTF-8')

规范化 Normalization

在处理不同的文本来源时,最重要的是不同来源的相同单词能被识别为相同。 Unicode中不区分大小写匹配的常用技术是大小写折叠(类似于下框)。 (请注意,案例折叠在内部应用NFKC标准化。)
我们还提供Unicode规范化操作,用于将字符串转换为字符的规范表示,其中规范化形式KC是默认值(NFKC)。

  1. print(text.case_fold_utf8(['Everything not saved will be lost.']))
  2. print(text.normalize_utf8(['Äffin']))
  3. print(text.normalize_utf8(['Äffin'], 'nfkd'))
  4. tf.Tensor(['everything not saved will be lost.'], shape=(1,), dtype=string)
  5. tf.Tensor(['\xc3\x84ffin'], shape=(1,), dtype=string)
  6. tf.Tensor(['A\xcc\x88ffin'], shape=(1,), dtype=string)

切词 Tokenization

分词是将字符串分解为单个单词的过程。通常,这些标记是单词、数字和/或标点符号。

主要的接口是tokenizer和tokenizerWithOffset,它们分别有一个方法tokenize和tokenizeWithOffset。

可以使用多个实现标记器,其中的每一个都实现了tokenizerWithOffset(它扩展了tokenizer),其中包括一个将字节偏移量获取到原始字符串中的选项。

这允许调用者知道token创建的原始字符串中的字节。

所有的标记器都返回raggedtensors,其中最内部的标记维度映射到原始的单个字符串。结果,生成的形状的秩增加了一。

如果对这方面不太熟悉,可以参考ragged tensor指南。https://www.tensorflow.org/guide/ragged_tensors

WhitespaceTokenizer

这是一个基本的标记器,它在icu定义的空白字符(如空格、制表符、换行符)上拆分utf-8字符串。

  1. tokenizer = text.WhitespaceTokenizer()
  2. tokens = tokenizer.tokenize(['everything not saved will be lost.', u'Sad☹'.encode('UTF-8')])
  3. print(tokens.to_list())
  4. [['everything', 'not', 'saved', 'will', 'be', 'lost.'], ['Sad\xe2\x98\xb9']]

UnicodeScriptTokenizer

此标记生成器根据Unicode脚本边界拆分UTF-8字符串。 使用的脚本代码对应于Unicode的国际组件(ICU)UScriptCode值。 请参阅:http://icu-project.org/apiref/icu4c/uscript_8h.html

在实践中,这种方法与WhitespaceTokenizer类似。最明显的区别在于它将从语言文本(例如USCRIPT_LATIN,USCRIPT_CYRILLIC等)中分割标点符号(USCRIPT_COMMON),同时还将语言文本彼此分开。

  1. tokenizer = text.UnicodeScriptTokenizer()
  2. tokens = tokenizer.tokenize(['everything not saved will be lost.',
  3. u'Sad☹'.encode('UTF-8')])
  4. print(tokens.to_list())
  5. [['everything', 'not', 'saved', 'will', 'be', 'lost', '.'],
  6. ['Sad', '\xe2\x98\xb9']]

Unicode split

当对没有空格的语言进行标记以分割单词时,通常只需按字符分割,这可以使用core中的unicode分割操作来完成。

  1. tokens = tf.strings.unicode_split([u"仅今年前".encode('UTF-8')], 'UTF-8')
  2. print(tokens.to_list())
  3. [['\xe4\xbb\x85', '\xe4\xbb\x8a', '\xe5\xb9\xb4', '\xe5\x89\x8d']]

Offsets

在对字符串进行标记时,通常需要知道标记源自原始字符串的位置。 出于这个原因,实现TokenizerWithOffsets的每个标记生成器都有一个tokenize_with_offsets方法,该方法将返回字节偏移量以及标记。 offset_starts列出每个标记开始时原始字符串中的字节,offset_limits列出每个标记结束的字节。

  1. tokenizer = text.UnicodeScriptTokenizer()
  2. (tokens, offset_starts, offset_limits) = tokenizer.tokenize_with_offsets(
  3. ['everything not saved will be lost.', u'Sad☹'.encode('UTF-8')])
  4. print(tokens.to_list())
  5. print(offset_starts.to_list())
  6. print(offset_limits.to_list())
  7. [['everything', 'not', 'saved', 'will', 'be', 'lost', '.'],
  8. ['Sad', '\xe2\x98\xb9']]
  9. [[0, 11, 15, 21, 26, 29, 33], [0, 3]]
  10. [[10, 14, 20, 25, 28, 33, 34], [3, 6]]

TF.Data Example

标记生成器使用tf.data API按预期工作。 下面提供了一个简单的例子。

  1. docs = tf.data.Dataset.from_tensor_slices([['Never tell me the odds.'],
  2. ["It's a trap!"]])
  3. tokenizer = text.WhitespaceTokenizer()
  4. tokenized_docs = docs.map(lambda x: tokenizer.tokenize(x))
  5. iterator = tokenized_docs.make_one_shot_iterator()
  6. print(iterator.get_next().to_list())
  7. print(iterator.get_next().to_list())
  8. [['Never', 'tell', 'me', 'the', 'odds.']]
  9. [["It's", 'a', 'trap!']]

Other Text Ops

TF.Text打包其他有用的预处理操作。 我们将在下面回顾几个。

Wordshape

在一些自然语言理解模型中使用的常见特征是查看文本字符串是否具有某个属性。 例如,句子破坏模型可能包含检查单词大写或者标点符号位于字符串末尾的功能。

Wordshape定义了各种有用的基于正则表达式的辅助函数,用于匹配输入文本中的各种相关模式。 这里有一些例子。

  1. tokenizer = text.WhitespaceTokenizer()
  2. tokens = tokenizer.tokenize(['Everything not saved will be lost.',
  3. u'Sad☹'.encode('UTF-8')])
  4. # Is capitalized?
  5. f1 = text.wordshape(tokens, text.WordShape.HAS_TITLE_CASE)
  6. # Are all letters uppercased?
  7. f2 = text.wordshape(tokens, text.WordShape.IS_UPPERCASE)
  8. # Does the token contain punctuation?
  9. f3 = text.wordshape(tokens, text.WordShape.HAS_SOME_PUNCT_OR_SYMBOL)
  10. # Is the token a number?
  11. f4 = text.wordshape(tokens, text.WordShape.IS_NUMERIC_VALUE)
  12. print(f1.to_list())
  13. print(f2.to_list())
  14. print(f3.to_list())
  15. print(f4.to_list())
  16. [[True, False, False, False, False, False], [True]]
  17. [[False, False, False, False, False, False], [False]]
  18. [[False, False, False, False, False, True], [True]]
  19. [[False, False, False, False, False, False], [False]]

N-grams & Sliding Window

给定滑动窗口大小为n的N-gram是连续的单词。 组合令牌时,支持三种减少机制。 对于文本,您可能希望使用Reduction.STRING_JOIN将字符串相互追加。 默认分隔符是一个空格,但可以使用string_separater参数进行更改。

另外两种还原方法通常与数值一起使用,它们是Reduction.SUM和Reduction.MEAN。

  1. tokenizer = text.WhitespaceTokenizer()
  2. tokens = tokenizer.tokenize(['Everything not saved will be lost.',
  3. u'Sad☹'.encode('UTF-8')])
  4. # Ngrams, in this case bi-gram (n = 2)
  5. bigrams = text.ngrams(tokens, 2, reduction_type=text.Reduction.STRING_JOIN)
  6. print(bigrams.to_list())
  7. [['Everything not', 'not saved', 'saved will', 'will be', 'be lost.'], []]

发表评论

表情:
评论列表 (有 0 条评论,90人围观)

还没有评论,来说两句吧...

相关阅读

    相关 DDD

    什么是DDD? ddd不是一种架构风格,而是一种方法论,什么是方法论,每个人按照自己的想法来设计就是一套方法论;ddd是一种业务比较认可,对于微服务拆分的一种方法论。

    相关 DDD

    [一文读懂DDD][DDD] 原文: [一文读懂DDD][DDD 1] 何为DDD DDD不是架构设计方法,不能把每个设计细节具象化,DDD是一套体系,决定了其开放性

    相关 CDN

    前言 最近在了解边缘计算,发现我们经常听说的CDN也是边缘计算里的一部分。那么说到CDN,好像只知道它中文叫做内容分发网络。那么具体CDN的原理是什么?能够为用户在浏览网站时