从我阅读的所有文档中,人们以这种方式和那种方式推动 BERT 如何使用或生成嵌入。我知道有一个键、一个查询和一个值,这些都是生成的。
我不知道原始嵌入——你放入 BERT 的原始东西——是否可以或应该是一个向量。人们对 BERT 或 ALBERT 如何不能用于逐字比较充满诗意,但没有人明确说明 bert 正在消耗什么。是向量吗?如果是这样,它只是一个单一的向量吗?为什么它不是 GLoVE 向量?(请暂时忽略位置编码讨论)
从我阅读的所有文档中,人们以这种方式和那种方式推动 BERT 如何使用或生成嵌入。我知道有一个键、一个查询和一个值,这些都是生成的。
我不知道原始嵌入——你放入 BERT 的原始东西——是否可以或应该是一个向量。人们对 BERT 或 ALBERT 如何不能用于逐字比较充满诗意,但没有人明确说明 bert 正在消耗什么。是向量吗?如果是这样,它只是一个单一的向量吗?为什么它不是 GLoVE 向量?(请暂时忽略位置编码讨论)
BERT 不能使用 GloVe 嵌入,仅仅是因为它使用了不同的输入分割。GloVe 使用传统的词类标记,而 BERT 将其输入分割成称为词块的子词单元。一方面,它确保没有超出词汇表的标记,另一方面,完全未知的单词被分割成字符,BERT 可能也无法理解它们。
无论如何,BERT 会与整个模型一起学习其自定义词块嵌入。它们不能携带与 word2vec 或 GloVe 相同类型的语义信息,因为它们通常只是单词片段,BERT 需要在后面的层中理解它们。
如果你愿意,你可能会说输入是单热向量,但几乎总是,它只是一个有用的教学抽象。所有现代深度学习框架都仅通过直接索引来实现嵌入查找,将嵌入矩阵与 one-hot-vector 相乘将是一种浪费。
BERT 的嵌入是 3 件事:
我猜你的问题是关于令牌嵌入的。
标记嵌入是一个向量,其中每个标记都被编码为一个词汇 ID。
例子 :
# !pip install transformers
from transformers import BertTokenizer
t = BertTokenizer.from_pretrained("bert-base-uncased")
text = "My dog is cute."
text2 = "He likes playing"
t1 = t.tokenize(text)
t2 = t.tokenize(text2)
print(t1, t2)
tt = t.encode(t1, t2)
print(tt)
['我的','狗','是','可爱','。'] ['他','喜欢','玩']
[101、2026、3899、2003、10140、1012、102、2002、7777、2652、102]