การฝังประโยค BERT จากหม้อแปลง
ฉันกำลังพยายามหาเวกเตอร์ประโยคจากสถานะที่ซ่อนอยู่ในแบบจำลอง BERT ดูคำแนะนำ Hugface BertModel ที่นี่ซึ่งกล่าวว่า:
from transformers import BertTokenizer, BertModel
tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased')
model = BertModel.from_pretrained("bert-base-multilingual-cased")
text = "Replace me by any text you'd like."
encoded_input = tokenizer(text, return_tensors='pt')
output = model(**encoded_input)
ก่อนอื่นโปรดทราบเนื่องจากอยู่บนเว็บไซต์สิ่งนี้ไม่ / ไม่ / ทำงาน คุณได้รับ:
>>> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'BertTokenizer' object is not callable
แต่ดูเหมือนว่าการเปลี่ยนแปลงเล็กน้อยจะแก้ไขได้โดยที่คุณไม่ได้เรียกใช้โทเค็นไนเซอร์โดยตรง แต่ขอให้เข้ารหัสอินพุต:
encoded_input = tokenizer.encode(text, return_tensors="pt")
output = model(encoded_input)
ตกลงนอกจากนั้นเทนเซอร์ที่ฉันได้รับมีรูปร่างแตกต่างจากที่ฉันคาดไว้:
>>> output[0].shape
torch.Size([1,11,768])
นี่หลายชั้นมาก ชั้นใดที่ถูกต้องในการใช้ฝังประโยค [0]
เหรอ? [-1]
เหรอ? เฉลี่ยหลาย ๆ ? ฉันมีเป้าหมายที่จะสร้างความคล้ายคลึงกันของโคไซน์กับสิ่งเหล่านี้ได้ดังนั้นฉันจึงต้องการเวกเตอร์ 1xN ที่เหมาะสมมากกว่าเทนเซอร์ NxK
ฉันเห็นว่าโครงการbert-as-a-serviceยอดนิยมดูเหมือนจะใช้[0]
ถูกต้องหรือไม่ มีเอกสารประกอบว่าแต่ละเลเยอร์คืออะไร?
คำตอบ
ฉันไม่คิดว่าจะมีเอกสารที่เชื่อถือได้เพียงฉบับเดียวที่บอกว่าจะใช้อะไรและเมื่อไร คุณต้องทดลองและวัดผลว่าอะไรดีที่สุดสำหรับงานของคุณ ข้อสังเกตล่าสุดเกี่ยวกับ BERT สรุปไว้อย่างชัดเจนในบทความนี้:https://arxiv.org/pdf/2002.12327.pdf.
ฉันคิดว่าหลักการง่ายๆคือ:
ใช้เลเยอร์สุดท้ายหากคุณกำลังจะปรับแต่งโมเดลสำหรับงานเฉพาะของคุณ และปรับแต่งทุกครั้งที่ทำได้ตัวอย่างการฝึกอบรมหลายร้อยหรือหลายสิบตัวอย่างก็เพียงพอแล้ว
ใช้เลเยอร์กลางบางส่วน (7-th หรือ 8-th) หากคุณไม่สามารถปรับแต่งโมเดลได้ สัญชาตญาณที่อยู่เบื้องหลังนั้นคือชั้นแรกจะพัฒนาการแสดงข้อมูลที่เป็นนามธรรมและเป็นนามธรรมมากขึ้น ในบางประเด็นการเป็นตัวแทนเริ่มมีเป้าหมายมากขึ้นสำหรับงานก่อนการฝึกอบรม
Bert-as-services ใช้เลเยอร์สุดท้ายตามค่าเริ่มต้น (แต่สามารถกำหนดค่าได้) [:, -1]
นี่ก็จะเป็น อย่างไรก็ตามจะส่งคืนรายการเวกเตอร์สำหรับโทเค็นอินพุตทั้งหมดเสมอ เวกเตอร์ที่ตรงกับ[CLS]
โทเค็นพิเศษ (ที่เรียกว่า) แรกจะถือเป็นการฝังประโยค นี่คือที่[0]
มาจากสไนเปอร์ที่คุณอ้างถึง
แม้ว่าคำตอบที่มีอยู่ของJindrichจะถูกต้อง แต่ก็ไม่ได้ตอบคำถามทั้งหมด สหกรณ์ถามว่าชั้นที่เขาควรจะใช้ในการคำนวณความคล้ายคลึงกันระหว่างโคไซน์ embeddings ประโยคและคำตอบสั้น ๆ สำหรับคำถามนี้คือใคร ตัวชี้วัดเช่นความคล้ายคลึงกันของโคไซน์ต้องการให้ขนาดของเวกเตอร์มีส่วนเท่ากันและมีความหมาย แต่นี่ไม่ใช่กรณีสำหรับ BERT Jacob Devlin (หนึ่งในผู้เขียนบทความ BERT) เขียนว่า :
ฉันไม่แน่ใจว่าเวกเตอร์เหล่านี้คืออะไรเนื่องจาก BERT ไม่ได้สร้างเวกเตอร์ประโยคที่มีความหมาย ดูเหมือนว่านี่กำลังทำการรวมค่าเฉลี่ยเหนือโทเค็นคำเพื่อให้ได้เวกเตอร์ประโยค แต่เราไม่เคยแนะนำว่าสิ่งนี้จะสร้างการแสดงประโยคที่มีความหมาย และแม้ว่าจะเป็นตัวแทนที่เหมาะสมเมื่อป้อนเข้าสู่ DNN ที่ได้รับการฝึกฝนสำหรับงานปลายน้ำก็ไม่ได้หมายความว่าจะมีความหมายในแง่ของระยะโคไซน์ (เนื่องจากระยะโคไซน์เป็นปริภูมิเชิงเส้นที่ทุกมิติถ่วงน้ำหนักเท่ากัน)
อย่างไรก็ตามไม่ได้หมายความว่าคุณไม่สามารถใช้ BERT สำหรับงานดังกล่าวได้ นั่นหมายความว่าคุณไม่สามารถใช้ตุ้มน้ำหนักที่ผ่านการฝึกอบรมมาแล้วได้ทันที คุณสามารถฝึกลักษณนามที่ด้านบนของ BERT ซึ่งเรียนรู้ว่าประโยคใดคล้ายคลึงกัน (โดยใช้[CLS]
โทเค็น) หรือคุณสามารถใช้ตัวแปลงประโยคซึ่งสามารถใช้ในสถานการณ์ที่ไม่ได้รับการดูแลเนื่องจากได้รับการฝึกฝนให้สร้างการแทนประโยคที่มีความหมาย