网站首页 > 技术文章 正文
写在前面
最近测了一下SPTAG这个近似最近邻搜索工具,打算拿一个东西先测测练练手,于是就想到了可以把之前的美女图建一个索引,看看能不能搜到想要的美女图。
需要用到的环境有以下:
- python3.7
- SPTAG(Docker版)
- MongoDB
代码见:github.com/nladuo/MMFi…
准备图片
首先是准备好美女图,我这里是很久以前爬的一些图,一共接近1万张。
如果没有的话,这里提供一下Google Drive下载链接:drive.google.com/file/d/1shZ…。
解压密码:nladuo。
图片过滤
然后接下来是对图片做一些预处理,这里我主要打算做的并不是整个的图片搜索,整个图片的搜索会比较麻烦。我这里只做人脸的搜索。
这里通过face_recognition这个库,把只有一张人脸的图片保存下来,并提取人脸,然后放到mongodb里面。
cd MMFinder/data_preprocess
python3 filter_images.py
这里过滤出来9477张图片
?
特征工程
接下来是要把图片转换成一个向量了,也就是特征工程。因为我本身也不做图像,所以不是很了解具体方法,大概查了一下,传统的方法有SIFT,现在的话就是神经网络了。
如果是一般的图,就用ImageNet训练好的提取最后一层的vector作为特征就好了。这里我找到了一个专门做人脸识别的一个预训练模型:sefiks.com/2018/08/06/…,准确度应该会更高一些。
模型的话就是VGG,最后一层是一个维度为2622的向量。通过处理,这里将所有的人脸转换成一个2622长度的vector,然后保存到mongodb中。
cd MMFinder/data_preprocess
python3 feature_extraction.py
?
建立索引
接下来是建立最近邻的索引,也叫dense-index,在文本搜索引擎中,我们一般用的是TF-IDF,属于sparse-index,也就是倒排索引。而dense-index一般是图结构的索引。
为什么要建索引呢?
其实就是加快搜索速度,如果正常情况下,我们搜索一张图,其实需要和数据库中的9477个向量都算一遍相似度,才能得到精确的相似度排序。这个时间复杂度是O(N)的,看起来不高,但是每次搜索,都是O(N),假设有1亿张图片,那不知道要等到哪年。
有了索引之后,可以保证搜索结果在固定的时间O(C)内返回,如果还慢,加机器就好了。
索引系统的安装
关于索引的选择,我这里使用的是SPTAG,因为这是一个高效可扩展的最近邻搜索系统。类似的系统还有facebook的faiss。这个安装起来其实还是比较麻烦的,如果想跑着玩儿,也可以看看scikit-learn里面的KDTree,LSH等做近似最近邻搜索的方法。
建立索引
安装好Docker下的SPTAG之后,这里先将所有的图片数据导出成SPTAG规定的输入格式。
cd MMFinder/index_construction
python3 export_SPTAG_indexbuilder_input.py
docker cp mm_index_input.txt (你的容器ID):/app/Release/
然后将导出的数据放到SPTAG-Docker容器里,通过indexbuilder建立索引。
docker attach (你的容器ID)
./indexbuilder -d 2622 -v Float -i ./mm_index_input.txt -o data/mm_index -a BKT -t 2
建立好索引之后,启动搜索的rpc服务。
python3 SPTAG_rpc_search_service.py
查询测试
接下来可以进入查询测试了,如果是mac用户可以安装imgcat工具,在命令行就能查看图片。
python3 search_test.py
效果如下,感觉还是可以的
?
前端Demo展示
最后是把各个模块整合一下,编写上传,搜索接口,形成一个完整的应用的Demo。
cd web_demo
python3 main.py
效果如下:
?
(美女图容易被屏蔽,这里用另一个图片集合作为替代)
?
?
- 上一篇: docker容器常用命令汇总
- 下一篇: 新手快速入门Docker,轻松掌握Docker安装与使用
猜你喜欢
- 2025-01-06 工作中必须掌握的docker知识
- 2025-01-06 linux下面安装docker
- 2025-01-06 docker常用指令及安装rabbitMQ
- 2025-01-06 Docker容器的基本介绍及使用
- 2025-01-06 docker -k8s
- 2025-01-06 (干货)Docker 快速入门,对比KVM有什么区别?如何安装与配置?
- 2025-01-06 Docker实践:Docker日常中的一些技巧
- 2025-01-06 Lazy系列:另一个很酷的终端界面工具lazydocker
- 2025-01-06 「云原生」镜像构建实战操作(Dockerfile)
- 2025-01-06 docker容器安装与部署,常用命令、容器卷、dockerfile,详细教程
- 05-15总结雅虎前端性能优化技巧(16条)
- 05-15日常生活中吃雪莲果有养生功效也有危害
- 05-15API 安全之认证鉴权
- 05-15Chaosblade: 阿里一个超级牛逼的混沌实验实施工具
- 05-15膨来仙岛丨搞电竞的都是什么成分?
- 05-15大事全知晓!2022年新闻日历来了!
- 05-15你是有多久没看过麦田圈了?一篇文章全面回顾2015麦田圈季
- 05-15魔兽世界9.1 刻希亚寻找宝箱、稀有WA(转自nga)
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- sqlset (64)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- js数组插入 (83)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)