赞
踩
Towards artificial general intelligence via a multimodal foundation model论文
Towards artificial general intelligence via a multimodal foundation model官方代码
The fundamental goal of artificial intelligence (AI) is to mimic the core cognitive activities of human. Despite tremendous success in the AI research, most of existing methods have only single-cognitive ability. To overcome this limitation and take a solid step towards artificial general intelligence (AGI), we develop a foundation model pre-trained with huge multimodal data, which can be quickly adapted for various downstream cognitive tasks. To achieve this goal, we propose to pre-train our foundation model by self-supervised learning with weak semantic correlation data crawled from the Internet and show that promising results can be obtained on a wide range of downstream tasks. Particularly, with the developed modelinterpretability tools, we demonstrate that strong imagination ability is now possessed by our foundation model. We believe that our work makes a transformative stride towards AGI, from our common practice of “weak or narrow AI” to that of “strong or generalized AI”.
人工智能(AI)的根本目标是模拟人类的核心认知活动。尽管人工智能研究取得了巨大的成功,但现有的方法大多只有单一的认知能力。为了克服这一限制,并向通用人工智能(AGI)迈出坚实的一步,我们开发了一个预先训练了大量多模态数据的基础模型,该模型可以快速适应各种下游认知任务。为了实现这一目标,我们建议使用从互联网上抓取的弱语义相关数据通过自监督学习预训练我们的基础模型,并表明在广泛的下游任务上可以获得令人满意的结果。特别是,通过开发的模型可解释性工具,我们证明了我们的基础模型现在具有很强的想象能力。我们相信,我们的工作对人工智能的发展迈出了革命性的一步,从我们通常的“弱或狭义人工智能”到“强或广义人工智能”。
学习两个可以将图像和文本输入嵌入到同一语义空间的编码器,以实现有效的图像-文本检索。为了使图像和文本编码器在相同的嵌入空间中学习更好的表示,我们在BriVL中引入了使用InfoNCE loss(对比学习损失)的跨模态对比学习。具体来说,我们的学习目标是从给定的文本嵌入中找到相应的图像嵌入,反之亦然。通过最大化每个标记为正值的图像文本对的余弦相似度,同时最小化标记为负对的图像文本对的余弦相似度,我们共同训练图像和文本编码器来学习对齐的跨模态嵌入空间。
我们引入了一个简单而有效的模块,称为多尺度图像块池化模块(Multi-Scale Patch Pooling, MSPP)来解决图像检测器性能问题。
对于每个输入图像
x
(
i
)
x^{(i)}
x(i),我们首先将其分割成不同尺度的多个patch,并记录patch坐标。在所有的实验中,我们采用1 × 1和6 × 6两个尺度,总共得到37个patch。接下来,我们将每一组patch坐标投影到由CNN主干(例如,EfficientNet)获得的feature map上,并生成由37个区域feature map组成的序列。最后,我们对每个区域特征图进行平均池化,得到patch特征序列
S
∈
R
c
×
N
p
S\in R^{c\times N_p}
S∈Rc×Np。其中每列对应一个patch,
N
p
N_p
Np为patch的个数(即本文中
N
p
N_p
Np = 37) ,每行
c
c
c为feature map中的通道数。
为了更好地捕捉图像patch特征之间的关系,我们部署了一个包含多个Transformer编码器层的自注意力块。每个Transformer编码器层由一个多头部注意(MultiHeadAttn)层和一个前馈网络(FFN)层组成:
S
′
=
L
a
y
e
r
N
o
r
m
(
S
+
M
u
l
t
i
H
e
a
d
A
t
t
n
(
S
)
)
S′=LayerNorm(S+MultiHeadAttn(S))
然后,我们通过应用平均池化层融合提取的patch特征,得到最终的d维图像嵌入
z
(
i
)
∈
R
d
z^{(i)}\in R^d
z(i)∈Rd。
给定一个句子 x ( t ) x^{(t)} x(t),我们首先对它进行标记化,得到一个标记序列 T = { t j ∣ j = 1 , . . . , l } T=\{t_j |j = 1,..., l\} T={tj∣j=1,...,l},其中 l l l表示句子的长度(例如,单词的数量), t j t_j tj表示 T T T的第j个标记。然后使用预训练的Transformer编码器(例如RoBERTa)将文本标记映射到特征向量序列(每个特征向量对应一个单词)。同样,为了更好地捕捉单词之间的关系,我们使用与图像编码器中相同的自注意机制来提取文本表示 r ( t ) r^{(t)} r(t)。还使用带有ReLU激活层的两层MLP块将文本表示 r ( t ) r^{(t)} r(t)映射到联合跨模态嵌入空间,从而得到最终的d维文本嵌入 z ( t ) ∈ R d z^{(t)}\in R^d z(t)∈Rd。
我们的BriVL中的跨模态对比损失是基于MoCo定义的,它提供了一种为对比学习构建动态样本队列的机制。由于我们的BriVL中使用的两个负队列将队列大小与迷你批处理大小解耦,因此我们可以拥有比迷你批处理大小大得多的负样本大小(从而节省gpu资源)。
我们构建了一个巨大的网络抓取多源图像文本数据集,称为弱语义相关数据集(weak semantic correlation dataset, WSCD)作为我们的预训练数据集。WSCD从网络上的多个来源收集中文图像-文本对,包括新闻,百科全书和社交媒体。具体地说,来自这些数据源的图像及其相应/周围的文本描述被用来形成图像-文本对。由于获得的图像-文本对是从网络上抓取的,因此期望每对图像和文本是弱相关的。
请注意,我们只过滤掉WSCD中的色情/敏感数据,而没有对原始数据进行任何形式的编辑或修改,以保持数据的自然分布。
人类有一种能力(甚至是本能),当我们听到单词或描述性句子时,相关场景会进入我们的脑海。至于我们的BriVL,一旦在如此大量的松散对齐的图像-文本对上进行预训练,我们就会着迷于当给定文本时它究竟会想象什么。我们不是通过下游任务间接地检查它,而是扩展了特征可视化(Feature Visualization, FeaVis),以直接查看BriVL对语义输入的视觉响应(即想象)。FeaVis是一种仅用于将卷积神经网络的特征可视化的算法。然而,对于像我们的BriVL这样的大规模跨模态基础模型,我们可以通过使用联合图像-文本嵌入空间作为桥梁来可视化任何文本输入。
可以看出,尽管这些概念是相当抽象的,但可视化能够表现出这些概念的具体体现。这种将抽象概念推广到一系列更具体的对象的能力是习得的常识的标志,也是我们仅使用弱语义相关数据(用抽象概念暴露模型)进行多模态预训练的有效性的标志。
接下来的两个文本输入描述了更复杂的场景,它们都来自中国古代诗歌,其语法与数据集中大多数其他文本完全不同,但是BriVL也表现不错。
总的来说,我们发现BriVL在复杂句子作为提示语的情况下具有很强的想象能力。
这些想象结果表明,我们的模型能够将特定对象与更一般的视觉环境联系起来。
具体来说,除了上面描述的图像-文本匹配损失外,我们在图像编码器的池化层(LLP, last layer before pooling)之前的最后一层的特征映射中选择神经元(即通道),并使每个神经元的值最大化。由于每个文本输入可能包含许多语义内容,我们可以看到在一定的语义约束下激活一个神经元是什么。选择三个神经元LLP-108, LLP-456和LLP-678(数字表示每个通道在特征图中的位置)进行神经元可视化。
即使在相同的语义约束下,激活不同的神经元也会导致不同的想象结果,这表明每个文本输入都具有丰富的语义,不同的神经元捕获了不同的方面。
我们利用VQGAN在BriVL的引导下生成图像,并与CLIP生成的图像进行对比。在ILSVRC-2012数据集上预训练的VQGAN在给定一系列token的情况下生成逼真的图像方面表现出色。每个这样的token都是来自VQGAN的预训练令牌集(即码本)的向量。我们首先随机抽取一系列token,并从预训练的VQGAN中获得生成的图像。接下来,我们将生成的图像输入到CLIP/BriVL的图像编码器中,并在文本编码器中输入一段文本。最后,我们定义了图像和文本嵌入匹配的目标,并反向传播结果梯度来更新初始标记序列。与网络/神经元可视化一样,VQGAN和CLIP/BriVL在生成过程中都是冻结的。生成的示例如图3所示:
为了展示我们预训练的BriVL的跨域知识转移能力和域外想象能力,我们在两个遥感场景分类基准上进行了zero-shot实验。
conda create -n BriVL python=3.8.3 -y
conda activate BriVL
pip install pathlib2==2.3.5
pip install pyyaml
pip install easydict==1.9
pip install Pillow==7.2.0
pip install numpy==1.18.5
conda install pytorch==1.7.1 torchvision==0.8.2 torchaudio==0.7.2 cudatoolkit=11.0 -c pytorch
安装pytorch对应版本CUDA
下载CUDA11.0
安装CUDA11.0,不安装驱动
transformers 4.6.1 (installation instructions)
pip install transformers==4.6.1
pip install timm==0.4.9
git clone https://github.com/neilfei/brivl-nmi.git
将预训练模型放入./pretrained/
文件夹
将找好的图片放入图像文件夹
编写输入数据的描述
修改推理代码进行推理
pip install ipykernel
python -m ipykernel install --user --name BriVL
import os
import argparse
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
import numpy as np
import random
from datasets import ImageData, TextData
from models import build_network
from utils import getLanMask
from utils.config import cfg_from_yaml_file, cfg
parser = argparse.ArgumentParser()
parser.add_argument('--load_checkpoint', type=str, default='./pretrained/brivl-with-roberta-base.pth')
parser.add_argument('--gpu_ids', type=str, default='0')
parser.add_argument('--img_bsize', type=int, default=64) # adjust the value according to GPU memory
parser.add_argument('--txt_bsize', type=int, default=64) # adjust the value according to GPU memory
parser.add_argument('--max_text_len', type=int, default=32) # adjust the value according to the maximum number of Chinese characters in each piece of text
# if the maximum number of Chinese characters for all texts is N, then this value should be at least N+2
# this value should not be more than 80
parser.add_argument('--data_root', type=str, default='./imgs') # your path to the folder of images
parser.add_argument('--seed', type=int, default=222)
parser.add_argument('--cfg_file', type=str, default='./cfg/eval.yml')
args = parser.parse_args()
cfg_from_yaml_file(args.cfg_file, cfg)
if args.max_text_len < cfg.MODEL.MAX_TEXT_LEN:
cfg.MODEL.MAX_TEXT_LEN = args.max_text_len
usage: ipykernel_launcher.py [-h] [--load_checkpoint LOAD_CHECKPOINT]
[--gpu_ids GPU_IDS] [--img_bsize IMG_BSIZE]
[--txt_bsize TXT_BSIZE]
[--max_text_len MAX_TEXT_LEN]
[--data_root DATA_ROOT] [--seed SEED]
[--cfg_file CFG_FILE]
ipykernel_launcher.py: error: unrecognized arguments: -f /root/.local/share/jupyter/runtime/kernel-2ef648cf-4761-4520-a9e7-b501bad7d183.json
An exception has occurred, use %tb to see the full traceback.
SystemExit: 2
报错原因为使用argparse模块,argparse模块和ipykernel_launcher.py识别参数会出现冲突,将args = parser.parse_args()
替换为args = parser.parse_known_args()[0]
即可
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_ids
torch.manual_seed(args.seed) # cpu
torch.cuda.manual_seed(args.seed) #gpu
np.random.seed(args.seed) #numpy
random.seed(args.seed) #random and transforms
torch.backends.cudnn.deterministic=True # cudnn
##### load the pre-trained model
print('Loading the pre-trained model...')
model = build_network(cfg.MODEL)
model = model.cuda()
model_component = torch.load(args.load_checkpoint, map_location=torch.device('cpu'))
model.learnable.load_state_dict(model_component['learnable'])
img_encoder = model.learnable['imgencoder'].eval()
txt_encoder = model.learnable['textencoder'].eval()
print('Done')
##### image data img_set = ImageData(cfg, args.data_root) img_loader = DataLoader( img_set, batch_size = args.img_bsize, shuffle = False, num_workers = 8, pin_memory = True, drop_last = False ) ##### extract image features imgFea_all = [] with torch.no_grad(): for i, batch in enumerate(img_loader): images, img_lens, img_boxs = batch[0], batch[1].reshape(-1), batch[2] images = images.cuda() img_boxs = img_boxs.cuda() # get image mask imgMask = getLanMask(img_lens, cfg.MODEL.MAX_IMG_LEN) imgMask = imgMask.cuda() imgFea = img_encoder(images, imgMask, img_boxs) imgFea_l2 = F.normalize(imgFea, p=2, dim=-1) imgFea_all.append(imgFea_l2) imgFea_all = torch.cat(imgFea_all, 0)
##### text data txt_set = TextData(cfg) txt_loader = DataLoader( txt_set, batch_size = args.txt_bsize, shuffle = False, num_workers = 8, pin_memory = True, drop_last = False ) ##### extract text features txtFea_all = [] with torch.no_grad(): for i, batch in enumerate(txt_loader): texts, text_lens = batch[0], batch[1] texts = texts.cuda() # get language mask textMask = getLanMask(text_lens, args.max_text_len) textMask = textMask.cuda() txtFea = txt_encoder(texts, textMask) txtFea_l2 = F.normalize(txtFea, p=2, dim=-1) txtFea_all.append(txtFea_l2) txtFea_all = torch.cat(txtFea_all, 0) ##### compute similarities similarity_matrix = torch.mm(imgFea_all, txtFea_all.t()) similarity_matrix
源代码只会输出相似矩阵的尺寸,这里输出了相似性矩阵
由我们的数据可知在配置文件中的第一行、第二行和第五行是正确描述,第三行和第四行是错误描述,然而相似性矩阵的输出结果表明并不能区分正确还是错误描述,这可能和文字的描述过于简单有关。
对于第六行的COCO数据集的小狗,虽然有较长的文字描述,仍然和前几张猫猫狗狗的推理结果一样,并不能有这很好的对应结果。
对于第七行的复杂内容数据,可能由于不是常见的场景类型,也没有很好的结果。
而第八行到第九行的数据我们给出了更加精准的文字描述并且图片内容较为简单,图文相似度显著提高。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。