การฝังประโยค BERT จากหม้อแปลง

Aug 17 2020

ฉันกำลังพยายามหาเวกเตอร์ประโยคจากสถานะที่ซ่อนอยู่ในแบบจำลอง 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]

ถูกต้องหรือไม่ มีเอกสารประกอบว่าแต่ละเลเยอร์คืออะไร?

คำตอบ

5 Jindřich Aug 18 2020 at 08:37

ฉันไม่คิดว่าจะมีเอกสารที่เชื่อถือได้เพียงฉบับเดียวที่บอกว่าจะใช้อะไรและเมื่อไร คุณต้องทดลองและวัดผลว่าอะไรดีที่สุดสำหรับงานของคุณ ข้อสังเกตล่าสุดเกี่ยวกับ BERT สรุปไว้อย่างชัดเจนในบทความนี้:https://arxiv.org/pdf/2002.12327.pdf.

ฉันคิดว่าหลักการง่ายๆคือ:

  • ใช้เลเยอร์สุดท้ายหากคุณกำลังจะปรับแต่งโมเดลสำหรับงานเฉพาะของคุณ และปรับแต่งทุกครั้งที่ทำได้ตัวอย่างการฝึกอบรมหลายร้อยหรือหลายสิบตัวอย่างก็เพียงพอแล้ว

  • ใช้เลเยอร์กลางบางส่วน (7-th หรือ 8-th) หากคุณไม่สามารถปรับแต่งโมเดลได้ สัญชาตญาณที่อยู่เบื้องหลังนั้นคือชั้นแรกจะพัฒนาการแสดงข้อมูลที่เป็นนามธรรมและเป็นนามธรรมมากขึ้น ในบางประเด็นการเป็นตัวแทนเริ่มมีเป้าหมายมากขึ้นสำหรับงานก่อนการฝึกอบรม

Bert-as-services ใช้เลเยอร์สุดท้ายตามค่าเริ่มต้น (แต่สามารถกำหนดค่าได้) [:, -1]นี่ก็จะเป็น อย่างไรก็ตามจะส่งคืนรายการเวกเตอร์สำหรับโทเค็นอินพุตทั้งหมดเสมอ เวกเตอร์ที่ตรงกับ[CLS]โทเค็นพิเศษ (ที่เรียกว่า) แรกจะถือเป็นการฝังประโยค นี่คือที่[0]มาจากสไนเปอร์ที่คุณอ้างถึง

2 cronoik Oct 07 2020 at 04:50

แม้ว่าคำตอบที่มีอยู่ของJindrichจะถูกต้อง แต่ก็ไม่ได้ตอบคำถามทั้งหมด สหกรณ์ถามว่าชั้นที่เขาควรจะใช้ในการคำนวณความคล้ายคลึงกันระหว่างโคไซน์ embeddings ประโยคและคำตอบสั้น ๆ สำหรับคำถามนี้คือใคร ตัวชี้วัดเช่นความคล้ายคลึงกันของโคไซน์ต้องการให้ขนาดของเวกเตอร์มีส่วนเท่ากันและมีความหมาย แต่นี่ไม่ใช่กรณีสำหรับ BERT Jacob Devlin (หนึ่งในผู้เขียนบทความ BERT) เขียนว่า :

ฉันไม่แน่ใจว่าเวกเตอร์เหล่านี้คืออะไรเนื่องจาก BERT ไม่ได้สร้างเวกเตอร์ประโยคที่มีความหมาย ดูเหมือนว่านี่กำลังทำการรวมค่าเฉลี่ยเหนือโทเค็นคำเพื่อให้ได้เวกเตอร์ประโยค แต่เราไม่เคยแนะนำว่าสิ่งนี้จะสร้างการแสดงประโยคที่มีความหมาย และแม้ว่าจะเป็นตัวแทนที่เหมาะสมเมื่อป้อนเข้าสู่ DNN ที่ได้รับการฝึกฝนสำหรับงานปลายน้ำก็ไม่ได้หมายความว่าจะมีความหมายในแง่ของระยะโคไซน์ (เนื่องจากระยะโคไซน์เป็นปริภูมิเชิงเส้นที่ทุกมิติถ่วงน้ำหนักเท่ากัน)

อย่างไรก็ตามไม่ได้หมายความว่าคุณไม่สามารถใช้ BERT สำหรับงานดังกล่าวได้ นั่นหมายความว่าคุณไม่สามารถใช้ตุ้มน้ำหนักที่ผ่านการฝึกอบรมมาแล้วได้ทันที คุณสามารถฝึกลักษณนามที่ด้านบนของ BERT ซึ่งเรียนรู้ว่าประโยคใดคล้ายคลึงกัน (โดยใช้[CLS]โทเค็น) หรือคุณสามารถใช้ตัวแปลงประโยคซึ่งสามารถใช้ในสถานการณ์ที่ไม่ได้รับการดูแลเนื่องจากได้รับการฝึกฝนให้สร้างการแทนประโยคที่มีความหมาย