एमएल समुदाय दिवस 9 नवंबर है! TensorFlow, JAX से नई जानकारी के लिए हमसे जुड़ें, और अधिक जानें

TF टेक्स्ट के साथ BERT प्रीप्रोसेसिंग

TensorFlow.org पर देखें Google Colab में चलाएं गिटहब पर देखें नोटबुक डाउनलोड करें

अवलोकन

टेक्स्ट प्रीप्रोसेसिंग कच्चे टेक्स्ट का मॉडल के पूर्णांक इनपुट में एंड-टू-एंड रूपांतरण है। एनएलपी मॉडल अक्सर टेक्स्ट को प्रीप्रोसेस करने के लिए कई सैकड़ों (यदि हजारों नहीं) पायथन कोड की पंक्तियों के साथ होते हैं। मॉडल के लिए टेक्स्ट प्रीप्रोसेसिंग अक्सर एक चुनौती होती है क्योंकि:

  • प्रशिक्षण-सेवारत तिरछा। यह सुनिश्चित करना कठिन होता जा रहा है कि मॉडल के इनपुट के प्रीप्रोसेसिंग लॉजिक मॉडल विकास के सभी चरणों (जैसे प्रीट्रेनिंग, फाइन-ट्यूनिंग, मूल्यांकन, अनुमान) में सुसंगत हैं। अलग-अलग हाइपरपैरामीटर, टोकननाइजेशन, स्ट्रिंग प्रीप्रोसेसिंग एल्गोरिदम या अलग-अलग चरणों में असंगत रूप से पैकेजिंग मॉडल इनपुट का उपयोग करने से मॉडल को हार्ड-टू-डीबग और विनाशकारी प्रभाव मिल सकता है।

  • दक्षता और लचीलापन। जबकि प्रीप्रोसेसिंग ऑफ़लाइन किया जा सकता है (उदाहरण के लिए डिस्क पर फ़ाइलों के लिए संसाधित आउटपुट लिखकर और फिर इनपुट पाइपलाइन में प्रीप्रोसेस्ड डेटा का पुन: उपभोग करके), इस विधि में एक अतिरिक्त फ़ाइल पढ़ने और लिखने की लागत होती है। प्रीप्रोसेसिंग ऑफ़लाइन भी असुविधाजनक है यदि प्रीप्रोसेसिंग निर्णय हैं जो गतिशील रूप से होने की आवश्यकता है। किसी भिन्न विकल्प के साथ प्रयोग करने के लिए डेटासेट को फिर से बनाने की आवश्यकता होगी।

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

इसके अतिरिक्त, सरल मॉडल इंटरफेस अलग-अलग, अस्पष्टीकृत डेटासेट पर मॉडल (जैसे अनुमान या प्रशिक्षण) को आजमाने के लिए इसे और अधिक सुविधाजनक बनाते हैं।

TF.Text . के साथ टेक्स्ट प्रीप्रोसेसिंग

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

इस ट्यूटोरियल कैसे TF.Text preprocessing ऑप्स उपयोग करने के लिए बर्ट मॉडल और काम pretraining मास्किंग भाषा के लिए आदानों "नकाबपोश एल एम और मास्किंग प्रक्रिया" के में वर्णित के लिए आदानों में पाठ डेटा को बदलने के लिए दिखाई देगा भाषा के लिए दीप द्वि-दिशा ट्रांसफॉर्मर की पूर्व प्रशिक्षण: बर्ट समझौता । इस प्रक्रिया में सबवर्ड इकाइयों में टेक्स्ट को टोकन करना, वाक्यों को जोड़ना, सामग्री को एक निश्चित आकार में ट्रिम करना और नकाबपोश भाषा मॉडलिंग कार्य के लिए लेबल निकालना शामिल है।

सेट अप

आइए पहले उन पैकेजों और पुस्तकालयों को आयात करें जिनकी हमें आवश्यकता है।

pip install -q -U tensorflow-text
import tensorflow as tf
import tensorflow_text as text
import functools
2021-08-17 11:09:49.001212: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0

हमारे डेटा दो पाठ विशेषताएं शामिल हैं और हम एक उदाहरण बना सकते हैं tf.data.Dataset । हमारा लक्ष्य एक समारोह है कि हम आपूर्ति कर सकते हैं बनाने के लिए है Dataset.map() प्रशिक्षण में इस्तेमाल किया जाएगा के साथ।

examples = {
    "text_a": [
      b"Sponge bob Squarepants is an Avenger",
      b"Marvel Avengers"
    ],
    "text_b": [
     b"Barack Obama is the President.",
     b"President is the highest office"
  ],
}

dataset = tf.data.Dataset.from_tensor_slices(examples)
next(iter(dataset))
2021-08-17 11:09:50.986363: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcuda.so.1
2021-08-17 11:09:51.592118: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-17 11:09:51.593052: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1733] Found device 0 with properties: 
pciBusID: 0000:00:05.0 name: Tesla V100-SXM2-16GB computeCapability: 7.0
coreClock: 1.53GHz coreCount: 80 deviceMemorySize: 15.78GiB deviceMemoryBandwidth: 836.37GiB/s
2021-08-17 11:09:51.593089: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
2021-08-17 11:09:51.596478: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublas.so.11
2021-08-17 11:09:51.596574: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublasLt.so.11
2021-08-17 11:09:51.597657: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcufft.so.10
2021-08-17 11:09:51.597974: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcurand.so.10
2021-08-17 11:09:51.598957: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcusolver.so.11
2021-08-17 11:09:51.599848: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcusparse.so.11
2021-08-17 11:09:51.600019: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudnn.so.8
2021-08-17 11:09:51.600118: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-17 11:09:51.601014: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-17 11:09:51.601942: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1871] Adding visible gpu devices: 0
2021-08-17 11:09:51.602609: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2021-08-17 11:09:51.603201: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-17 11:09:51.604143: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1733] Found device 0 with properties: 
pciBusID: 0000:00:05.0 name: Tesla V100-SXM2-16GB computeCapability: 7.0
coreClock: 1.53GHz coreCount: 80 deviceMemorySize: 15.78GiB deviceMemoryBandwidth: 836.37GiB/s
2021-08-17 11:09:51.604221: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-17 11:09:51.605115: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-17 11:09:51.605907: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1871] Adding visible gpu devices: 0
2021-08-17 11:09:51.605943: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
2021-08-17 11:09:52.196319: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1258] Device interconnect StreamExecutor with strength 1 edge matrix:
2021-08-17 11:09:52.196355: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1264]      0 
2021-08-17 11:09:52.196362: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1277] 0:   N 
2021-08-17 11:09:52.196585: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-17 11:09:52.197468: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-17 11:09:52.198293: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-17 11:09:52.199096: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1418] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 14646 MB memory) -> physical GPU (device: 0, name: Tesla V100-SXM2-16GB, pci bus id: 0000:00:05.0, compute capability: 7.0)
{'text_a': <tf.Tensor: shape=(), dtype=string, numpy=b'Sponge bob Squarepants is an Avenger'>,
 'text_b': <tf.Tensor: shape=(), dtype=string, numpy=b'Barack Obama is the President.'>}

tokenizing

हमारा पहला कदम किसी भी स्ट्रिंग प्रीप्रोसेसिंग को चलाना और हमारे डेटासेट को टोकन करना है। यह प्रयोग किया जा सकता text.BertTokenizer है, जो एक है text.Splitter कि के लिए subwords या wordpieces में वाक्य tokenize कर सकते हैं बर्ट मॉडल एक शब्दावली से उत्पन्न दिया Wordpiece एल्गोरिथ्म । आप से TF.Text में उपलब्ध अन्य subword tokenizers के बारे में अधिक सीख सकते हैं यहां

शब्दावली पहले से उत्पन्न BERT चेकपॉइंट से हो सकती है, या आप अपने स्वयं के डेटा पर स्वयं उत्पन्न कर सकते हैं। इस उदाहरण के प्रयोजनों के लिए, आइए एक खिलौना शब्दावली बनाएं:

_VOCAB = [
    # Special tokens
    b"[UNK]", b"[MASK]", b"[RANDOM]", b"[CLS]", b"[SEP]",
    # Suffixes
    b"##ack", b"##ama", b"##ger", b"##gers", b"##onge", b"##pants",  b"##uare",
    b"##vel", b"##ven", b"an", b"A", b"Bar", b"Hates", b"Mar", b"Ob",
    b"Patrick", b"President", b"Sp", b"Sq", b"bob", b"box", b"has", b"highest",
    b"is", b"office", b"the",
]

_START_TOKEN = _VOCAB.index(b"[CLS]")
_END_TOKEN = _VOCAB.index(b"[SEP]")
_MASK_TOKEN = _VOCAB.index(b"[MASK]")
_RANDOM_TOKEN = _VOCAB.index(b"[RANDOM]")
_UNK_TOKEN = _VOCAB.index(b"[UNK]")
_MAX_SEQ_LEN = 8
_MAX_PREDICTIONS_PER_BATCH = 5

_VOCAB_SIZE = len(_VOCAB)

lookup_table = tf.lookup.StaticVocabularyTable(
    tf.lookup.KeyValueTensorInitializer(
      keys=_VOCAB,
      key_dtype=tf.string,
      values=tf.range(
          tf.size(_VOCAB, out_type=tf.int64), dtype=tf.int64),
      value_dtype=tf.int64),
      num_oov_buckets=1
)

आइए निर्माण एक text.BertTokenizer ऊपर शब्दावली का उपयोग करते हुए और एक में पाठ आदानों tokenize RaggedTensor .`।

bert_tokenizer = text.BertTokenizer(lookup_table, token_out_type=tf.string)
bert_tokenizer.tokenize(examples["text_a"])
<tf.RaggedTensor [[[b'Sp', b'##onge'], [b'bob'], [b'Sq', b'##uare', b'##pants'], [b'is'], [b'an'], [b'A', b'##ven', b'##ger']], [[b'Mar', b'##vel'], [b'A', b'##ven', b'##gers']]]>
bert_tokenizer.tokenize(examples["text_b"])
<tf.RaggedTensor [[[b'Bar', b'##ack'], [b'Ob', b'##ama'], [b'is'], [b'the'], [b'President'], [b'[UNK]']], [[b'President'], [b'is'], [b'the'], [b'highest'], [b'office']]]>

से पाठ उत्पादन text.BertTokenizer हम देखते हैं कि पाठ tokenized किया जा रहा है की अनुमति देता है, लेकिन मॉडल पूर्णांक आईडी की आवश्यकता है। हम सेट कर सकते हैं token_out_type को परम tf.int64 आईडी (जो शब्दावली में सूचकांक कर रहे हैं) पूर्णांक प्राप्त करने के लिए।

bert_tokenizer = text.BertTokenizer(lookup_table, token_out_type=tf.int64)
segment_a = bert_tokenizer.tokenize(examples["text_a"])
segment_a
<tf.RaggedTensor [[[22, 9], [24], [23, 11, 10], [28], [14], [15, 13, 7]], [[18, 12], [15, 13, 8]]]>
segment_b = bert_tokenizer.tokenize(examples["text_b"])
segment_b
<tf.RaggedTensor [[[16, 5], [19, 6], [28], [30], [21], [0]], [[21], [28], [30], [27], [29]]]>

text.BertTokenizer एक रिटर्न RaggedTensor आकार के साथ [batch, num_tokens, num_wordpieces] । क्योंकि हम अतिरिक्त की जरूरत नहीं है num_tokens हमारे वर्तमान उपयोग के मामले के लिए आयाम, हम एक प्राप्त करने के लिए पिछले दो आयाम विलय कर सकते हैं RaggedTensor आकार के साथ [batch, num_wordpieces] :

segment_a = segment_a.merge_dims(-2, -1)
segment_a
<tf.RaggedTensor [[22, 9, 24, 23, 11, 10, 28, 14, 15, 13, 7], [18, 12, 15, 13, 8]]>
segment_b = segment_b.merge_dims(-2, -1)
segment_b
<tf.RaggedTensor [[16, 5, 19, 6, 28, 30, 21, 0], [21, 28, 30, 27, 29]]>

सामग्री ट्रिमिंग

BERT का मुख्य इनपुट दो वाक्यों का संयोजन है। हालाँकि, BERT को एक निश्चित आकार और आकार में इनपुट की आवश्यकता होती है और हमारे पास ऐसी सामग्री हो सकती है जो हमारे बजट से अधिक हो।

हम एक का उपयोग करके इस से निपटने कर सकते हैं text.Trimmer (एक बार पिछले अक्ष के साथ concatenated) एक पूर्व निर्धारित आकार के लिए हमारी सामग्री नीचे ट्रिम करने के लिए। वहाँ अलग हैं text.Trimmer प्रकार जो अलग एल्गोरिदम का उपयोग करते संरक्षित करने के लिए सामग्री का चयन करें। text.RoundRobinTrimmer उदाहरण के लिए प्रत्येक खंड के लिए समान रूप से कोटा आवंटित करेगा लेकिन वाक्य के सिरों ट्रिम कर सकते हैं। text.WaterfallTrimmer अंतिम वाक्य के अंत से शुरू ट्रिम जाएगा।

हमारे उदाहरण के लिए, हम का उपयोग करेगा RoundRobinTrimmer एक बाएँ-से-सही ढंग से प्रत्येक खंड से जो चयन आइटम नहीं है।

trimmer = text.RoundRobinTrimmer(max_seq_length=[_MAX_SEQ_LEN])
trimmed = trimmer.trim([segment_a, segment_b])
trimmed
[<tf.RaggedTensor [[22, 9, 24, 23], [18, 12, 15, 13]]>,
 <tf.RaggedTensor [[16, 5, 19, 6], [21, 28, 30, 27]]>]

trimmed है, जहां एक बैच भर में तत्वों की संख्या 8 तत्वों (जब साथ अक्ष = -1 concatenated) अब अनुभाग हैं।

खंडों का संयोजन

अब जब हम खंडों छंटनी की है, हम उन्हें एक साथ एक भी प्राप्त करने के लिए गठजोड़ कर सकते हैं RaggedTensor । बर्ट शुरुआत (इंगित करने के लिए विशेष टोकन का उपयोग करता है [CLS] ) और एक खंड (के अंत [SEP] )। हम यह भी एक जरूरत है RaggedTensor जो संयुक्त में आइटम का संकेत Tensor जो खंड के हैं। हम उपयोग कर सकते हैं text.combine_segments() इन दोनों को प्राप्त करने के लिए Tensor डाला विशेष टोकन के साथ।

segments_combined, segments_ids = text.combine_segments(
  [segment_a, segment_b],
  start_of_sequence_id=_START_TOKEN, end_of_segment_id=_END_TOKEN)
segments_combined, segments_ids
(<tf.RaggedTensor [[3, 22, 9, 24, 23, 11, 10, 28, 14, 15, 13, 7, 4, 16, 5, 19, 6, 28, 30, 21, 0, 4], [3, 18, 12, 15, 13, 8, 4, 21, 28, 30, 27, 29, 4]]>,
 <tf.RaggedTensor [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1]]>)

नकाबपोश भाषा मॉडल कार्य

अब है कि हम अपने बुनियादी आदानों है, हम आदानों "नकाबपोश एल एम और मास्किंग प्रक्रिया" के लिए आवश्यक निकालने के लिए शुरू कर सकते हैं काम में वर्णित बर्ट: भाषा समझ के लिए दीप द्वि-दिशा ट्रांसफॉर्मर की पूर्व प्रशिक्षण

नकाबपोश भाषा मॉडल कार्य में हमारे लिए सोचने के लिए दो उप-समस्याएं हैं: (१) मास्किंग के लिए किन वस्तुओं का चयन करना है और (२) उन्हें किन मूल्यों को सौंपा गया है?

आइटम चयन

क्योंकि हम बेतरतीब ढंग से मास्किंग के लिए आइटम का चयन करने का चयन करेंगे, हम एक का उपयोग करेगा text.RandomItemSelectorRandomItemSelector बेतरतीब ढंग से दिए गए प्रतिबंध (करने के लिए एक बैच विषय में आइटम का चयन करता है max_selections_per_batch , selection_rate और unselectable_ids और) रिटर्न एक बूलियन मुखौटा का संकेत है जो आइटम का चयन किया गया।

random_selector = text.RandomItemSelector(
    max_selections_per_batch=_MAX_PREDICTIONS_PER_BATCH,
    selection_rate=0.2,
    unselectable_ids=[_START_TOKEN, _END_TOKEN, _UNK_TOKEN]
)
selected = random_selector.get_selection_mask(
    segments_combined, axis=1)
selected
<tf.RaggedTensor [[False, False, False, False, False, False, False, True, False, True, True, False, False, False, False, False, True, False, False, False, False, False], [False, False, False, True, False, False, False, True, False, False, False, False, False]]>

नकाबपोश मूल्य का चयन

मास्किंग के लिए मूल्य चुनने के लिए मूल बीईआरटी पेपर का वर्णन करने वाली कार्यप्रणाली इस प्रकार है:

के लिए mask_token_rate समय की, साथ आइटम की जगह [MASK] टोकन:

"my dog is hairy" -> "my dog is [MASK]"

के लिए random_token_rate समय की, कोई भी शब्द के साथ आइटम की जगह:

"my dog is hairy" -> "my dog is apple"

के लिए 1 - mask_token_rate - random_token_rate समय की, मद अपरिवर्तित रखना:

"my dog is hairy" -> "my dog is hairy."

text.MaskedValuesChooser इस तर्क समाहित और हमारे पूर्व प्रसंस्करण समारोह के लिए इस्तेमाल किया जा सकता है। यहाँ का एक उदाहरण है MaskValuesChooser रिटर्न दिए गए mask_token_rate 80% की और डिफ़ॉल्ट random_token_rate :

input_ids = tf.ragged.constant([[19, 7, 21, 20, 9, 8], [13, 4, 16, 5], [15, 10, 12, 11, 6]])
mask_values_chooser = text.MaskValuesChooser(_VOCAB_SIZE, _MASK_TOKEN, 0.8)
mask_values_chooser.get_mask_values(input_ids)
<tf.RaggedTensor [[1, 1, 1, 1, 1, 1], [1, 1, 1, 1], [16, 1, 12, 1, 1]]>

जब एक साथ आपूर्ति की RaggedTensor इनपुट, text.MaskValuesChooser एक रिटर्न RaggedTensor या तो के साथ एक ही आकार के _MASK_VALUE (0), एक यादृच्छिक आईडी, या एक ही अपरिवर्तित आईडी।

नकाबपोश भाषा मॉडल कार्य के लिए इनपुट उत्पन्न करना

अब जब हम एक है RandomItemSelector मदद करने के लिए हमें मास्किंग और के लिए आइटम का चयन text.MaskValuesChooser प्रदान करना है, हम उपयोग कर सकते हैं text.mask_language_model() हमारे बर्ट मॉडल के लिए इस कार्य के सभी आदानों इकट्ठा करने के लिए।

masked_token_ids, masked_pos, masked_lm_ids = text.mask_language_model(
  segments_combined,
  item_selector=random_selector, mask_values_chooser=mask_values_chooser)
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/util/dispatch.py:206: batch_gather (from tensorflow.python.ops.array_ops) is deprecated and will be removed after 2017-10-25.
Instructions for updating:
`tf.batch_gather` is deprecated, please use `tf.gather` with `batch_dims=-1` instead.

आइए गोता गहरा और के आउटपुट की जांच mask_language_model() के उत्पादन में masked_token_ids है:

masked_token_ids
<tf.RaggedTensor [[3, 22, 9, 25, 23, 1, 10, 28, 14, 1, 13, 7, 4, 16, 11, 19, 6, 28, 30, 21, 0, 4], [3, 18, 12, 15, 13, 8, 4, 21, 28, 1, 1, 29, 4]]>

याद रखें कि हमारा इनपुट एक शब्दावली का उपयोग करके एन्कोड किया गया है। अगर हम डिकोड masked_token_ids हमारे शब्दावली का उपयोग करते हुए, हम पाते हैं:

tf.gather(_VOCAB, masked_token_ids)
<tf.RaggedTensor [[b'[CLS]', b'Sp', b'##onge', b'box', b'Sq', b'[MASK]', b'##pants', b'is', b'an', b'[MASK]', b'##ven', b'##ger', b'[SEP]', b'Bar', b'##uare', b'Ob', b'##ama', b'is', b'the', b'President', b'[UNK]', b'[SEP]'], [b'[CLS]', b'Mar', b'##vel', b'A', b'##ven', b'##gers', b'[SEP]', b'President', b'is', b'[MASK]', b'[MASK]', b'office', b'[SEP]']]>

सूचना है कि कुछ wordpiece टोकन के साथ या तो प्रतिस्थापित किया गया है [MASK] , [RANDOM] या एक अलग आईडी मूल्य। masked_pos उत्पादन हमें टोकन कि प्रतिस्थापित किया गया है के सूचकांक (संबंधित बैच में) देता है।

masked_pos
<tf.RaggedTensor [[3, 5, 9, 14], [9, 10]]>

masked_lm_ids हमें टोकन के मूल मूल्य देता है।

masked_lm_ids
<tf.RaggedTensor [[24, 11, 15, 5], [30, 27]]>

मानव पठनीय मूल्य प्राप्त करने के लिए हम यहां आईडी को फिर से डीकोड कर सकते हैं।

tf.gather(_VOCAB, masked_lm_ids)
<tf.RaggedTensor [[b'bob', b'##uare', b'A', b'##ack'], [b'the', b'highest']]>

पैडिंग मॉडल इनपुट

अब है कि हम अपने मॉडल के लिए सभी आदानों है, हमारे पूर्व प्रसंस्करण में अंतिम चरण के लिए उन्हें 2-आयामी तय में पैकेज है Tensor रों गद्दी के साथ और यह भी एक मुखौटा उत्पन्न Tensor मूल्यों जो पैड मान हैं का संकेत है। हम उपयोग कर सकते हैं text.pad_model_inputs() इस कार्य में हमारी मदद करने।

# Prepare and pad combined segment inputs
input_word_ids, input_mask = text.pad_model_inputs(
  masked_token_ids, max_seq_length=_MAX_SEQ_LEN)
input_type_ids, _ = text.pad_model_inputs(
  masked_token_ids, max_seq_length=_MAX_SEQ_LEN)

# Prepare and pad masking task inputs
masked_lm_positions, masked_lm_weights = text.pad_model_inputs(
  masked_token_ids, max_seq_length=_MAX_PREDICTIONS_PER_BATCH)
masked_lm_ids, _ = text.pad_model_inputs(
  masked_lm_ids, max_seq_length=_MAX_PREDICTIONS_PER_BATCH)

model_inputs = {
    "input_word_ids": input_word_ids,
    "input_mask": input_mask,
    "input_type_ids": input_type_ids,
    "masked_lm_ids": masked_lm_ids,
    "masked_lm_positions": masked_lm_positions,
    "masked_lm_weights": masked_lm_weights,
}
model_inputs
{'input_word_ids': <tf.Tensor: shape=(2, 8), dtype=int64, numpy=
 array([[ 3, 22,  9, 25, 23,  1, 10, 28],
        [ 3, 18, 12, 15, 13,  8,  4, 21]])>,
 'input_mask': <tf.Tensor: shape=(2, 8), dtype=int64, numpy=
 array([[1, 1, 1, 1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1, 1, 1, 1]])>,
 'input_type_ids': <tf.Tensor: shape=(2, 8), dtype=int64, numpy=
 array([[ 3, 22,  9, 25, 23,  1, 10, 28],
        [ 3, 18, 12, 15, 13,  8,  4, 21]])>,
 'masked_lm_ids': <tf.Tensor: shape=(2, 5), dtype=int64, numpy=
 array([[24, 11, 15,  5,  0],
        [30, 27,  0,  0,  0]])>,
 'masked_lm_positions': <tf.Tensor: shape=(2, 5), dtype=int64, numpy=
 array([[ 3, 22,  9, 25, 23],
        [ 3, 18, 12, 15, 13]])>,
 'masked_lm_weights': <tf.Tensor: shape=(2, 5), dtype=int64, numpy=
 array([[1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1]])>}

समीक्षा

आइए समीक्षा करें कि हमारे पास अब तक क्या है और हमारे प्रीप्रोसेसिंग फ़ंक्शन को इकट्ठा करें। यहाँ हमारे पास क्या है:

def bert_pretrain_preprocess(vocab_table, features):
  # Input is a string Tensor of documents, shape [batch, 1].
  text_a = features["text_a"]
  text_b = features["text_b"]

  # Tokenize segments to shape [num_sentences, (num_words)] each.
  tokenizer = text.BertTokenizer(
      vocab_table,
      token_out_type=tf.int64)
  segments = [tokenizer.tokenize(text).merge_dims(
      1, -1) for text in (text_a, text_b)]

  # Truncate inputs to a maximum length.
  trimmer = text.RoundRobinTrimmer(max_seq_length=6)
  trimmed_segments = trimmer.trim(segments)

  # Combine segments, get segment ids and add special tokens.
  segments_combined, segment_ids = text.combine_segments(
      trimmed_segments,
      start_of_sequence_id=_START_TOKEN,
      end_of_segment_id=_END_TOKEN)

  # Apply dynamic masking task.
  masked_input_ids, masked_lm_positions, masked_lm_ids = (
      text.mask_language_model(
        segments_combined,
        random_selector,
        mask_values_chooser,
      )
  )

  # Prepare and pad combined segment inputs
  input_word_ids, input_mask = text.pad_model_inputs(
    masked_token_ids, max_seq_length=_MAX_SEQ_LEN)
  input_type_ids, _ = text.pad_model_inputs(
    masked_token_ids, max_seq_length=_MAX_SEQ_LEN)

  # Prepare and pad masking task inputs
  masked_lm_positions, masked_lm_weights = text.pad_model_inputs(
    masked_token_ids, max_seq_length=_MAX_PREDICTIONS_PER_BATCH)
  masked_lm_ids, _ = text.pad_model_inputs(
    masked_lm_ids, max_seq_length=_MAX_PREDICTIONS_PER_BATCH)

  model_inputs = {
      "input_word_ids": input_word_ids,
      "input_mask": input_mask,
      "input_type_ids": input_type_ids,
      "masked_lm_ids": masked_lm_ids,
      "masked_lm_positions": masked_lm_positions,
      "masked_lm_weights": masked_lm_weights,
  }
  return model_inputs

हम पहले से एक का निर्माण किया tf.data.Dataset और अब हम हमारे इकट्ठे पूर्व प्रसंस्करण समारोह का उपयोग कर सकते bert_pretrain_preprocess() में Dataset.map() । यह हमें अपने कच्चे स्ट्रिंग डेटा को पूर्णांक इनपुट में बदलने और सीधे हमारे मॉडल में फीड करने के लिए एक इनपुट पाइपलाइन बनाने की अनुमति देता है।

dataset = tf.data.Dataset.from_tensors(examples)
dataset = dataset.map(functools.partial(
    bert_pretrain_preprocess, lookup_table))

next(iter(dataset))
2021-08-17 11:09:58.366778: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:176] None of the MLIR Optimization Passes are enabled (registered 2)
2021-08-17 11:09:58.441242: I tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 2000165000 Hz
{'input_word_ids': <tf.Tensor: shape=(2, 8), dtype=int64, numpy=
 array([[ 3, 22,  9, 25, 23,  1, 10, 28],
        [ 3, 18, 12, 15, 13,  8,  4, 21]])>,
 'input_mask': <tf.Tensor: shape=(2, 8), dtype=int64, numpy=
 array([[1, 1, 1, 1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1, 1, 1, 1]])>,
 'input_type_ids': <tf.Tensor: shape=(2, 8), dtype=int64, numpy=
 array([[ 3, 22,  9, 25, 23,  1, 10, 28],
        [ 3, 18, 12, 15, 13,  8,  4, 21]])>,
 'masked_lm_ids': <tf.Tensor: shape=(2, 5), dtype=int64, numpy=
 array([[ 5, 19,  0,  0,  0],
        [12, 28,  0,  0,  0]])>,
 'masked_lm_positions': <tf.Tensor: shape=(2, 5), dtype=int64, numpy=
 array([[ 3, 22,  9, 25, 23],
        [ 3, 18, 12, 15, 13]])>,
 'masked_lm_weights': <tf.Tensor: shape=(2, 5), dtype=int64, numpy=
 array([[1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1]])>}
  • बर्ट के साथ बाँटिए पाठ - कैसे वर्गीकृत पाठ करने के लिए एक pretrained बर्ट मॉडल का उपयोग करने पर एक ट्यूटोरियल। यह अब एक अच्छा अनुवर्ती है कि आप BERT मॉडल द्वारा उपयोग किए गए इनपुट को प्रीप्रोसेस करने के तरीके से परिचित हैं।

  • TF पाठ के साथ Tokenizing - ट्यूटोरियल tokenizers के विभिन्न प्रकार है कि TF.Text में मौजूद का ब्यौरा।

  • साथ पाठ हैंडलिंग RaggedTensor - कैसे उपयोग बनाते हैं, और हेरफेर करने के लिए पर विस्तृत गाइड RaggedTensor रों।