参数分布
Bert模型的版本如下:
BERT-Base, Uncased: 12-layer, 768-hidden, 12-heads, 110M parameters
BERT-Large, Uncased: 24-layer, 1024-hidden, 16-heads, 340M parameters
BERT-Base, Cased: 12-layer, 768-hidden, 12-heads , 110M parameters
BERT-Large, Cased: 24-layer, 1024-hidden, 16-heads, 340M parameters
BERT-Base, Chinese: Chinese Simplified and Traditional, 12-layer, 768-hidden, 12-heads, 110M parameters
所有的输入长度最长为512,英文版的"vocab_size": 30522,中文版的"vocab_size": 21128
其中的parameters的数量很少有人关注过,下面就Bert模型中的参数进行一个简单的分析。
Bert模型的输入要做一个向量化,提取每个词的三维信息,如图:
因为,句子的长度不一样,而我们向量化的时候把每个输入都做成了512的长度,这里就需要一个类似补0的操作,我认为这里的表达形式也是一种参数的学习。因此在Embedding层也是有一个权重参数的。
然后就把处理好的向量输入到12个transformer blocks中,每一个transformer block(bert只是使用到transformer的encoder)中包含了encoder模块,具体的构成参考transformer相关文献。在encoder中主要是包含了self-Attention,前馈神经网络和归一化功能。
Self-Attention的主要功能是在编码当前单词的时候能够同时关注到上下文中和它有关的单词,在实现层面上,简单的说就是3个矩阵的自乘,矩阵计算形式:
这个Q、k和V都是要经过和网络的学习得到的权重矩阵做运算得到的,这里很有可能就涉及到大量的参数。
另外前馈神经网络做了全连接,每个连接需要对应的一个权重值——也就是权重参数。
根据具体的实现代码:logits_lm = self.decoder(h_masked)得知,最后在transformer blocks的后面还接入了一个全连接。这里也有一部分参数。
总体来说bert模型的参数主要包含3部分:Embeddding层的参数,transformer blocks的参数和最后输出的全连接参数。
第一部分的参数:
30522*768+512*768+4*768
第二部分参数:
【(768*768+768)*4+(768*2)+(3072*768*2+3072)+768*3】*12
第三部分参数:
768*768+768
参数个数总计:109482240~1.09亿
而BERT-Base, Chinese BERT-Base, Chinese总是约为1.02亿。
代码:
num_weights=0
for name, param in model.state_dict().items():#model为任意加载进来的一个bert模型
if len(param.shape)==1:
num_weights+=param.shape[0]
print(name, param.shape,end=' ')
print('参数个数为:',param.shape[0])
else:
num_weights += param.shape[0]*param.shape[1]
print(name, param.shape, end=' ')
print('参数个数为:', param.shape[0]*param.shape[1])
print('参数总数:',num_weights)
附录——部分参数:
bert.embeddings.word_embeddings.weight torch.Size([30522, 768]) 参数个数为: 23440896
bert.embeddings.position_embeddings.weight torch.Size([512, 768]) 参数个数为: 393216
bert.embeddings.token_type_embeddings.weight torch.Size([2, 768]) 参数个数为: 1536
bert.embeddings.LayerNorm.weight torch.Size([768]) 参数个数为: 768
bert.embeddings.LayerNorm.bias torch.Size([768]) 参数个数为: 768
bert.encoder.layer.0.attention.self.query.weight torch.Size([768, 768]) 参数个数为: 589824
bert.encoder.layer.0.attention.self.query.bias torch.Size([768]) 参数个数为: 768
bert.encoder.layer.0.attention.self.key.weight torch.Size([768, 768]) 参数个数为: 589824
bert.encoder.layer.0.attention.self.key.bias torch.Size([768]) 参数个数为: 768
bert.encoder.layer.0.attention.self.value.weight torch.Size([768, 768]) 参数个数为: 589824
bert.encoder.layer.0.attention.self.value.bias torch.Size([768]) 参数个数为: 768
bert.encoder.layer.0.attention.output.dense.weight torch.Size([768, 768]) 参数个数为: 589824
bert.encoder.layer.0.attention.output.dense.bias torch.Size([768]) 参数个数为: 768
bert.encoder.layer.0.attention.output.LayerNorm.weight torch.Size([768]) 参数个数为: 768
bert.encoder.layer.0.attention.output.LayerNorm.bias torch.Size([768]) 参数个数为: 768
bert.encoder.layer.0.intermediate.dense.weight torch.Size([3072, 768]) 参数个数为: 2359296
bert.encoder.layer.0.intermediate.dense.bias torch.Size([3072]) 参数个数为: 3072
bert.encoder.layer.0.output.dense.weight torch.Size([768, 3072]) 参数个数为: 2359296
bert.encoder.layer.0.output.dense.bias torch.Size([768]) 参数个数为: 768
bert.encoder.layer.0.output.LayerNorm.weight torch.Size([768]) 参数个数为: 768
bert.encoder.layer.0.output.LayerNorm.bias torch.Size([768]) 参数个数为: 768
参考文献: