Florence-2 with OpenVINO & FiftyOne:圖像分析中的現實世界應用
在本文中,我們將深入探討一個實際的現實世界用例,結合兩個強大工具的優勢,以最大化Florence-2模型的效率和易用性。我們將首先使用OpenVINO將原始的PyTorch模型轉換為優化的壓縮格式,使其能夠在僅使用CPU的機器上高效運行。
為了進一步提高其實用性并解鎖額外功能,我們將利用FiftyOne——一個用于探索和策劃圖像數據集的多功能工具——幫助我們在現實世界場景中充分利用模型的預測。
目錄
- 每個組件的簡要介紹
- 從Pexels獲取免費圖片
- FiftyOne數據集
- OpenVINO Florence-2模型
- 將Florence-2預測添加到我們的FiftyOne數據集中
- 探索結果
- 參考文獻、有用鏈接和源代碼
我盡量保持簡單,以便我們開始探索這個流程的潛力。下圖顯示了數據流,從我們收集的圖像(沒有標簽的RGB圖像)到一個已經具有一些有用功能和Florence-2模型預測的FiftyOne數據集。
流程概述
每個組件的簡要介紹
讓我們非常簡要地討論一下提到的每個組件,Florence-2模型、OpenVINO和FiftyOne。
Florence-2是一個尖端的視覺基礎模型,能夠使用簡單的文本提示處理廣泛的計算機視覺和視覺-語言任務。與傳統模型在多項任務上掙扎不同,Florence-2可以輕松地在圖像描述、目標檢測和分割等任務之間切換。它通過使用一個龐大的數據集實現這一點,該數據集包含126百萬圖像上的54億視覺注釋,使其能夠理解復雜的視覺信息。這使得Florence-2成為開發者和研究人員的有力工具,提供了在多種應用中零樣本學習和微調的高級功能。
“OpenVINO是一個開源工具包,用于優化和部署從云端到邊緣的深度學習模型。它加速了各種用例的深度學習推理,例如生成性AI、視頻、音頻和語言,支持PyTorch、TensorFlow、ONNX等流行框架的模型。轉換和優化模型,并在Intel?硬件和環境的混合部署,在本地和設備上,在瀏覽器或云端。”
FiftyOne為優化圖像數據集分析流程提供了構建塊。包括可視化復雜標簽、評估模型預測、識別失敗模式、查找注釋錯誤等。這是一個非常好的工具,強烈推薦你查看他們的官方網站。
從Pexels獲取免費圖片
首先,我們需要一些圖片來開始工作。在這個例子中,我將從pexels.com收集具有通用許可的圖片,為了更有效地下載它們,我使用了一個名為pexel-downloader的Python包,不過你可以使用任何地方的任何圖片池。
安裝pexel-downloader:
pip install pexel-downloader
我已經下載了一些“奧林匹克運動”的圖片,使用pexel-downloader的代碼如下:
from pexel_downloader import PexelDownloader
if __name__ == '__main__':
downloader = PexelDownloader(api_key="<YOUR-PEXELS-API-KEY>")
query = "olympics sports"
save_dir = "./dataset/images"
downloader.download_images(query=query,
num_images=100,
save_directory=save_dir,
size='medium')
這將下載100張圖片并將它們保存到“./dataset/images”文件夾中。
FiftyOne數據集
一旦我們有了圖片文件夾,我們就可以創建我們的初始FiftyOne數據集。安裝FiftyOne和創建五十一數據集的代碼片段:
pip install fiftyone
import fiftyone as fo
images_dir = "./datasets/images"
dataset_name = "sports-dataset"
dataset = fo.Dataset.from_images_dir(images_dir,
name=dataset_name,
persistent=True)
# You can launch the FiftyOne UI from here or later using the CLI program
# to launch it from here you can just do
session = fo.launch_app(dataset)
session.wait(-1)
# to launch from your terminal just do
# fiftyone app launch <dataset-name>
當Fiftyone應用程序運行時,你現在可以從瀏覽器(默認localhost:5151)探索你的數據集。
沒有標簽的我們運動數據集的FiftyOne UI
OpenVINO Florence-2模型
下一步是使用OpenVINO優化Florence-2模型。幸運的是,我們可以依賴英特爾OpenVINO團隊的出色工作。他們已經創建了一個全面的演示和代碼,展示了如何從Hugging Face轉換Florence-2 PyTorch模型。你可以從我的Google Drive獲取轉換后的模型,只需將其下載到完整代碼項目目錄的主文件夾中(本文的完整Github代碼見文章末尾)。
將Florence-2預測添加到我們的FiftyOne數據集中
最后,讓我們將OpenVINO Florence-2預測添加到我們的FiftyOne數據集中!為此,我們只使用目標檢測和圖像描述。此外,讓我們探索另一個非常有用的特性,即圖像嵌入空間探索工具,為此,讓我們將佛羅倫薩圖像編碼器的輸出保存為我們的圖像嵌入。完整的代碼如下所述,基本上,它加載我們已經創建的Fiftyone數據集,并從磁盤加載我們的模型(使用openvino-notebook示例中的OVFlorence2Model)。
import click
import fiftyone.brain as fob
import fiftyone as fo
from ov_florence2_helper import OVFlorence2Model
from transformers import AutoProcessor
from PIL import Image
import numpy as np
def normalize_bbox(bbox, image_height, image_width):
x1, y1, x2, y2 = bbox
return (x1 / image_width, y1 / image_height,
(x2 - x1) / image_width, (y2 - y1) / image_height)
def run_inference(sample_collection, model_path):
processor = AutoProcessor.from_pretrained(model_path, trust_remote_code=True)
model = OVFlorence2Model(model_path, "AUTO")
for sample in sample_collection.iter_samples(autosave=True, progress=True):
try:
# Load image
image = Image.open(sample.filepath)
width, height = image.width, image.height
# Extract image-features (embedding)
inputs = processor(text="<OD>", images=image, return_tensors="pt")
image_features = model.encode_image(inputs["pixel_values"])
# Object detection and caption inference in a single loop
detections, caption = [], None
for task in ["<OD>", "<CAPTION>"]:
if task == "<CAPTION>":
inputs = processor(text=task, images=image, return_tensors="pt")
generated_ids = model.generate(input_ids=inputs["input_ids"],
pixel_values=inputs["pixel_values"],
max_new_tokens=1024,
do_sample=False,
image_features=image_features,
num_beams=3)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
parsed_answer = processor.post_process_generation(generated_text, task=task, image_size=(width, height))
if task == "<OD>":
for idx, bbox in enumerate(parsed_answer[task]['bboxes']):
label = parsed_answer[task]["labels"][idx]
normalized_bbox = normalize_bbox(bbox, height, width)
detections.append(fo.Detection(label=label, bounding_box=normalized_bbox))
else:
caption = parsed_answer[task]
# Add predictions to sample
sample["detections"] = fo.Detections(detections=detections)
sample["caption"] = caption
sample["florence2_image_feats"] = image_features.reshape(-1) # flatting image features
except Exception as e:
continue
@click.command()
@click.option("--dataset-name",
"--name",
required=True,
prompt="Name of the dataset?")
@click.option("--model-path",
"-m",
required=False,
default="Florence-2-base")
def main(dataset_name, model_path):
assert fo.dataset_exists(dataset_name), f"Dataset {dataset_name} does not exist yet."
dataset = fo.load_dataset(dataset_name)
run_inference(dataset, model_path)
###################################################################
# Get 2D embedding space visualization from florence2-image-feats #
###################################################################
# recovery embeddings (image features) from the sample field "florence2_image_feats", populated during "run_inference"
florence_embeddings = dataset.values(field_or_expr="florence2_image_feats")
florence_embeddings = np.array(florence_embeddings).reshape(len(dataset), -1)
print("[INFO] Computing 2D visualization using embeddings")
fob.compute_visualization(dataset,
embeddings=florence_embeddings,
method="umap",
brain_key="florence2_embegginds_viz")
if __name__ == '__main__':
main()
我們添加了模型的三個期望內容,目標檢測(邊界框)、標題(文本)和圖像嵌入(編碼器的圖像特征)。
sample["detections"] = fo.Detections(detections=detections)
sample["caption"] = caption
sample["florence2_image_feats"] = image_features.reshape(-1) # flatting image features
在遍歷所有樣本并添加預測之后,我們可以使用“florence2_image_feats”創建嵌入空間的2D可視化。下面的代碼片段顯示了如何使用FiftyOne大腦模塊(fiftyone.brain)的內置函數來實現這一點。
###################################################################
# Get 2D embedding space visualization from florence2-image-feats #
###################################################################
# recovery embeddings (image features) from the sample field "florence2_image_feats", populated during "run_inference"
florence_embeddings = dataset.values(field_or_expr="florence2_image_feats")
florence_embeddings = np.array(florence_embeddings).reshape(len(dataset), -1)
print("[INFO] Computing 2D visualization using embeddings")
fob.compute_visualization(dataset,
embeddings=florence_embeddings,
method="umap",
brain_key="florence2_embegginds_viz")
探索結果
帶有標題的樣本示例:“兩個擊劍運動員在舞臺上進行動作”
標題:“一群花樣游泳運動員在游泳池中”
讓我們也檢查一下嵌入空間以及嵌入接近的樣本之間的關系(“聚類意義”)。
一個包含游泳池/水的圖像群
體育場
參考資料OpenVINO的官方文檔:https://docs.openvino.ai/2024/index.html
完整代碼:https://github.com/Gabriellgpc/computer-vision-dataset-maker