向量计算-第11章-实战2-构建“以图搜图”向量检索系统_第1页
向量计算-第11章-实战2-构建“以图搜图”向量检索系统_第2页
向量计算-第11章-实战2-构建“以图搜图”向量检索系统_第3页
向量计算-第11章-实战2-构建“以图搜图”向量检索系统_第4页
向量计算-第11章-实战2-构建“以图搜图”向量检索系统_第5页
已阅读5页,还剩35页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

清华大学出版社《向量计算》配套课件·课堂讲义第11章实战2:构建“以图搜图”向量检索系统换个角度学AI,打通任督二脉刘鹏著·清华大学出版社从零构建一个能看懂图像语义的检索系统《向量计算》配套课件第11章实战2:构建“以图搜图”向量检索系统第11章实战2:构建“以图搜图”向量检索系统2/40教学目标1掌握图像预处理、数据增强与质量评估方法2理解CLIP模型并将图像编码为向量特征3会用Chroma/FAISS/Qdrant存储与检索向量4实现以图搜图、以文搜图与Web检索界面5评估检索准确率并做性能优化重点与难点1重点:CLIP特征提取+向量检索的端到端范式2难点:不同向量数据库的索引类型与参数选择《向量计算》配套课件第11章实战2:构建“以图搜图”向量检索系统第11章实战2:构建“以图搜图”向量检索系统3/40本章内容导航11.1图像数据准备与预处理11.2使用CLIP模型提取图像特征11.3存入向量数据库11.4实现“以图搜图”检索功能11.5本章小结《向量计算》配套课件·第11章实战2:构建“以图搜图”向量检索系统11.1图像数据准备与预处理为何预处理·数据集准备·PIL/OpenCV·数据增强·质量评估·批量流水线《向量计算》配套课件11.1图像数据准备与预处理第11章实战2:构建“以图搜图”向量检索系统5/40为什么需要图像预处理?●统一尺寸:深度学习模型通常要求固定尺寸的输入图像●归一化:将像素值归一化到合理范围,提升训练稳定性●数据增强:通过旋转、翻转、裁剪等操作扩充数据集●质量提升:去噪、增强对比度,提升图像质量–不预处理:模型无法接收不同尺寸图像、像素范围不一致、数据不足易过拟合《向量计算》配套课件11.1图像数据准备与预处理第11章实战2:构建“以图搜图”向量检索系统6/40常用图像数据集对比(表11-1)数据集类型图片数量特点适用场景CIFAR-10通用60,00010个类别,尺寸小教学演示ImageNet通用1,000万+1000个类别模型训练COCO多目标330,000目标检测分割复杂任务Flickr25K风景25,000带标签相似图片搜索商品数据集商品自定义需要自己收集电商搜索《向量计算》配套课件11.1图像数据准备与预处理第11章实战2:构建“以图搜图”向量检索系统7/40OpenCV高级处理:归一化与标准化importcv2importnumpyasnpdefpreprocess_image(image_path,target_size=(224,224)):#读取图像img=cv2.imread(image_path)#转换颜色空间(BGR->RGB)img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#调整大小img=cv2.resize(img,target_size)#归一化到[0,1]范围img=img.astype(np.float32)/255.0#标准化(使用ImageNet的均值和标准差)mean=np.array([0.485,0.456,0.406])std=np.array([0.229,0.224,0.225])img=(img-mean)/stdreturnimg#使用示例processed_img=preprocess_image("./dataset/dresses/dress_001.jpg")print(f"处理后图像形状:{processed_img.shape}")注:BGR转RGB、缩放、归一化到[0,1]再用ImageNet均值方差标准化《向量计算》配套课件11.1图像数据准备与预处理第11章实战2:构建“以图搜图”向量检索系统8/40数据增强:Albumentations流水线importalbumentationsasA#安装:pipinstallalbumentationsdefget_augmentation_pipeline():"""创建数据增强流水线"""returnA.Compose([#几何变换A.RandomRotate90(p=0.5),A.Flip(p=0.5),A.Transpose(p=0.5),#随机裁剪和缩放A.RandomResizedCrop(height=224,width=224,scale=(0.8,1.0),ratio=(0.9,1.1),p=1.0),注:组合几何变换、随机裁剪、颜色变换、噪声模糊与归一化,可对一张图生成多个增强版本《向量计算》配套课件11.1图像数据准备与预处理第11章实战2:构建“以图搜图”向量检索系统9/40图像质量评估:SSIM与MSEfromskimage.metricsimportstructural_similarityasssimdefcalculate_image_quality(img1,img2):"""计算图像质量指标参数:img1,img2:两张numpy格式的图像返回:质量指标字典"""#确保图像尺寸相同ifimg1.shape!=img2.shape:img2=cv2.resize(img2,(img1.shape[1],img1.shape[0]))#转换为灰度图gray1=cv2.cvtColor(img1,cv2.COLOR_RGB2GRAY)gray2=cv2.cvtColor(img2,cv2.COLOR_RGB2GRAY)#计算结构相似度(SSIM)ssim_value=ssim(gray1,gray2,data_range=gray1.max()-gray1.min())#计算均方误差(MSE)mse=np.mean((img1-img2)**2)注:以结构相似度SSIM和均方误差MSE量化图像相似度,用于剔除低质量/重复图像《向量计算》配套课件11.1图像数据准备与预处理第11章实战2:构建“以图搜图”向量检索系统10/40图像相似度计算示例●SSIM越接近1表示结构越相似●MSE越小表示像素差异越小–可用于构建数据集时过滤低质量/重复图像图11-1图像相似度计算示例《向量计算》配套课件11.1图像数据准备与预处理第11章实战2:构建“以图搜图”向量检索系统11/40批量处理流水线:ImagePreprocessorclassImagePreprocessor:"""图像预处理器"""def__init__(self,output_dir,target_size=(224,224)):self.output_dir=Path(output_dir)self.target_size=target_sizeself.output_dir.mkdir(parents=True,exist_ok=True)#创建数据增强流水线self.augmentation=get_augmentation_pipeline()defprocess_single_image(self,image_path):try:#读取图像img=cv2.imread(str(image_path))ifimgisNone:returnNone#转换颜色空间img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#调整大小img=cv2.resize(img,self.target_size)#应用数据增强augmented=self.augmentation(image=img)returnaugmented['image']注:统一尺寸、颜色转换、数据增强,批量处理并pickle保存处理结果《向量计算》配套课件·第11章实战2:构建“以图搜图”向量检索系统11.2使用CLIP模型提取图像特征CLIP核心思想·架构·安装·特征提取·保存与可视化《向量计算》配套课件11.2使用CLIP模型提取图像特征第11章实战2:构建“以图搜图”向量检索系统13/40CLIP:核心思想与双塔架构●OpenAI于2021年提出的多模态模型,经4亿对图像-文本数据训练–双塔结构:图像编码器(ViT/ResNet)+文本编码器(Transformer)●对比学习:匹配的图像-文本对向量更接近,不匹配的更远离–训练损失ContrastiveLoss:正样本拉近、负样本推远●优势:语义理解强、零样本泛化、跨模态检索、预训练即用《向量计算》配套课件11.2使用CLIP模型提取图像特征第11章实战2:构建“以图搜图”向量检索系统14/40安装CLIP:三种方式pipinstallgit+/openai/CLIP.gitpipinstalltransformerstorchpillowpipinstallsentence-transformers注:OpenAICLIP/HuggingFaceTransformers/Sentence-Transformers《向量计算》配套课件11.2使用CLIP模型提取图像特征第11章实战2:构建“以图搜图”向量检索系统15/40使用OpenAICLIP:加载模型importclipimporttorch#检查CUDA是否可用device="cuda"iftorch.cuda.is_available()else"cpu"print(f"使用设备:{device}")#加载CLIP模型model,preprocess=clip.load("ViT-B/32",device=device)#查看模型信息print(f"模型类型:{model.visual.__class__.__name__}")print(f"特征维度:{model.visual.output_dim}")print(f"输入图像尺寸:{model.visual.input_resolution}")注:自动选择cuda/cpu,加载ViT-B/32并打印模型信息(特征维度512)《向量计算》配套课件11.2使用CLIP模型提取图像特征第11章实战2:构建“以图搜图”向量检索系统16/40提取单张图像的特征fromPILimportImagedefextract_image_feature(image_path,model,preprocess,device):"""提取图像特征参数:image_path:图像路径model:CLIP模型preprocess:CLIP预处理函数device:设备(cuda/cpu)返回:图像特征向量"""#加载并预处理图像image=Image.open(image_path)image_input=preprocess(image).unsqueeze(0).to(device)#提取特征withtorch.no_grad():image_features=model.encode_image(image_input)注:encode_image后归一化(用于余弦相似度),转为numpy向量《向量计算》配套课件11.2使用CLIP模型提取图像特征第11章实战2:构建“以图搜图”向量检索系统17/40批量提取数据集特征defextract_dataset_features(dataset_dir,model,preprocess,device,batch_size=32):"""批量提取数据集的特征"""dataset_path=Path(dataset_dir)image_extensions={'.jpg','.jpeg','.png','.bmp','.webp'}#收集所有图像路径image_paths=[]forimg_pathindataset_path.rglob('*'):ifimg_path.suffix.lower()inimage_extensions:image_paths.append(img_path)print(f"找到{len(image_paths)}张图像")#提取特征features=[]metadata=[]model.eval()#设置为评估模式foriintqdm(range(0,len(image_paths),batch_size),desc="提取特征"):batch_paths=image_paths[i:i+batch_size]注:收集图像路径、model.eval()、按batch_size分批;每批encode_image后归一化收集特征与元数据《向量计算》配套课件11.2使用CLIP模型提取图像特征第11章实战2:构建“以图搜图”向量检索系统18/40保存特征与t-SNE降维可视化importpickleimportnumpyasnpdefsave_features(features,metadata,output_path):features_array=np.array(features)data={'features':features_array,'metadata':metadata,'feature_dim':features_array.shape[1],'num_images':len(features)}withopen(output_path,'wb')asf:pickle.dump(data,f)fromsklearn.manifoldimportTSNEimportmatplotlib.pyplotaspltprint("正在使用t-SNE降维...")#使用t-SNE降维到2Dtsne=TSNE(n_components=2,random_state=42,perplexity=30)features_2d=tsne.fit_transform(features)注:特征pickle持久化;用t-SNE降到2D后按类别绘制散点,同类图像会聚集《向量计算》配套课件·第11章实战2:构建“以图搜图”向量检索系统11.3存入向量数据库为何需要·数据库选型·Chroma·FAISS·Qdrant·性能优化《向量计算》配套课件11.3存入向量数据库第11章实战2:构建“以图搜图”向量检索系统20/40为什么需要向量数据库存储图像特征?●CLIP-ViT-B-32特征为512维,数据集常含成千上万张图片–线性扫描耗时长:每次查询与所有向量算相似度,复杂度O(n)–内存占用大:100万张512维向量约需2GB内存●专业索引(HNSW/IVF):检索复杂度接近O(logn)–支持向量压缩(PQ)、分布式扩展与元数据管理《向量计算》配套课件11.3存入向量数据库第11章实战2:构建“以图搜图”向量检索系统21/40适合图像检索的向量数据库对比(表11-2)数据库图像检索优势学习成本性能适用场景Chroma简单易用,快速原型低中小规模数据集(<10万)Milvus高性能,支持多种索引中高中大规模(10万至1亿)Qdrant快速,Rust实现低高中大规模Weaviate模块化,支持多种模型中高复杂场景FAISS高性能,纯计算高最高大规模离线检索《向量计算》配套课件11.3存入向量数据库第11章实战2:构建“以图搜图”向量检索系统22/40向量数据库选择建议●学习和原型开发:Chroma或FAISS●生产环境(中等规模):Qdrant或Milvus●生产环境(大规模):Milvus或FAISS–本实战以Chroma、FAISS、Qdrant三种为代表演示《向量计算》配套课件11.3存入向量数据库第11章实战2:构建“以图搜图”向量检索系统23/40Chroma:创建客户端与集合importchromadb#创建持久化客户端client=chromadb.PersistentClient(path="./image_vector_db")print("Chroma客户端创建成功")defcreate_image_collection(client,collection_name="image_features"):#检查集合是否已存在try:collection=client.get_collection(name=collection_name)returncollectionexcept:collection=client.create_collection(name=collection_name,metadata={"description":"Imagefeaturevectors","model":"CLIP-ViT-B-32","dimension":512})注:PersistentClient→get/create_collection(metadata维度512),插入用collection.add(embeddings,metadatas,ids)《向量计算》配套课件11.3存入向量数据库第11章实战2:构建“以图搜图”向量检索系统24/40FAISS:创建索引(IVF/PQ/HNSW)importfaissimportnumpyasnpclassImageVectorSearch:"""基于Faiss的图像向量搜索"""def__init__(self,feature_dim,index_type='IVFFlat'):self.feature_dim=feature_dimself.index_type=index_typeself.index=Noneself.metadata=[]self.create_index()defcreate_index(self):ifself.index_type=='IVFFlat':quantizer=faiss.IndexFlatL2(self.feature_dim)self.index=faiss.IndexIVFFlat(quantizer,self.feature_dim,100)elifself.index_type=='HNSW':self.index=faiss.IndexHNSWFlat(self.feature_dim,32)else:#默认:暴力搜索self.index=faiss.IndexFlatL2(self.feature_dim)注:IndexIVFFlat、IndexIVFPQ、IndexHNSWFlat,或默认暴力IndexFlatL2《向量计算》配套课件11.3存入向量数据库第11章实战2:构建“以图搜图”向量检索系统25/40FAISS:添加向量与搜索defadd_vectors(self,vectors,metadata):#转换为float32类型vectors_float32=vectors.astype(np.float32)self.index.add(vectors_float32)self.metadata.extend(metadata)print(f"添加了{len(vectors)}个向量,总数:{self.index.ntotal}")defsearch(self,query_vector,top_k=10):query_vector_float32=np.array([query_vector],dtype=np.float32)ifself.index_typein['IVFFlat','IVFPQ']:#nprobe:搜索的聚类中心数量self.index.nprobe=10distances,indices=self.index.search(query_vector_float32,top_k)results=[]foriinrange(top_k):idx=indices[0][i]ifidx<len(self.metadata)andidx>=0:results.append({'rank':i+1,'distance':distances[0][i],'metadata':self.metadata[idx]})returnresults注:add写入、nprobe设置、index.search返回距离与索引《向量计算》配套课件11.3存入向量数据库第11章实战2:构建“以图搜图”向量检索系统26/40Qdrant:Rust实现的高性能向量数据库●pipinstallqdrant-client,QdrantClient(host,port=6333)–create_collection时VectorParams(size=512,distance=Distance.COSINE)●插入:PointStruct(id,vector,payload)+client.upsert●搜索:client.search(query_vector,limit=top_k,with_payload=True)–结果hit.score即相似度,hit.payload携带路径等元数据《向量计算》配套课件11.3存入向量数据库第11章实战2:构建“以图搜图”向量检索系统27/40优化向量数据库性能:索引与GPU加速#对于小规模数据集(<10万):使用Flat索引index_type='Flat'#暴力搜索,精度最高,但速度慢#对于中等规模(10万-100万):使用IVFFlatindex_type='IVFFlat'#平衡精度和速度#对于大规模(>100万):使用IVFPQ或HNSWindex_type='IVFPQ'#空间占用小,速度快nlist=int(np.sqrt(len(features)))#聚类中心数量,通常为数据量的平方根importfaiss#将索引转移到GPUres=faiss.StandardGpuResources()gpu_index=faiss.index_cpu_to_gpu(res,0,vector_search.index)#使用GPU索引进行搜索gpu_index.nprobe=10distances,indices=gpu_index.search(query_vector,top_k=10)注:按数据规模选索引类型,nprobe等调参,index_cpu_to_gpu加速《向量计算》配套课件·第11章实战2:构建“以图搜图”向量检索系统11.4实现“以图搜图”检索功能系统架构·核心检索·批量/过滤·Web界面·以文搜图·性能评估·完整代码《向量计算》配套课件11.4实现“以图搜图”检索功能第11章实战2:构建“以图搜图”向量检索系统29/40完整的以图搜图系统架构●图像输入:用户上传或拍照上传查询图像●特征提取:使用CLIP模型提取查询图像的特征向量●相似度检索:在向量数据库中搜索最相似的K张图片●结果展示:展示相似图像和相似度分数–核心范式:特征提取+向量检索《向量计算》配套课件11.4实现“以图搜图”检索功能第11章实战2:构建“以图搜图”向量检索系统30/40核心检索类:ImageSearchSystemclassImageSearchSystem:"""以图搜图系统"""def__init__(self,vector_db,model,preprocess,device):self.vector_db=vector_dbself.model=modelself.preprocess=preprocessself.device=deviceself.model.eval()defextract_query_feature(self,query_image_path):image=Image.open(query_image_path)image_input=self.preprocess(image).unsqueeze(0).to(self.device)withtorch.no_grad():query_feature=self.model.encode_image(image_input)query_feature=query_feature/query_feature.norm(dim=-1,keepdim=True)query_feature=query_feature.cpu().numpy()[0]returnquery_feature注:初始化持有vector_db与CLIP模型,提取查询特征并search《向量计算》配套课件11.4实现“以图搜图”检索功能第11章实战2:构建“以图搜图”向量检索系统31/40核心检索:search与结果可视化defsearch(self,query_image_path,top_k=10):#1.提取查询特征query_feature=self.extract_query_feature(query_image_path)#2.在向量数据库中搜索results=self.vector_db.search(query_feature,top_k=top_k)returnresultsdefsearch_and_visualize(self,query_image_path,top_k=10,output_path='search_result.png'):#执行搜索results=self.search(query_image_path,top_k=top_k)#可视化结果self.visualize_results(query_image_path,results,output_path)returnresultssearch_system=ImageSearchSystem(vector_db=vector_search,model=model,preprocess=preprocess,device=device)query_image="./dataset/dresses/dress_001.jpg"results=search_system.search_and_visualize(query_image,top_k=10)注:search调用vector_db搜索;可视化以网格展示查询与Top-K《向量计算》配套课件11.4实现“以图搜图”检索功能第11章实战2:构建“以图搜图”向量检索系统32/40批量搜索与高级过滤defbatch_search(search_system,query_images,top_k=10):"""批量搜索"""all_results=[]fori,query_imageinenumerate(tqdm(query_images,desc="批量搜索")):results=search_system.search(query_image,top_k=top_k)all_results.append({'query_image':query_image,'results':results})print(f"查询{i+1}:{query_image}")print(f"找到{len(results)}个相似图像\n")returnall_resultsdefsearch_with_filters(search_system,query_image_path,category_filter=None,top_k=10):#执行搜索(返回更多结果,以便过滤)results=search_system.search(query_image_path,top_k=top_k*10)ifcategory_filter:filtered_results=[resultforresultinresultsifresult['metadata']['category']==category_filter]filtered_results=filtered_results[:top_k]else:filtered_results=results[:top_k]returnfiltered_results注:batch_search遍历多查询;search_with_filters按类别过滤Top-K《向量计算》配套课件11.4实现“以图搜图”检索功能第11章实战2:构建“以图搜图”向量检索系统33/40构建StreamlitWeb界面●安装:pipinstallstreamlitpillow,streamlitrunapp.py–侧边栏:top_k滑块+CLIP模型下拉选择(ViT-B/32等)–st.cache_resource缓存模型加载,避免重复下载●st.file_uploader上传图片→preprocess→encode_image●调用vector_search.search,用st.columns网格展示相似图与相似度《向量计算》配套课件11.4实现“以图搜图”检索功能第11章实战2:构建“以图搜图”向量检索系统34/40多模态检索:以文搜图deftext_to_image_search(search_system,text_query,top_k=10):"""使用文本查询搜索图像"""#分词并编码文本text_tokens=clip.tokenize([text_query]).to(search_system.device)#提取文本特征withtorch.no_grad():text_features=search_system.model.encode_text(text_tokens)#归一化text_features=text_features/text_features.norm(dim=-1,keepdim=True)text_features=text_features.cpu().numpy()[0]#在向量数据库中搜索results=search_system.vector_db.search(text_features,top_k=top_k)returnresultstext_query="一条红色的连衣裙"results=text_to_image_search(search_system,text_query,top_k=10)注:clip.tokenize+encode_text得文本向量,在同一向量库检索《向量计算》配套课件11.4实现“以图搜图”检索功能第11章实战2:构建“以图搜图”向量检索系统35/40性能优化技巧●缓存查询结果:继承系统类,用图像md5哈希作缓存键–命中缓存直接返回,超出cache_size删除最旧项(LRU)●批量查询:stack多张查询图一次encode_image–批量提取特征后逐个search,摊薄模型前向开销《向量计算》配套课件11.4实现“以图搜图”检索功能第11章实战2:构建“以图搜图”向量检索系统36/40评估检索性能:Top-K准确率与曲线defevaluate_retrieval_accuracy(search_system,query_dataset,top_k=10):correct=0total=len(query_dataset)forqueryintqdm(query_dataset,desc="评估检索性能"):results=search_system.search(query['query_image'],top_k=top_k)#检查Top-K结果中是否有正确类别top_k_categories=[r['metadata']['category']forrinresults]ifquery['ground_truth_category']intop_k_categories:correct+=1accuracy=correct/totalprint(f"\n检索准确率(Top-{top_k}):{accuracy:.2%}")returnaccuracydefplot_accuracy_curve(search_system,query_dataset,max_k=20):accuracies=[]forkinrange(1,max_k+1):accuracy=e

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论