TensorFlow支持Unicode,中文NLP終於省心了
整理 | 非主流
出品 | AI科技大本營
終於,TensorFlow 增加了對 Unicode 的支持。
什麼是 Unicode?Unicode 是計算機科學領域裡的一項業界標準,包括字符集、編碼方案等。Unicode 是為了解決傳統的字元編碼方案的局限而產生的,它為每種語言中的每個字元設定了統一併且唯一的二進位編碼,以滿足跨語言、跨平台進行文本轉換、處理的要求。
在處理自然語言時,了解字元串中字元的編碼方式非常重要。因為計算機只能處理數字,如果要處理文本,就必須先把文本轉換為數字。最早的計算機在設計時採用 8 個比特(bit)作為一個位元組(byte),所以一個位元組能表示的最大的整數就是 255(二進位 11111111 = 十進位 255),0 - 255 被用來表示大小寫英文字母、數字和一些符號,這個編碼表被稱為 ASCII 編碼,比如大寫字母 A 的編碼是 65,小寫字母 z 的編碼是 122。
如果要表示中文,顯然一個位元組是不夠的,至少需要兩個位元組,而且還不能和 ASCII 編碼衝突,所以,中國制定了 GB2312 編碼,用來把中文編進去。
類似的,日文和韓文等其他語言也有這個問題。為了統一所有文字的編碼,Unicode 應運而生。Unicode 把所有語言都統一到一套編碼里,這樣就不會再有亂碼問題了。
Unicode 幾乎支持所有的語言,是字元編碼最常用的標準。Unicode 規定,每個字元使用唯一的整數代碼點(code point)表示,其值介於 0 和 0x10FFFF 之間。把代碼點按順序放置,就能得到一個 Unicode 字元串。
因此,TensorFlow 支持 Unicode 對中文 NLP 的研究人員來說絕對算得上是一大利好。與此同時,TensorFlow 社區也推出了新的 Unicode colab 教程,展示了如何在 TensorFlow 中表示 Unicode 字元串。
在使用 TensorFlow 時,有兩種標準方式來表示 Unicode 字元串:
作為整數向量,其中每個位置包含一個代碼點。
作為字元串,使用字元編碼將代碼點序列編碼到字元串中,包括最常見的 UTF-8、UTF-16 等字元編碼。
以下代碼分別為使用代碼點 UTF-8 和 UTF-16 顯示字元串「語言處理」的編碼。
# Unicode string, represented as a vector of code points.
text_chars= tf.constant([35821,35328,22788,29702])
# Unicode string, represented as a UTF-8-encoded string scalar.
text_utf8= tf.constant("xe8xafxadxe8xa8x80xe5xa4x84xe7x90x86")
# Unicode string, represented as a UTF-16-BE-encoded string scalar.
text_utf16be= tf.constant("x8bxedx8ax00Yx04tx06")```
當然,你可能經常需要在不同的表示之間進行轉換,而 TensorFlow 1.13 已添加了執行此操作的函數:
例如,如果要將上述示例中的 UTF-8 表示解碼為代碼點向量,則可以執行以下操作:
當對包含多個字元串的 Tensor 進行解碼時,字元串可能具有不同的長度。unicode_decode 將結果作為 RaggedTensor 返回,其內部維度的長度根據每個字元串中的字元數而變化。
以下是 Unicode 使用方法的詳細介紹,希望對大家能有所幫助。
!pip install -q tf-nightly
from__future__importabsolute_import, division, print_function
importtensorflowastf
tf.enable_eager_execution()
tf.string
通過基本的 TensorFlow tf.string dtype,你可以構建位元組字元串的張量(tensor)。Unicode 字元串默認為 utf-8 編碼。
tf.constant(u"Thanks ")
tf.string 張量可以保存不同長度的位元組串,因為位元組串被視為原子單位。字元串長度不包括在張量尺寸中。
f.constant([u"You"re",u"welcome!"]).shape
TensorShape([Dimension(2)])
Unicode 表示
在 TensorFlow 中有兩種表示 Unicode 字元串的標準方法:
字元串標量,使用已知字元編碼對代碼點序列進行編碼。
int32 vector,每個位置包含一個代碼點。
例如,以下三個值都表示 Unicode 字元串「語言處理」。
# Unicode string, represented as a UTF-8 encoded string scalar.
text_utf8 = tf.constant(u"語言處理")
text_utf8
# Unicode string, represented as a UTF-16-BE encoded string scalar.
text_utf16be = tf.constant(u"語言處理".encode("UTF-16-BE"))
text_utf16be
# Unicode string, represented as a vector of Unicode code points.
text_chars = tf.constant([ord(char)forcharinu"語言處理"])
text_chars
表示之間的轉換
TensorFlow 提供了在這些不同表示之間進行轉換的操作:
Batch dimensions
解碼多個字元串時,每個字元串中的字元數可能不相等。 其返回結果是 tf.RaggedTensor,其中最裡面的維度的長度根據每個字元串中的字元數而變化。
[104,195,108,108,111]
[87,104,97,116,32,105,115,32,116,104,101,32,119,101,97,116,104,101,114,32,116,111,109,111,114,114,111,119]
[71,246,246,100,110,105,103,104,116]
[128522]
你既可以直接使用 tf.RaggedTensor,也可以用 tf.RaggedTensor.to_tensor 將其轉換為有填充的密集 tf.Tensor,或者用 tf.RaggedTensor.to_sparse 將其轉換為 tf.SparseTensor。
batch_chars_padded = batch_chars_ragged.to_tensor(default_value=-1)
print(batch_chars_padded.numpy())
batch_chars_sparse= batch_chars_ragged.to_sparse()
編碼多個相同長度的字元串時,可以使用 tf.Tensor 作為輸入:
編碼多個不同長度的字元串時,應使用 tf.RaggedTensor 作為輸入:
如果你有一個帶填充或稀疏格式的多個字元串的張量,那麼在調用 unicode_encode 之前應將其轉換為 tf.RaggedTensor:
Unicode操作
字元長度
11 bytes; 8 UTF-8 characters
字元子串
b"xf0"
b"xf0x9fx98x8a"
拆分 Unicode 字元串
array([b"T", b"h", b"a", b"n", b"k", b"s", b" ", b"xf0x9fx98x8a"], dtype=object)
字元的位元組偏移量
Atbyteoffset: codepoint127880
Atbyteoffset4: codepoint127881
Atbyteoffset8: codepoint127882
Unicode 腳本
每個 Unicode 代碼點都屬於一個稱為腳本的代碼點集合。字元的腳本有助於確定字元可能屬於哪種語言。例如,我們知道"Б"是西里爾文字,那就表示包含該字元的現代文本可能來自斯拉夫語言,如俄語或烏克蘭語。
[178]
參考鏈接:
https://medium.com/tensorflow/adding-unicode-support-in-tensorflow-6a04fb983b63
https://www.tensorflow.org/tutorials/representation/unicode
※開源項目哪家強?Github年終各大排行榜超級盤點
※給CEO們:吳恩達的五條AI轉型實戰「秘籍」
TAG:AI科技大本營 |