यूनिकोड स्ट्रिंग्स

TensorFlow.org पर देखें Google Colab में चलाएं GitHub पर स्रोत देखें नोटबुक डाउनलोड करें

परिचय

एनएलपी मॉडल अक्सर अलग-अलग वर्णों के साथ अलग-अलग भाषाओं को संभालते हैं। यूनिकोड एक मानक एन्कोडिंग प्रणाली है कि लगभग सभी भाषाओं से पात्रों का प्रतिनिधित्व करने के लिए किया जाता है। हर यूनिकोड वर्ण एक अद्वितीय पूर्णांक का उपयोग कर इनकोडिंग कोड बिंदु के बीच 0 और 0x10FFFF । एक यूनिकोड स्ट्रिंग शून्य या अधिक कोड अंक की एक अनुक्रम है।

यह ट्यूटोरियल दिखाता है कि TensorFlow में यूनिकोड स्ट्रिंग्स का प्रतिनिधित्व कैसे करें और मानक स्ट्रिंग ऑप्स के यूनिकोड समकक्षों का उपयोग करके उनमें हेरफेर करें। यह यूनिकोड स्ट्रिंग्स को स्क्रिप्ट डिटेक्शन के आधार पर टोकन में अलग करता है।

import tensorflow as tf
import numpy as np

tf.string डेटा प्रकार

बुनियादी TensorFlow tf.string dtype आप बाइट तार के tensors का निर्माण करने की अनुमति देता है। यूनिकोड तार कर रहे हैं utf-8 डिफ़ॉल्ट रूप से इनकोडिंग।

tf.constant(u"Thanks 😊")
<tf.Tensor: shape=(), dtype=string, numpy=b'Thanks \xf0\x9f\x98\x8a'>

एक tf.string टेन्सर व्यवहार करता है परमाणु इकाइयों के रूप में तार बाइट। यह इसे अलग-अलग लंबाई के बाइट स्ट्रिंग्स को स्टोर करने में सक्षम बनाता है। स्ट्रिंग की लंबाई टेंसर आयामों में शामिल नहीं है।

tf.constant([u"You're", u"welcome!"]).shape
TensorShape([2])

आप निर्माण तार करने के लिए अजगर का उपयोग करते हैं, ध्यान दें कि स्ट्रिंग शाब्दिक हैं डिफ़ॉल्ट रूप से यूनिकोड-इनकोडिंग।

यूनिकोड का प्रतिनिधित्व

TensorFlow में यूनिकोड स्ट्रिंग का प्रतिनिधित्व करने के दो मानक तरीके हैं:

  • string अदिश - जहां कोड अंक के अनुक्रम एक ज्ञात का उपयोग कर इनकोडिंग वर्ण एन्कोडिंग
  • int32 वेक्टर - जहां प्रत्येक स्थिति एक भी कोड बिंदु शामिल हैं।

उदाहरण के लिए, निम्नलिखित तीन मानों सभी यूनिकोड स्ट्रिंग प्रतिनिधित्व करते हैं "语言处理" (जो साधन चीनी में "भाषा संसाधन"):

# 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)>

अभ्यावेदन के बीच कनवर्ट करना

TensorFlow इन विभिन्न अभ्यावेदन के बीच कनवर्ट करने के लिए संचालन प्रदान करता है:

  • tf.strings.unicode_decode : धर्मान्तरित कोड अंक की एक वेक्टर के लिए एक एन्कोड स्ट्रिंग अदिश।
  • tf.strings.unicode_encode : धर्मान्तरित एक एन्कोड स्ट्रिंग अदिश के लिए कोड अंक की एक वेक्टर।
  • tf.strings.unicode_transcode : धर्मान्तरित एक अलग एन्कोडिंग के लिए एक एन्कोड स्ट्रिंग अदिश।
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'>

बैच आयाम

एकाधिक स्ट्रिंग्स को डिकोड करते समय, प्रत्येक स्ट्रिंग में वर्णों की संख्या समान नहीं हो सकती है। वापसी परिणाम एक है tf.RaggedTensor , जहां अंतरतम आयाम लंबाई प्रत्येक स्ट्रिंग में वर्णों की संख्या पर निर्भर करता है।

# 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]

आप इस का उपयोग कर सकते हैं tf.RaggedTensor सीधे, या यह एक घने में बदलने का tf.Tensor गद्दी या एक साथ tf.SparseTensor तरीकों का उपयोग कर tf.RaggedTensor.to_tensor और 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,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _,      _]]

जब एक ही लंबाई के साथ कई तार एन्कोडिंग, एक का उपयोग tf.Tensor इनपुट के रूप में।

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)>

जब लंबाई बदलती के साथ कई तार एन्कोडिंग, एक का उपयोग tf.RaggedTensor इनपुट के रूप में।

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)>

आप गद्देदार या विरल प्रारूप में कई तार के साथ एक टेन्सर है, तो उसे पहले कन्वर्ट एक में tf.RaggedTensor कॉल करने से पहले 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)>

यूनिकोड संचालन

चरित्र की लंबाई

का प्रयोग करें unit के पैरामीटर tf.strings.length दर्शाने के लिए चरित्र लंबाई की गणना की जानी चाहिए सेशन। unit को चूक "BYTE" , लेकिन यह इस तरह के रूप में अन्य मूल्यों, करने के लिए सेट किया जा सकता है "UTF8_CHAR" या "UTF16_CHAR" , प्रत्येक एन्कोडेड स्ट्रिंग में यूनिकोड कोड पॉइंट्स की संख्या का निर्धारण करने के लिए।

# 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

कैरेक्टर सबस्ट्रिंग

tf.strings.substr सेशन स्वीकार करता unit पैरामीटर, और निर्धारित करने के लिए क्या ऑफसेट की तरह इसे इस्तेमाल करता है pos और len paremeters होते हैं।

# 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'

यूनिकोड स्ट्रिंग्स को विभाजित करें

tf.strings.unicode_split आपरेशन अलग-अलग पात्रों की सबस्ट्रिंग में यूनिकोड तार बांट देता है।

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)

वर्णों के लिए बाइट ऑफ़सेट

द्वारा उत्पन्न चरित्र टेन्सर संरेखित करने के लिए tf.strings.unicode_decode मूल तार के साथ, यह जानना जहां हर किरदार के लिए शुरू होता है के लिए ऑफसेट उपयोगी है। विधि tf.strings.unicode_decode_with_offsets के समान है unicode_decode को छोड़कर यह हर किरदार की भरपाई शुरू युक्त एक दूसरे टेन्सर देता है कि,।

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

यूनिकोड स्क्रिप्ट

प्रत्येक यूनिकोड कोड बिंदु एक के रूप में जाना कोड पॉइंट्स का एक संग्रह के अंतर्गत आता है स्क्रिप्ट । एक चरित्र की लिपि यह निर्धारित करने में सहायक होती है कि चरित्र किस भाषा में हो सकता है। उदाहरण के लिए, यह जानना कि 'Б' सिरिलिक लिपि में है, यह दर्शाता है कि उस चरित्र वाला आधुनिक पाठ रूसी या यूक्रेनी जैसी स्लाव भाषा से होने की संभावना है।

TensorFlow प्रदान करता है tf.strings.unicode_script जो स्क्रिप्ट किसी दिए गए कोडपॉइंट का उपयोग करता है निर्धारित करने के लिए आपरेशन। स्क्रिप्ट कोड हैं int32 करने के लिए इसी मान यूनिकोड के लिए अंतर्राष्ट्रीय अवयव (आईसीयू) UScriptCode मूल्यों।

uscript = tf.strings.unicode_script([33464, 1041])  # ['芸', 'Б']

print(uscript.numpy())  # [17, 8] == [USCRIPT_HAN, USCRIPT_CYRILLIC]
[17  8]

tf.strings.unicode_script आपरेशन भी करने के लिए बहुआयामी लागू किया जा सकता tf.Tensor या tf.RaggedTensor कोड पॉइंट्स के रों:

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]]>

उदाहरण: सरल विभाजन

सेगमेंटेशन टेक्स्ट को शब्द-जैसी इकाइयों में विभाजित करने का कार्य है। यह अक्सर आसान होता है जब शब्दों को अलग करने के लिए अंतरिक्ष वर्णों का उपयोग किया जाता है, लेकिन कुछ भाषाएं (जैसे चीनी और जापानी) रिक्त स्थान का उपयोग नहीं करती हैं, और कुछ भाषाओं (जैसे जर्मन) में लंबे यौगिक होते हैं जिन्हें उनके अर्थ का विश्लेषण करने के लिए विभाजित किया जाना चाहिए। वेब टेक्स्ट में, "NY株価" (न्यूयॉर्क स्टॉक एक्सचेंज) के रूप में, विभिन्न भाषाओं और लिपियों को अक्सर एक साथ मिलाया जाता है।

हम स्क्रिप्ट में अनुमानित शब्द सीमाओं में परिवर्तन का उपयोग करके बहुत मोटा विभाजन (किसी भी एमएल मॉडल को लागू किए बिना) कर सकते हैं। यह उपरोक्त "NY株価" उदाहरण जैसे तारों के लिए काम करेगा। यह उन अधिकांश भाषाओं के लिए भी काम करेगा जो रिक्त स्थान का उपयोग करती हैं, क्योंकि विभिन्न लिपियों के अंतरिक्ष वर्णों को USCRIPT_COMMON के रूप में वर्गीकृत किया जाता है, एक विशेष स्क्रिप्ट कोड जो किसी भी वास्तविक पाठ से भिन्न होता है।

# dtype: string; shape: [num_sentences]
#
# The sentences to process.  Edit this line to try out different inputs!
sentence_texts = [u'Hello, world.', u'世界こんにちは']

सबसे पहले, वाक्यों को वर्ण कोड बिंदुओं में डिकोड करें, और प्रत्येक वर्ण के लिए स्क्रिप्ट पहचानकर्ता खोजें।

# 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]]>

यह निर्धारित करने के लिए स्क्रिप्ट पहचानकर्ताओं का उपयोग करें कि शब्द सीमाएँ कहाँ जोड़ी जानी चाहिए। प्रत्येक वाक्य की शुरुआत में एक शब्द सीमा जोड़ें, और प्रत्येक वर्ण के लिए जिसकी स्क्रिप्ट पिछले वर्ण से भिन्न है।

# 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)

इसके बाद आप उन शुरू ऑफसेट का प्रयोग कर एक निर्माण करने के लिए कर सकते हैं RaggedTensor सभी बैचों से शब्दों की सूची से युक्त।

# 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]]>

खत्म करने के लिए, खंड शब्द कोड पॉइंट्स RaggedTensor पठनीयता के लिए UTF-8 तार में वाक्य और एनकोड में वापस।

# 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']]