ইউনিকোড স্ট্রিং

TensorFlow.org এ দেখুন Google Colab-এ চালান GitHub-এ উৎস দেখুন নোটবুক ডাউনলোড করুন

ভূমিকা

NLP মডেলগুলি প্রায়ই বিভিন্ন অক্ষর সেট সহ বিভিন্ন ভাষা পরিচালনা করে। ইউনিকোড একটি প্রমিত এনকোডিং সিস্টেম প্রায় সব ভাষা থেকে অক্ষর প্রতিনিধিত্ব করতে ব্যবহৃত হয়। প্রতিটি ইউনিকোড অক্ষর একটি অনন্য পূর্ণসংখ্যা ব্যবহার এনকোডেড হয়েছে কোড বিন্দু মধ্যে 0 এবং 0x10FFFF । একটি ইউনিকোড স্ট্রিং শূন্য বা তার বেশি কোড পয়েন্ট ক্রম।

এই টিউটোরিয়ালটি দেখায় কিভাবে টেনসরফ্লোতে ইউনিকোড স্ট্রিংগুলিকে উপস্থাপন করতে হয় এবং স্ট্যান্ডার্ড স্ট্রিং অপসের ইউনিকোড সমতুল্য ব্যবহার করে সেগুলিকে ম্যানিপুলেট করতে হয়। এটি স্ক্রিপ্ট সনাক্তকরণের উপর ভিত্তি করে ইউনিকোড স্ট্রিংগুলিকে টোকেনে আলাদা করে।

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

আপনি কনস্ট্রাক্ট স্ট্রিং পাইথন ব্যবহার করেন, তাহলে মনে রাখবেন যে স্ট্রিং লিটারেল হয় ডিফল্টরূপে ইউনিকোড এনকোডেড।

ইউনিকোড প্রতিনিধিত্ব

টেনসরফ্লোতে একটি ইউনিকোড স্ট্রিং প্রতিনিধিত্ব করার দুটি আদর্শ উপায় রয়েছে:

  • 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" , প্রতিটি এনকোডেড স্ট্রিং ইউনিকোড codepoints সংখ্যা নির্ধারণ।

# 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 অপারেশন পৃথক অক্ষর, সাবস্ট্রিং মধ্যে ইউনিকোড স্ট্রিং splits।

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

ইউনিকোড স্ক্রিপ্ট

প্রতিটি ইউনিকোড কোড বিন্দু একটি নামে পরিচিত codepoints একটি একক সংগ্রহের অংশ স্ক্রিপ্ট । অক্ষরটি কোন ভাষায় হতে পারে তা নির্ধারণ করতে একটি অক্ষরের স্ক্রিপ্ট সহায়ক। উদাহরণস্বরূপ, 'Б' সিরিলিক স্ক্রিপ্টে রয়েছে তা জানা ইঙ্গিত দেয় যে আধুনিক পাঠ্যটি সম্ভবত স্লাভিক ভাষা যেমন রাশিয়ান বা ইউক্রেনীয় থেকে এসেছে।

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 s অথবা tf.RaggedTensor codepoints এর S:

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

শেষ করার জন্য, সেগমেন্ট শব্দ codepoints 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']]