•轻量级: Florence-2 提供了 0.2B 和 0.7B 两种版本,即使在资源有限的设备上也能流畅运行,极大地降低了使用门槛。
•高性能: 得益于大规模数据集的预训练以及创新的多任务学习策略,Florence-2 在图像描述、目标检测、光学字符识别等任务上均有不俗的表现,甚至可以媲美那些巨型模型!
•统一架构: Florence-2 采用统一的表征来处理各种计算机视觉和视觉语言任务,无需为不同的任务设计不同的模型,简化了模型开发和部署流程。
•图像搜索: 用户可以使用自然语言搜索图像,例如 "找到一张有猫和狗在玩耍的图片"。
•智能助手: 智能助手可以理解用户提供的图像,并回答用户关于图像的问题,提供更智能化的服务。
•辅助驾驶: 自动驾驶汽车可以使用 VQA 技术理解周围环境,例如识别交通信号灯、行人、车辆等,并做出更安全的驾驶决策。
虽然 Florence-2 发布的模型没有直接包含 VQA 功能,但我们可以通过微调的方式,将它训练成一个强大的 VQA 模型。一种有效的方法是使用区域到描述提示,例如,我们可以将问题和图像区域作为输入,并训练模型生成对该区域的描述,从而间接地回答问题。
为了评估 Florence-2 在 VQA 任务上的性能,我们使用 DocVQA 数据集进行了实验。实验结果令人振奋:经过微调后,Florence-2 在 DocVQA 上的 Levenshtein 相似度从 0 提高到 57.0,这意味着模型能够生成与真实答案非常接近的文本输出!
效果验证:模糊图像的问答,提取邮件主题。
迫不及待地想体验 Florence-2 在 VQA 上的强大实力了吗?别着急,我们这就来手把手教你如何微调 Florence-2,打造属于你自己的 VQA 模型!
在开始之前,我们需要做好以下准备工作:
•硬件: 一块 NVIDIA GPU (建议使用 A100 或 T4),当然,如果你没有 GPU 也不用担心,使用 CPU 也是可以的,只是训练速度会慢一些。
•软件: Python 3.8+, PyTorch 1.10+, Transformers 4.20+,这些工具都是开源免费的,安装也非常方便。
•数据集: DocVQA 数据集,你可以在 Hugging Face 上找到它。
万事俱备,只欠代码!接下来,我们将使用 Hugging Face Transformers 库来微调 Florence-2,让它学会回答关于图像的问题!
1.安装依赖:
!pipinstall-qdatasetsflash_attntimmeinops
2.加载数据集:
fromdatasetsimportload_dataset
data=load_dataset("HuggingFaceM4/DocumentVQA")3.加载模型:
fromtransformersimportAutoModelForCausalLM,AutoProcessor
importtorch
device=torch.device("cuda"iftorch.cuda.is_available()else"cpu")
model=AutoModelForCausalLM.from_pretrained(
"microsoft/Florence-2-base-ft",
trust_remote_code=True,
revision="refs/pr/6",
).to(device)
processor=AutoProcessor.from_pretrained(
"microsoft/Florence-2-base-ft",trust_remote_code=True,revision="refs/pr/6"
)
#冻结视觉编码器参数,降低训练成本
forparaminmodel.vision_tower.parameters():
param.requires_grad=False4定义数据集类:
importtorch
fromtorch.utils.dataimportDataset
classDocVQADataset(Dataset):
def__init__(self,data):
self.data=data
def__len__(self):
returnlen(self.data)
def__getitem__(self,idx):
example=self.data[idx]
question="<DocVQA>"+example["question"]
first_answer=example["answers"][0]
image=example["image"].convert("RGB")
returnquestion,first_answer,image5.定义数据加载器:
importos
fromtorch.utils.dataimportDataLoader
fromtqdmimporttqdm
fromtransformersimportAdamW,get_scheduler
defcollate_fn(batch):
questions,answers,images=zip(*batch)
inputs=processor(
text=list(questions),
images=list(images),
return_tensors="pt",
padding=True,
).to(device)
returninputs,answers
train_dataset=DocVQADataset(data["train"])
val_dataset=DocVQADataset(data["validation"])
batch_size=6#根据GPU内存调整
num_workers=0
train_loader=DataLoader(
train_dataset,
batch_size=batch_size,
collate_fn=collate_fn,
num_workers=num_workers,
shuffle=True,
)
val_loader=DataLoader(
val_dataset,
batch_size=batch_size,
collate_fn=collate_fn,
num_workers=num_workers,
)6.微调模型:
epochs=7
optimizer=AdamW(model.parameters(),lr=1e-6)
num_training_steps=epochs*len(train_loader)
lr_scheduler=get_scheduler(
name="linear",
optimizer=optimizer,
num_warmup_steps=0,
num_training_steps=num_training_steps,
)
forepochinrange(epochs):
model.train()
train_loss=0
forinputs,answersintqdm(
train_loader,desc=f"TrainingEpoch{epoch+1}/{epochs}"
):
input_ids=inputs["input_ids"]
pixel_values=inputs["pixel_values"]
labels=(
processor.tokenizer(
text=answers,
return_tensors="pt",
padding=True,
return_token_type_ids=False,
)
.input_ids.to(device)
)
outputs=model(input_ids=input_ids,pixel_values=pixel_values,labels=labels)
loss=outputs.loss
loss.backward()
optimizer.step()
lr_scheduler.step()
optimizer.zero_grad()
train_loss+=loss.item()
avg_train_loss=train_loss/len(train_loader)
print(f"AverageTrainingLoss:{avg_train_loss}")
model.eval()
val_loss=0
withtorch.no_grad():
forbatchintqdm(
val_loader,desc=f"ValidationEpoch{epoch+1}/{epochs}"
):
inputs,answers=batch
input_ids=inputs["input_ids"]
pixel_values=inputs["pixel_values"]
labels=(
processor.tokenizer(
text=answers,
return_tensors="pt",
padding=True,
return_token_type_ids=False,
)
.input_ids.to(device)
)
outputs=model(
input_ids=input_ids,pixel_values=pixel_values,labels=labels
)
loss=outputs.loss
val_loss+=loss.item()
print(val_loss/len(val_loader))7.保存模型:
model.save_pretrained("path/to/save/model")
processor.save_pretrained("path/to/save/processor")完成训练后,你可以使用以下代码来测试你的 VQA 模型:
fromPILimportImage
#加载图像
image=Image.open("path/to/your/image.jpg")
#输入问题
question="Whatisintheimage?"
#使用模型进行预测
inputs=processor(text=question,images=image,return_tensors="pt").to(device)
generated_text=model.generate(**inputs)
#输出预测结果
print(processor.decode(generated_text[0],skip_special_tokens=True))为了更直观地展示 Florence-2 的 VQA 能力,我们提供一些 Demo 示例:
英文:
•Q: What's the retention of Franchise?A: 81.3%.
•Q: What's the share of Industry Switchers Gained?A: 1.7%.
中文:
•Q: “每个图像多少个token?”A: 64.
•Q: 最大图像分辨率?A: 980x980.
Florence-2 凭借其轻量级、高性能和易于微调的特性,为 VQA 领域注入了新的活力。相信在不久的将来,Florence-2 将会在更多 VQA 应用中大放异彩,为我们带来更加智能化的生活体验!
| 欢迎光临 链载Ai (https://www.lianzai.com/) | Powered by Discuz! X3.5 |