TensorFlow.org'da görüntüleyin | Google Colab'da çalıştırın | Kaynağı GitHub'da görüntüleyin | Not defterini indir |
Tanıtım
NLP modelleri genellikle farklı karakter setleriyle farklı dilleri işler. Unicode neredeyse tüm dillerdeki karakterleri göstermek için kullanılan standart bir kodlama sistemidir. Her Unicode karakter benzersiz tamsayı kullanılarak kodlanan kod noktası arasındaki 0
ve 0x10FFFF
. Bir Unicode dizgisini sıfır ya da daha fazla kod noktalarına bir dizisidir.
Bu öğretici, Unicode dizelerinin TensorFlow'da nasıl temsil edileceğini ve standart dize operasyonlarının Unicode eşdeğerlerini kullanarak bunların nasıl değiştirileceğini gösterir. Unicode dizelerini, komut dosyası algılamaya dayalı olarak belirteçlere ayırır.
import tensorflow as tf
import numpy as np
tf.string
veri türü
Temel TensorFlow tf.string
dtype
sen bayt dizeleri tensörleri oluşturmanızı sağlar. Unicode dizeleri utf-8 varsayılan olarak kodlanmış.
tf.constant(u"Thanks 😊")
<tf.Tensor: shape=(), dtype=string, numpy=b'Thanks \xf0\x9f\x98\x8a'>
Bir tf.string
tensör davranır atomik birimler olarak dizeleri bayt. Bu, farklı uzunluklardaki bayt dizilerini saklamasını sağlar. Tel uzunluğu, tensör boyutlarına dahil değildir.
tf.constant([u"You're", u"welcome!"]).shape
TensorShape([2])
Eğer yapı dizelerine Python kullanıyorsanız, not o dize hazır olan varsayılan olarak Unicode ile kodlanmış.
Unicode'u temsil etme
TensorFlow'da bir Unicode dizesini temsil etmenin iki standart yolu vardır:
-
string
skalar - kod noktalarının dizisi bilinen kullanılarak kodlanır karakter kodlamasını . -
int32
vektör - her bir konum tek bir kod noktası içerir.
Örneğin, aşağıdaki üç değer tüm Unicode dizesi temsil "语言处理"
(Çince hangi vasıta "dil işleme"):
# Unicode string, represented as a UTF-8 encoded string scalar.
text_utf8 = tf.constant(u"语言处理")
text_utf8
<tf.Tensor: shape=(), dtype=string, numpy=b'\xe8\xaf\xad\xe8\xa8\x80\xe5\xa4\x84\xe7\x90\x86'>
# Unicode string, represented as a UTF-16-BE encoded string scalar.
text_utf16be = tf.constant(u"语言处理".encode("UTF-16-BE"))
text_utf16be
<tf.Tensor: shape=(), dtype=string, numpy=b'\x8b\xed\x8a\x00Y\x04t\x06'>
# Unicode string, represented as a vector of Unicode code points.
text_chars = tf.constant([ord(char) for char in u"语言处理"])
text_chars
<tf.Tensor: shape=(4,), dtype=int32, numpy=array([35821, 35328, 22788, 29702], dtype=int32)>
temsiller arasında dönüştürme
TensorFlow, bu farklı temsiller arasında dönüştürme işlemleri sağlar:
-
tf.strings.unicode_decode
: dönüştürür kod noktalarının bir vektöre kodlanmış bir dize sayıl. -
tf.strings.unicode_encode
: dönüştürür kodlanmış dize sayısal alan için kod noktalarının bir vektör. -
tf.strings.unicode_transcode
: dönüştürür farklı kodlama kodlanmış bir dize sayıl.
tf.strings.unicode_decode(text_utf8,
input_encoding='UTF-8')
<tf.Tensor: shape=(4,), dtype=int32, numpy=array([35821, 35328, 22788, 29702], dtype=int32)>
tf.strings.unicode_encode(text_chars,
output_encoding='UTF-8')
<tf.Tensor: shape=(), dtype=string, numpy=b'\xe8\xaf\xad\xe8\xa8\x80\xe5\xa4\x84\xe7\x90\x86'>
tf.strings.unicode_transcode(text_utf8,
input_encoding='UTF8',
output_encoding='UTF-16-BE')
<tf.Tensor: shape=(), dtype=string, numpy=b'\x8b\xed\x8a\x00Y\x04t\x06'>
Parti boyutları
Birden çok dizenin kodunu çözerken, her dizedeki karakter sayısı eşit olmayabilir. Dönüş sonucu meydana gelir tf.RaggedTensor
iç boyutu uzunluk her bir dize karakter sayısına bağlı olarak değişir.
# A batch of Unicode strings, each represented as a UTF8-encoded string.
batch_utf8 = [s.encode('UTF-8') for s in
[u'hÃllo', u'What is the weather tomorrow', u'Göödnight', u'😊']]
batch_chars_ragged = tf.strings.unicode_decode(batch_utf8,
input_encoding='UTF-8')
for sentence_chars in batch_chars_ragged.to_list():
print(sentence_chars)
[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]
Bu kullanabilirsiniz tf.RaggedTensor
doğrudan veya yoğun dönüştürmek tf.Tensor
dolgu veya bir ile tf.SparseTensor
yöntemlerle tf.RaggedTensor.to_tensor
ve tf.RaggedTensor.to_sparse
.
batch_chars_padded = batch_chars_ragged.to_tensor(default_value=-1)
print(batch_chars_padded.numpy())
[[ 104 195 108 108 111 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1] [ 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 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1] [128522 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1]]
batch_chars_sparse = batch_chars_ragged.to_sparse()
nrows, ncols = batch_chars_sparse.dense_shape.numpy()
elements = [['_' for i in range(ncols)] for j in range(nrows)]
for (row, col), value in zip(batch_chars_sparse.indices.numpy(), batch_chars_sparse.values.numpy()):
elements[row][col] = str(value)
# max_width = max(len(value) for row in elements for value in row)
value_lengths = []
for row in elements:
for value in row:
value_lengths.append(len(value))
max_width = max(value_lengths)
print('[%s]' % '\n '.join(
'[%s]' % ', '.join(value.rjust(max_width) for value in row)
for row in elements))
[[ 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, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]]
Aynı uzunlukta olan çok sayıda dizge kodlarken, bir kullanma tf.Tensor
girdi olarak kullanılmaktadır.
tf.strings.unicode_encode([[99, 97, 116], [100, 111, 103], [99, 111, 119]],
output_encoding='UTF-8')
<tf.Tensor: shape=(3,), dtype=string, numpy=array([b'cat', b'dog', b'cow'], dtype=object)>
Değişken uzunlukta olan çok sayıda dizge kodlarken, bir kullanma tf.RaggedTensor
girdi olarak kullanılmaktadır.
tf.strings.unicode_encode(batch_chars_ragged, output_encoding='UTF-8')
<tf.Tensor: shape=(4,), dtype=string, numpy= array([b'h\xc3\x83llo', b'What is the weather tomorrow', b'G\xc3\xb6\xc3\xb6dnight', b'\xf0\x9f\x98\x8a'], dtype=object)>
Eğer yastıklı veya seyrek biçimde birden çok dizeli bir tensörünü varsa, içine ilk dönüştürmek tf.RaggedTensor
çağırmadan önce tf.strings.unicode_encode
.
tf.strings.unicode_encode(
tf.RaggedTensor.from_sparse(batch_chars_sparse),
output_encoding='UTF-8')
<tf.Tensor: shape=(4,), dtype=string, numpy= array([b'h\xc3\x83llo', b'What is the weather tomorrow', b'G\xc3\xb6\xc3\xb6dnight', b'\xf0\x9f\x98\x8a'], dtype=object)>
tf.strings.unicode_encode(
tf.RaggedTensor.from_tensor(batch_chars_padded, padding=-1),
output_encoding='UTF-8')
<tf.Tensor: shape=(4,), dtype=string, numpy= array([b'h\xc3\x83llo', b'What is the weather tomorrow', b'G\xc3\xb6\xc3\xb6dnight', b'\xf0\x9f\x98\x8a'], dtype=object)>
Unicode işlemleri
karakter uzunluğu
Kullanım unit
parametresi tf.strings.length
karakter uzunlukları bilgisayarlı nasıl olması gerektiği belirten op. unit
varsayılan "BYTE"
, ancak bu gibi başka değerler, ayarlanabilir "UTF8_CHAR"
ya da "UTF16_CHAR"
, her bir kodlanmış dize Unicode codepoints sayısını belirlemek için.
# Note that the final character takes up 4 bytes in UTF8.
thanks = u'Thanks 😊'.encode('UTF-8')
num_bytes = tf.strings.length(thanks).numpy()
num_chars = tf.strings.length(thanks, unit='UTF8_CHAR').numpy()
print('{} bytes; {} UTF-8 characters'.format(num_bytes, num_chars))
11 bytes; 8 UTF-8 characters
Karakter alt dizeleri
tf.strings.substr
op kabul unit
parametresi ve nazik uzaklıklar belirlemek için kullanır pos
ve len
parametrelerine içerirler.
# Here, unit='BYTE' (default). Returns a single byte with len=1
tf.strings.substr(thanks, pos=7, len=1).numpy()
b'\xf0'
# Specifying unit='UTF8_CHAR', returns a single 4 byte character in this case
print(tf.strings.substr(thanks, pos=7, len=1, unit='UTF8_CHAR').numpy())
b'\xf0\x9f\x98\x8a'
Unicode dizelerini böl
tf.strings.unicode_split
operasyonu bireysel karakterlerin alt dizelere içine unicode dizeleri böler.
tf.strings.unicode_split(thanks, 'UTF-8').numpy()
array([b'T', b'h', b'a', b'n', b'k', b's', b' ', b'\xf0\x9f\x98\x8a'], dtype=object)
Karakterler için bayt ofsetleri
Tarafından üretilen karakter tensörünü hizalamak için tf.strings.unicode_decode
orijinal dize ile, her karakter başladığı için ofset bilmek yararlıdır. Yöntem tf.strings.unicode_decode_with_offsets
benzer unicode_decode
her karakter başlangıç ofsetinin içeren ikinci tensörünün döndürmesi dışında.
codepoints, offsets = tf.strings.unicode_decode_with_offsets(u'🎈🎉🎊', 'UTF-8')
for (codepoint, offset) in zip(codepoints.numpy(), offsets.numpy()):
print('At byte offset {}: codepoint {}'.format(offset, codepoint))
At byte offset 0: codepoint 127880 At byte offset 4: codepoint 127881 At byte offset 8: codepoint 127882
Unicode komut dosyaları
Her Unicode kod noktası olarak bilinen codepoints tek koleksiyona ait senaryo . Bir karakterin yazısı, karakterin hangi dilde olabileceğini belirlemede yardımcı olur. Örneğin, 'Б'nin Kiril alfabesinde olduğunu bilmek, o karakteri içeren modern metnin muhtemelen Rusça veya Ukraynaca gibi bir Slav dilinden geldiğini gösterir.
TensorFlow içerir tf.strings.unicode_script
olan komut, belirli bir kod noktası kullanımını belirlemek için işlem. Komut kodları int32
tekabül değerleri Unicode için Uluslararası Bileşenlerinin (YBÜ) UScriptCode
değerler.
uscript = tf.strings.unicode_script([33464, 1041]) # ['芸', 'Б']
print(uscript.numpy()) # [17, 8] == [USCRIPT_HAN, USCRIPT_CYRILLIC]
[17 8]
tf.strings.unicode_script
işlemi de çok boyutlu uygulanabilir tf.Tensor
ler veya tf.RaggedTensor
s codepoints arasında:
print(tf.strings.unicode_script(batch_chars_ragged))
<tf.RaggedTensor [[25, 25, 25, 25, 25], [25, 25, 25, 25, 0, 25, 25, 0, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, 25, 25], [25, 25, 25, 25, 25, 25, 25, 25, 25], [0]]>
Örnek: Basit segmentasyon
Segmentasyon, metni kelime benzeri birimlere ayırma görevidir. Sözcükleri ayırmak için boşluk karakterleri kullanıldığında bu genellikle kolaydır, ancak bazı diller (Çince ve Japonca gibi) boşluk kullanmaz ve bazı diller (Almanca gibi) anlamlarını analiz etmek için bölünmesi gereken uzun bileşikler içerir. Web metninde, "NY株価" (New York Menkul Kıymetler Borsası) örneğinde olduğu gibi, farklı diller ve yazılar sıklıkla birlikte karıştırılır.
Kelime sınırlarını yaklaşık olarak belirlemek için komut dosyasındaki değişiklikleri kullanarak (herhangi bir ML modeli uygulamadan) çok kaba segmentasyon gerçekleştirebiliriz. Bu, yukarıdaki "NY株価" örneğindeki gibi dizeler için işe yarar. Ayrıca, çeşitli komut dosyalarının boşluk karakterlerinin tümü, herhangi bir gerçek metinden farklı olan özel bir komut dosyası kodu olan USCRIPT_COMMON olarak sınıflandırıldığından, boşluk kullanan çoğu dilde çalışır.
# dtype: string; shape: [num_sentences]
#
# The sentences to process. Edit this line to try out different inputs!
sentence_texts = [u'Hello, world.', u'世界こんにちは']
İlk olarak, cümlelerin kodunu karakter kod noktalarına çözün ve her karakter için kod tanımlayıcısını bulun.
# dtype: int32; shape: [num_sentences, (num_chars_per_sentence)]
#
# sentence_char_codepoint[i, j] is the codepoint for the j'th character in
# the i'th sentence.
sentence_char_codepoint = tf.strings.unicode_decode(sentence_texts, 'UTF-8')
print(sentence_char_codepoint)
# dtype: int32; shape: [num_sentences, (num_chars_per_sentence)]
#
# sentence_char_scripts[i, j] is the Unicode script of the j'th character in
# the i'th sentence.
sentence_char_script = tf.strings.unicode_script(sentence_char_codepoint)
print(sentence_char_script)
<tf.RaggedTensor [[72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 46], [19990, 30028, 12371, 12435, 12395, 12385, 12399]]> <tf.RaggedTensor [[25, 25, 25, 25, 25, 0, 0, 25, 25, 25, 25, 25, 0], [17, 17, 20, 20, 20, 20, 20]]>
Kelime sınırlarının nereye eklenmesi gerektiğini belirlemek için kod tanımlayıcılarını kullanın. Her cümlenin başına ve yazısı önceki karakterden farklı olan her karakter için bir kelime sınırı ekleyin.
# dtype: bool; shape: [num_sentences, (num_chars_per_sentence)]
#
# sentence_char_starts_word[i, j] is True if the j'th character in the i'th
# sentence is the start of a word.
sentence_char_starts_word = tf.concat(
[tf.fill([sentence_char_script.nrows(), 1], True),
tf.not_equal(sentence_char_script[:, 1:], sentence_char_script[:, :-1])],
axis=1)
# dtype: int64; shape: [num_words]
#
# word_starts[i] is the index of the character that starts the i'th word (in
# the flattened list of characters from all sentences).
word_starts = tf.squeeze(tf.where(sentence_char_starts_word.values), axis=1)
print(word_starts)
tf.Tensor([ 0 5 7 12 13 15], shape=(6,), dtype=int64)
Daha sonra kurmak için bu başlangıç uzaklıklar kullanabilirsiniz RaggedTensor
tüm toplu kelimelerin listesini içeren.
# dtype: int32; shape: [num_words, (num_chars_per_word)]
#
# word_char_codepoint[i, j] is the codepoint for the j'th character in the
# i'th word.
word_char_codepoint = tf.RaggedTensor.from_row_starts(
values=sentence_char_codepoint.values,
row_starts=word_starts)
print(word_char_codepoint)
<tf.RaggedTensor [[72, 101, 108, 108, 111], [44, 32], [119, 111, 114, 108, 100], [46], [19990, 30028], [12371, 12435, 12395, 12385, 12399]]>
Bitirmek için, bölüm kelimesi codepoints RaggedTensor
okunabilirlik için UTF-8 dizeleri içine cümle ve kodlamak içine geri.
# dtype: int64; shape: [num_sentences]
#
# sentence_num_words[i] is the number of words in the i'th sentence.
sentence_num_words = tf.reduce_sum(
tf.cast(sentence_char_starts_word, tf.int64),
axis=1)
# dtype: int32; shape: [num_sentences, (num_words_per_sentence), (num_chars_per_word)]
#
# sentence_word_char_codepoint[i, j, k] is the codepoint for the k'th character
# in the j'th word in the i'th sentence.
sentence_word_char_codepoint = tf.RaggedTensor.from_row_lengths(
values=word_char_codepoint,
row_lengths=sentence_num_words)
print(sentence_word_char_codepoint)
tf.strings.unicode_encode(sentence_word_char_codepoint, 'UTF-8').to_list()
<tf.RaggedTensor [[[72, 101, 108, 108, 111], [44, 32], [119, 111, 114, 108, 100], [46]], [[19990, 30028], [12371, 12435, 12395, 12385, 12399]]]> [[b'Hello', b', ', b'world', b'.'], [b'\xe4\xb8\x96\xe7\x95\x8c', b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf']]