Buckets:
| # เบื้องหลังของ pipeline | |
| {#if fw === 'pt'} | |
| <CourseFloatingBanner chapter={2} | |
| classNames="absolute z-10 right-0 top-0" | |
| notebooks={[ | |
| {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/th/chapter2/section2_pt.ipynb"}, | |
| {label: "Aws Studio", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/th/chapter2/section2_pt.ipynb"}, | |
| ]} /> | |
| {:else} | |
| <CourseFloatingBanner chapter={2} | |
| classNames="absolute z-10 right-0 top-0" | |
| notebooks={[ | |
| {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/th/chapter2/section2_tf.ipynb"}, | |
| {label: "Aws Studio", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/th/chapter2/section2_tf.ipynb"}, | |
| ]} /> | |
| {/if} | |
| > [!TIP] | |
| > Section นี้จะเป็น Section แรกที่เนื้อหาจะค่อนข้างแตกต่างกันขึ้นอยู่กับว่าคุณใช้ PyTorch หรือ TensorFlow คุณสามารถเลือก plateform ที่คุณต้องการได้จากปุ่มที่อยู่ด้านบนของชื่อหัวข้อ! | |
| {#if fw === 'pt'} | |
| <Youtube id="1pedAIvTWXk"/> | |
| {:else} | |
| <Youtube id="wVN12smEvqg"/> | |
| {/if} | |
| เรามาเริ่มกันด้วยตัวอย่างนี้ โดยเรามาดูกันว่าเกิดอะไรขึ้นในเบื้องหลังเมื่อเราทำการสั่งการ(executed) โค้ดด้านล่างนี้จาก [Chapter 1](/course/chapter1): | |
| ```python | |
| from transformers import pipeline | |
| classifier = pipeline("sentiment-analysis") | |
| classifier( | |
| [ | |
| "I've been waiting for a HuggingFace course my whole life.", | |
| "I hate this so much!", | |
| ] | |
| ) | |
| ``` | |
| และ ผลลัพธ์ที่ได้: | |
| ```python out | |
| [{'label': 'POSITIVE', 'score': 0.9598047137260437}, | |
| {'label': 'NEGATIVE', 'score': 0.9994558095932007}] | |
| ``` | |
| อย่างที่เราเห็นใน [Chapter 1](/course/chapter1), pipeline นี้เป็นการรวมเอา 3 ขั้นตอน : แ(preprocessing), ส่งข้อมูลเข้าไปยังโมเดล, และการประมวลผลข้อมูลที่ออกมาจากโมเดล (postprocessing) | |
| <div class="flex justify-center"> | |
| <img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter2/full_nlp_pipeline.svg" alt="The full NLP pipeline: tokenization of text, conversion to IDs, and inference through the Transformer model and the model head."/> | |
| <img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter2/full_nlp_pipeline-dark.svg" alt="The full NLP pipeline: tokenization of text, conversion to IDs, and inference through the Transformer model and the model head."/> | |
| </div> | |
| เรามาดูแต่ละขั้นตอนเหล่านี้กันอย่างละเอียดเลยดีกว่า | |
| ## การประมวลผลข้อมูลขั้นต้น(Preprocessing) ด้วย tokenizer | |
| เหมือนกับโครงข่ายประสาท(neural networks) อื่นๆ, โมเดล Transformer ไม่สามารถที่จะประมวลผลข้อมูลที่เป็นข้อความ(text) ได้ตรงๆ ดังนั้นขั้นแรกของ pipeline ก็คือการแปลงข้อความให้เป็นตัวเลข(numbers) ที่โมเดลนั้นสามารถประมวลผลได้ ในกระบวนการนี้เราจะใช้ *tokenizer* ซึ่งจะรับผิดชอบในการทำ : | |
| - แบ่งข้อมูลออกเป็น คำ(words), หน่วยย่อยของคำ (subwords), หรือ สัญลักษณ์ (เช่น เครื่องหมายวรรคตอน (punctuation)) เหล่านี้เราเรียกว่า *token* | |
| - ทำการเชื่อมโยง (Mapping) แต่ละ token ไปเป็นตัวเลข (integer) | |
| - เพิ่มเติมข้อมูลที่อาจจะเป็นประโยชน์กับโมเดล | |
| กระบวนการประมวลผลข้อมูลขั้นต้น(preprocessing) ทั้งหมดนี้จำเป็นที่จะต้องเป็นไปในแนวทางที่เหมือนกับตอนที่โมเดลได้ผ่านการเทรนมาก่อนหน้านี้(pretrained), ดังนั้นสิ่งแรกที่เราจำเป็นต้องทำคือดาวน์โหลดข้อมูลจาก [Model Hub](https://huggingface.co/models) ในการดาวน์โหลดนี้ เราสามารถทำได้โดยใช้คลาส `AutoTokenizer` และเรียกเมธอด `from_pretrained()` โดยหากระบุชื่อ checkpoint ของโมเดล เมธอด `from_pretrained()` จะทำการดึงข้อมูลทั้งหมดที่เกี่ยวกับ tokenizer ของโมเดลมาเก็บไว้(จะดาวน์โหลดเพียงครั้งเดียวตอนที่เรารันโค้ดด้านล่างนี้ครั้งแรกเท่านั้น) | |
| เนื่องจาก checkpoint เริ่มต้น(default) ของ `sentiment-analysis` pipeline คือ `distilbert-base-uncased-finetuned-sst-2-english` (สามารถดู model card [ที่นี่](https://huggingface.co/distilbert-base-uncased-finetuned-sst-2-english)), ดังนั้นเราจะรันโค้ดนี้: | |
| ```python | |
| from transformers import AutoTokenizer | |
| checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" | |
| tokenizer = AutoTokenizer.from_pretrained(checkpoint) | |
| ``` | |
| เมื่อเรามี tokenizer แล้ว เราสามารถใส่ประโยคข้อความของเราเข้าไปและเราจะได้สารานุกรม(dictionary) ที่พร้อมนำไปใส่ในโมเดลออกมา! สิ่งเดียวที่เหลือที่ต้องทำ คือ การแปลงข้อมูลอัตลักษณ์(IDs) ของข้อมูลที่ใส่เข้าไป(input) ไปเป็น tensors | |
| คุณสามารถใช้ 🤗 Transformers โดยที่ไม่จำเป็นต้องกังวลเลยว่า ML framework ตัวไหนที่ใช้เป็น backend; มันอาจจะเป็น PyTorch หรือ TensorFlow, หรือ Flax สำหรับบางโมเดล แต่อย่างไรก็ตามโมเดล Transformer จะรับเพียง *tensor* เป็นข้อมูลที่ใส่เข้าไป(input) เท่านั้น ถ้านี่เป็นครั้งแรกที่คุณได้ยินเกี่ยวกับคำว่า tensor คุณสามารถเปรียบเทียบมันเป็นเหมือน NumPy arrays แทนก็ได้ โดยที่ NumPy array สามารถเป็นได้ทั้ง scalar (0D), vector (1D), matrix (2D), หรือมีหลายๆมิติ. เหล่านี้ก็คือ tensor ดีๆนี่เอง tensor ของ ML frameworks อื่นๆ ก็มีลักษณะคล้ายๆกัน และสามารถสร้างขึ้นได้ง่ายเหมือน NumPy arrays | |
| การกำหนดประเภทของ tensor ที่เราต้องการได้กลับมา (PyTorch, TensorFlow, หรือ NumPy) เราสามารถใช้ตัวแปร(argument) `return_tensors`: | |
| {#if fw === 'pt'} | |
| ```python | |
| raw_inputs = [ | |
| "I've been waiting for a HuggingFace course my whole life.", | |
| "I hate this so much!", | |
| ] | |
| inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt") | |
| print(inputs) | |
| ``` | |
| {:else} | |
| ```python | |
| raw_inputs = [ | |
| "I've been waiting for a HuggingFace course my whole life.", | |
| "I hate this so much!", | |
| ] | |
| inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="tf") | |
| print(inputs) | |
| ``` | |
| {/if} | |
| ไม่ต้องกังวลเกี่ยวการเพิ่ม(padding) และการตัดออก(truncation) ในตอนนี้ เราจะอธิบายทีหลัง สิ่งหลักๆ ที่ควรจำคือ คุณสามารถที่จะส่งผ่านประโยคหนึ่งประโยค หรือ รายการ(list)ของประโยค พร้อมทั้งระบุประเภทของ tensor ที่คุณต้องการได้กลับมา(ถ้าไม่ระบุประเภท คุณจะได้ผลกลับมาเป็น list of lists) | |
| {#if fw === 'pt'} | |
| ผลลัพธ์ที่เป็น tensor ของ PyTorch ก็จะหน้าตาประมาณนี้ | |
| ```python out | |
| { | |
| 'input_ids': tensor([ | |
| [ 101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012, 102], | |
| [ 101, 1045, 5223, 2023, 2061, 2172, 999, 102, 0, 0, 0, 0, 0, 0, 0, 0] | |
| ]), | |
| 'attention_mask': tensor([ | |
| [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], | |
| [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] | |
| ]) | |
| } | |
| ``` | |
| {:else} | |
| ผลลัพธ์ที่เป็น tensor ของ PyTorch ก็จะหน้าตาประมาณนี้ | |
| ```python out | |
| { | |
| 'input_ids': <tf.Tensor: shape=(2, 16), dtype=int32, numpy= | |
| array([ | |
| [ 101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012, 102], | |
| [ 101, 1045, 5223, 2023, 2061, 2172, 999, 102, 0, 0, 0, 0, 0, 0, 0, 0] | |
| ], dtype=int32)>, | |
| 'attention_mask': <tf.Tensor: shape=(2, 16), dtype=int32, numpy= | |
| array([ | |
| [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], | |
| [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0] | |
| ], dtype=int32)> | |
| } | |
| ``` | |
| {/if} | |
| ผลลัพธ์จะเป็นสารานุกรม(dictionary) ที่มี 2 คีย์(keys), `input_ids` และ `attention_mask` โดยที่ `input_ids` จะมีข้อมูลเป็นตัวเลข(integers)จำนวนสองแถว (หนึ่งแถวต่อหนึ่งประโยค) ซึ่งเป็นอัตลักษณ์ที่เฉพาะเจาะจงของ token ในแต่ละประโยค ส่วน `attention_mask` เราจะอธิบายในบทนี้อีกครั้งหลังจากนี้ | |
| ## มาอธิบายเกี่ยวกับโมเดลกัน | |
| {#if fw === 'pt'} | |
| เราสามารถดาวน์โหลดโมเดลที่ผ่านการเทรนมาแล้ว(pretrained) ของเราได้เหมือนกับที่เราทำกับ tokenizer ของเรา 🤗 Transformers มีคลาส `AutoModel` ซึ่งก็มีเมธอด `from_pretrained()` เช่นกัน: | |
| ```python | |
| from transformers import AutoModel | |
| checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" | |
| model = AutoModel.from_pretrained(checkpoint) | |
| ``` | |
| {:else} | |
| เราสามารถดาวน์โหลดโมเดลที่ผ่านการเทรนมาแล้ว(pretrained) ของเราได้เหมือนกับที่เราทำกับ tokenizer ของเรา 🤗 Transformers มีคลาส `TFAutoModel` ซึ่งก็มีเมธอด `from_pretrained()` เช่นกัน: | |
| ```python | |
| from transformers import TFAutoModel | |
| checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" | |
| model = TFAutoModel.from_pretrained(checkpoint) | |
| ``` | |
| {/if} | |
| ในตัวอย่างโค้ดนี้ เราดาวน์โหลด checkpoint เดียวกันกับที่เราใช้ใน pipeline ของเราก่อนหน้านี้ (มันน่ามีการเก็บ(cached)ไว้แล้ว) และสร้างโมเดลขึ้นมาพร้อมกัน | |
| ในสถาปัตยกรรมนี้จะมีเฉพาะโมดูล Transformer พื้นฐาน: ให้ข้อมูลเข้าไป และมันให้สิ่งที่เราเรียกว่า *hidden states* ออกมา หรือที่เรารู้จักกันในนาม *features* สำหรับข้อมูลอินพุตของแต่ละโมเดล เราจะทำการหาเวกเตอร์หลายมิติ(high-dimensional vector) ที่บ่งบอก **ความเข้าใจสภาวะแวดล้อมของข้อมูลนั้นโดนโมเดล Transformer** | |
| ถ้านี้ฟังดูไม่สมเหตุสมผล ไม่ต้องกังวล เดี๋ยวเราจะอธิบายทัั้งหมดอีกครั้ง | |
| ในขณะที่ hidden states เหล่านี้เป็นประโยชน์ในตัวมันอยู่แล้ว มันเลยถูกนำไปใช้กับส่วนอื่นของโมเดลด้วย ที่เรารู้จักกันในนาม *head* ใน [Chapter 1](/course/chapter1), งานที่แตกต่างกันอาจจะสามารถใช้สถาปัตยกรรมเหมือนกันได้ แต่งานแต่ละอย่างจะมีส่วนหัว(head)ที่แตกต่างกันไป | |
| ### เวคเตอร์หลายมิติ (A high-dimensional vector) ? | |
| เวอเตอร์ที่ได้จากโมดูลของ Transformer นั้นปกติจะมีขนาดใหญ่ โดยทั่วไปแล้วมันจะมี 3 มิติ: | |
| - **ขนาดของชุด(ฺBatch size)**: จำนวนของประโยคที่ผ่านการประมวลผล (2 ประโยคในตัวอย่างของเรา) | |
| - **ความยาวของประโยค(Sequence length)**: ความยาวของตัวเลขที่เป็นตัวแทนของประโยค (16 ตัวเลขในตัวอย่างของเรา) | |
| - **ขนาดของ Hidden states (Hidden size)**: มิติของเวคเตอร์ของแต่ละข้อมูลที่ให้เข้าไปยังโมเดล | |
| มันจะถูกบอกว่ามันเป็นเวคเตอร์ "หลายมิติ(high dimensional)" ก็เพราะค่าสุดท้าย ขนาดของ hidden states นั้นสามารถมีขนาดที่ใหญ่มาก(786 เป็นค่าที่ใช้กันทั่วไปสำหรับโมเดลขนาดเล็ก, ส่วนในโมเดลขนาดใหญ่นั้นสามารถขึ้นไปได้ถึง 3072 หรือมากกว่านั้น) | |
| เราจะเห็นได้ว่าถ้าเราใส่ข้อมูลที่เราประมวลผลมาแล้วเข้าไปยังโมเดลของเรา: | |
| {#if fw === 'pt'} | |
| ```python | |
| outputs = model(**inputs) | |
| print(outputs.last_hidden_state.shape) | |
| ``` | |
| ```python out | |
| torch.Size([2, 16, 768]) | |
| ``` | |
| {:else} | |
| ```py | |
| outputs = model(inputs) | |
| print(outputs.last_hidden_state.shape) | |
| ``` | |
| ```python out | |
| (2, 16, 768) | |
| ``` | |
| {/if} | |
| จะสังเกตว่าข้อมูลที่ออกจากโมเดล 🤗 Transformers นั้นจะมีลักษณะเหมือนกับ `namedtuple`s หรือ dictionaries คุณสามารถเข้าถึงองค์ประกอบต่าง(elements) ได้ด้วย attributes (เหมือนที่เราทำ) หรือด้วย key (`outputs["last_hidden_state"]`) หรือแม้กระทั่งด้วย index ถ้าคุณรู้ว่าสิ่งที่คุณมองหานั้นอยู่ตรงไหน (`outputs[0]`) | |
| ### Model heads: ทำความเข้าใจจากตัวเลข | |
| โมเดล heads รับเวคเตอร์หลายมิติ(high-dimensional) ของ hidden states เข้าไปและจะทำการโปรเจคเวคเตอร์ดังกล่าวไปยังมิติอื่น ซึ่งโดยปกติโมเดล heads จะประกอบด้วยเลเยอร์เชิงเส้น(linear layers) อย่างน้อยหนึ่งเลเยอร์: | |
| <div class="flex justify-center"> | |
| <img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter2/transformer_and_head.svg" alt="A Transformer network alongside its head."/> | |
| <img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter2/transformer_and_head-dark.svg" alt="A Transformer network alongside its head."/> | |
| </div> | |
| เอาท์พุตของโมเดล Transformer จะส่งตรงไปที่หัวโมเดล(model head)เพื่อทำการประมวลผล | |
| ในไดอะแกรมนี้ โมเดลจะถูกแทนที่ด้วยเลเยอร์ฝังตัว(embeddings layer) และเลเยอร์ย่อย(subsequent layers) ของตัวมันเอง โดยเลเยอร์ฝังตัว(embeddings layer) จะทำการแปลงตัวบ่งชี้ตัวตนของอินพุต(Input ID) ที่อยู่ในอินพุตที่เป็น tokenized ไปเป็นเวคเตอร์ที่่เป็นตัวแทนของ token ที่เกี่ยวข้อง ส่วนเลเยอร์ย่อยอื่นๆจะจัดการเวคเตอร์อื่นโดยใช้กระบวนการ attention เพื่อให้ได้มาซึ่งตัวแทน(representation) สุดท้ายของประโยค | |
| มีหลายสถาปัตยกรรมใน 🤗 Transformers โดยที่หนึ่งสถาปัตยกรรมถูกออกแบบมาให้ใช้กับงานเฉพาะหนึ่งงาน นี่เป็นเพียงส่วนหนึ่งจากหลายๆโมเดล : | |
| - `*Model` (retrieve the hidden states) | |
| - `*ForCausalLM` | |
| - `*ForMaskedLM` | |
| - `*ForMultipleChoice` | |
| - `*ForQuestionAnswering` | |
| - `*ForSequenceClassification` | |
| - `*ForTokenClassification` | |
| - and others 🤗 | |
| {#if fw === 'pt'} | |
| สำหรับในตัวอย่างของเรานั้น เราต้องการโมเดลที่มี head สำหรับการจำแนกประโยค(sequence classification) (โดยสามารถที่จะจำแนกประโยคว่าเป็นประโยคเชิงบวก หรือ ลบ) ดังนั้น เราจะไม่ใช้คลาส `AutoModel` แต่จะใช้ `AutoModelForSequenceClassification`: | |
| ```python | |
| from transformers import AutoModelForSequenceClassification | |
| checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" | |
| model = AutoModelForSequenceClassification.from_pretrained(checkpoint) | |
| outputs = model(**inputs) | |
| ``` | |
| {:else} | |
| สำหรับในตัวอย่างของเรานั้น เราต้องการโมเดลที่มี head สำหรับการจำแนกประโยค(sequence classification) (โดยสามารถที่จะจำแนกประโยคว่าเป็นประโยคเชิงบวก หรือ ลบ) ดังนั้น เราจะไม่ใช้คลาส `TFAutoModel` แต่จะใช้ `TFAutoModelForSequenceClassification`: | |
| ```python | |
| from transformers import TFAutoModelForSequenceClassification | |
| checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" | |
| model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint) | |
| outputs = model(inputs) | |
| ``` | |
| {/if} | |
| ถ้าเราดูที่ขนาด(shape) ของอินพุต มิติ(dimensionality)จะน้อยกว่ามาก : model head ที่รับเอาเวคเตอร์ขนาดหลายมิติเป็นอินพุตเหมือนที่เราเห็นก่อนหน้านี้ และให้เอาท์พุตเป็นเวคเตอร์ที่มีสองค่า (หนึ่งค่าต่อหนึ่งสัญลักษณ์(label)) : | |
| ```python | |
| print(outputs.logits.shape) | |
| ``` | |
| {#if fw === 'pt'} | |
| ```python out | |
| torch.Size([2, 2]) | |
| ``` | |
| {:else} | |
| ```python out | |
| (2, 2) | |
| ``` | |
| {/if} | |
| เนื่องจากเรามีแค่สองประโยคและสองสัญลักษณ์(labels) ผลลัพธ์ที่ได้จากโมเดลของเราจึงมีขนาด 2x2 | |
| ## การประมวลหลังจากได้ผลลัพธ์มาแล้ว (Postprocessing) | |
| ค่าที่เราได้มาจากโมเดลนั้นไม่จำเป็นต้องดูเป็นเหตุเป็นผลในตัวมันเอง เดี๋ยวเราลองมาดูกัน: | |
| ```python | |
| print(outputs.logits) | |
| ``` | |
| {#if fw === 'pt'} | |
| ```python out | |
| tensor([[-1.5607, 1.6123], | |
| [ 4.1692, -3.3464]], grad_fn=<AddmmBackward>) | |
| ``` | |
| {:else} | |
| ```python out | |
| <tf.Tensor: shape=(2, 2), dtype=float32, numpy= | |
| array([[-1.5606991, 1.6122842], | |
| [ 4.169231 , -3.3464472]], dtype=float32)> | |
| ``` | |
| {/if} | |
| โมเดลของเราทำนาย `[-1.5607, 1.6123]` สำหรับประโยคแรก และ `[ 4.1692, -3.3464]` สำหรับประโยคที่สอง ค่าเหล่านี้ไม่ใช่ค่าความน่าจะเป็น(probabilities) แต่เป็นค่า *logits* เป็นคะแนนดิบที่ยังไม่ผ่านการ normalized ที่ส่งออกมาจากเลเยอร์สุดท้ายของโมเดล การแปลงค่าคะแนนไปเป็นค่าความน่าจะเป็น(probabilities) คะแนนเหล่านี้จำเป็นที่จะต้องผ่านเลเยอร์ที่ชื่อว่า [SoftMax](https://en.wikipedia.org/wiki/Softmax_function) (โมเดลของ 🤗 Transformers ทั้งหมด จะส่งข้อมูลออกมาเป็น logits โดยที่ loss function ของการเทรนโมเดลจะทำการรวม activation function ของเลเยอร์สุดท้าย เช่น SoftMax เข้ากับ loss function หลัก เช่น cross entropy): | |
| {#if fw === 'pt'} | |
| ```py | |
| import torch | |
| predictions = torch.nn.functional.softmax(outputs.logits, dim=-1) | |
| print(predictions) | |
| ``` | |
| {:else} | |
| ```py | |
| import tensorflow as tf | |
| predictions = tf.math.softmax(outputs.logits, axis=-1) | |
| print(predictions) | |
| ``` | |
| {/if} | |
| {#if fw === 'pt'} | |
| ```python out | |
| tensor([[4.0195e-02, 9.5980e-01], | |
| [9.9946e-01, 5.4418e-04]], grad_fn=<SoftmaxBackward>) | |
| ``` | |
| {:else} | |
| ```python out | |
| tf.Tensor( | |
| [[4.01951671e-02 9.59804833e-01] | |
| [9.9945587e-01 5.4418424e-04]], shape=(2, 2), dtype=float32) | |
| ``` | |
| {/if} | |
| ตอนนี้เราจะเห็นว่าโมเดลทำนาย `[0.0402, 0.9598]` สำหรับประโยคแรก และ `[0.9995, 0.0005]` สำหรับประโยคที่สอง ซึ่งคะแนนเหล่านี้คือคะแนนความน่าจะเป็น(probabilities score) ที่สามารถนำไปจำแนกได้ | |
| เพื่อที่จะให้ได้สัญลักษณ์(label) ของแต่ละตำแหน่ง เราสามารถดูได้จากคุณสมบัติ `id2label` ของโมเดล model config (เดี๋ยวเราจะอธิบายเพิ่มเติมใน section ถัดไป): | |
| ```python | |
| model.config.id2label | |
| ``` | |
| ```python out | |
| {0: 'NEGATIVE', 1: 'POSITIVE'} | |
| ``` | |
| เราสามารถที่จะสรุปได้ว่าโมเดลทำการทำนายดังต่อไปนี้ | |
| - ประโยคแรก: NEGATIVE: 0.0402, POSITIVE: 0.9598 | |
| - ประโยคที่สอง: NEGATIVE: 0.9995, POSITIVE: 0.0005 | |
| ถึงตรงนี้ประสบความสำเร็จในการลองทำ สาม ขั้นตอนของ pipeline: การประมวลผลเบื้องต้น(preprocessing)โดยใช้ tokenizers, ส่งข้อมูลเข้าไปยังโมเดล,และการประมวลผลข้อมูลที่ได้จากโมเดล! ต่อจากนี้เราจะไปลงลึกในรายละเอียดของแต่ละขั้นตอน | |
| > [!TIP] | |
| > ✏️ **ลองเลย!** เลือกสอง(หรือมากกว่านั้น) ข้อความของคุณเองและลองใส่มันเข้าไปใน `sentiment-analysis` pipeline. แล้วทำขั้นตอนต่างๆ ที่คุณเรียนผ่านมาใน section นี้และตรวจสอบดูว่าคุณได้ผลเหมือนเดิมหรือไม่! | |
| <EditOnGithub source="https://github.com/huggingface/course/blob/main/chapters/th/chapter2/2.mdx" /> |
Xet Storage Details
- Size:
- 28.1 kB
- Xet hash:
- c64ced47a422ae36f39d42f09cc3d6a1735ff1de7657db11a0c9b2904ae707af
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.