minimind-v/model/vision_utils.py

63 lines
2.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import warnings
from transformers import CLIPProcessor, CLIPModel
from PIL import Image
import requests
import torch
import transformers
warnings.filterwarnings('ignore')
def get_vision_model():
# 加载预训练的CLIP模型和处理器
model_path = "./model/clip_model/clip-vit-base-patch32"
model = CLIPModel.from_pretrained(model_path)
processor = CLIPProcessor.from_pretrained(model_path)
return (model, processor)
def get_img_process(image, processor):
# 将图像调整为144*144大小
image = image.resize((224, 224))
# 使用CLIPProcessor处理每个patch
inputs = processor(images=image, return_tensors="pt", clean_up_tokenization_spaces=False)
return inputs
def get_img_embedding(batch_encoding, vision_model):
embeddings = []
def hook_fn(module, input, output):
# 将特征添加到 embeddings 列表中
embeddings.append(output.last_hidden_state)
# 从 BatchEncoding 中提取图像张量
if isinstance(batch_encoding, transformers.tokenization_utils_base.BatchEncoding):
image_tensor = batch_encoding['pixel_values']
else:
image_tensor = batch_encoding # torch.Size([32, 4, 3, 224, 224])
# 如果图像张量的形状是5维,则无需添加额外维度
if len(image_tensor.shape) == 4:
image_tensor = image_tensor.unsqueeze(0) # 添加批次维度
# 获取批次大小
batch_size = image_tensor.size(0)
with torch.no_grad():
# 注册 hook 到模型的目标层(例如 vision_model 的倒数第二层)
layer = vision_model.vision_model.encoder
hook = layer.register_forward_hook(hook_fn)
for i in range(batch_size):
# 取出当前批次中的单个图像
single_image = image_tensor[i] # 添加批次维度
# 调用 get_image_features 来获取图像特征
_ = vision_model.get_image_features(single_image)
# 取消 hook
hook.remove()
# 拼接所有特征向量成为一个张量
all_embeddings = torch.stack(embeddings, dim=0).squeeze() # torch.Size([32, 4, 50, 768])
return all_embeddings