赞
踩
huggingface模型库在cv和nlp中用的太多了,而其中的模型调用方法大同小异,索性直接扒出来源码来看看这些模型的通用性。文章中的模型解析来自huggingface官方源码,该模型为源文件transformers.models.vilt.modeling_vilt.py,真的纯官方模型奥!
该架构在huggingface中通用,都是有模型对应的数据预处理器processor及模型model,应用from_pretrain方法载入。其中,embedding部分不同的模型在接收数据时并不统一,encoder部分几乎所有的自注意力模型都相差不大,例如vit、bert、clip等均使用该架构。
- processor = ViltProcessor.from_pretrained("./vilt-b32-finetuned-vqa") # VILT模型预处理器
- model = ViltForQuestionAnswering.from_pretrained("./vilt-b32-finetuned-vqa").cuda() # VILT预训练模型
导图中的名称来源于源文件的类名,展示了各类的调用关系。
总体流程为:
1. 图像、文本数据经过resize、padding后经过processor得到了模型的输入数据encoding,其中包括图片向量、文本向量、图片与文本向量掩码。其中掩码只有文本padding的部分做了掩码,其余均不进行掩码操作。将encoding送入模型得到输出。
- encoding = processor(image_list, text_list, return_tensors="pt", padding=True)
- outputs = model(**encoding)
2. encoding送入模型中,文本向量与位置编码(0~max_length)同时嵌入到768维之后直接相加变成包含位置编码的文本向量,位置编码为常量不可学习。图片向量通过卷积后展开变成144维向量,随机初始化可学习的位置编码,二者分别融入了图片分块位置信息后分别拼接了cls特殊向量直接相加变成145维包含位置编码的文本向量。
3. 将包含位置编码的文本向量和包含位置编码的文本向量直接拼接,所有文本向量加0,图片向量加1作为区别文本与图片的凭证。(这个区分感觉有点玄学)
4. 拼接后的向量是[batch_size, text_max_length + 145, 768]维的,送入encoder层,VlitLayer的存在意义就是让层数可以修改。encoder层的布局和vit一模一样,绿色部分由ViltSelfAttention层和ViltSelfOutput层实现,第一次黄+绿部分由ViltAttention层实现,第二次黄+蓝由ViltMLP层实现。
5. 经过好几层encoder后,维度不变[batch_size, text_max_length + 145, 768],把这个向量直接作为输出1。另外取向量第一个[batch_size,第一个, 768]向量经过一个线性层作为输出2。这个输出二是文本向量的头一个位置cls,不是图片添加的那个cls。
6. 从输入数据经过整个模型得到了output,这个输出包括输出1和输出2。
应用输出1和输出2可以在后面加上各种各样的分类头做不同的任务,但是从官网下载下来的预训练权重并没有适配各项不同任务,相当于零样本训练模型,还是要做几轮微调才可以达到论文中的指标(我试了最高到69.3%,不知道哪里出了问题,有没有调到70的大佬呢)。在VQA2.0上不做训练验证集准确率为66.98%,微调过后可达到74.5%,代码不放了(这是不花钱能看的?),另外比较费卡,4张12G显卡跑满一个epoch大概需要1.8小时。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。