2021SC@SDUSC

本篇博客为项目汇报:应用本学期对Tensorflow.Similarity的学习认识,实现相似图片搜索系统。

基于TensorflowSimilarity的相似图片搜索引擎

  • 摘要
  • 1 总体设计
    • 1.1 需求规定及运行环境
    • 1.2 基本设计概念和处理流程
  • 2 图像预处理
    • 2.1读取和预处理
  • 3 神经网络模型
    • 3.1 什么是VGG16
    • 3.2为什么选择VGG16
  • 3.3特征提取
  • 4 搜索
    • 4.1利用 L2 Norm 计算距离
    • 4.2图片数据库
  • 5 总结

摘要

传统图像搜索引擎是一个图像数据库,一般可以通过使用关键字进行搜索,以便用户可以找到有价值的图像。 创建于 2001 年 7 月 12 日的谷歌图片搜索引擎是当今最全面、最著名的图片搜索引擎,2001 年,Google 注意到对其常规搜索无法满足的特定查询的巨大搜索需求。 对于特定的搜索,谷歌注意到图像结果会比同样情况下的文本结果好得多。但是限制与图片的特定标注以及不同用户对同一事物描述的差异,当用户根据一个图片搜索其他相关图片时,结果往往不理想。
[1] [2] 介绍了如何利用PyTorch训练和评估CNN以进行图像搜索,包括:用于图像检索的训练(微调)CNN;Supervised Whitening,作为后处理,用于全局图像描述符;在Oxford和Paris数据集上测试 CNN 图像检索。
综上,结合学习相似开源项目代码[3][4],我使用Tensorflow.Keras(目前流行的开源人工神经网络库)+ Flask,编写完成一个简单但易于使用的Image Reverse Retrieval Engine。

1 总体设计

1.1 需求规定及运行环境

使用者上传需要搜索的图片,根据相似度的高低排序反馈前30个最相似的图片。


如图,输入图片为人和一只宠物狗,系统反馈30张同种类宠物狗的图片,并更具相似度高低排序输出。

1.2 基本设计概念和处理流程

代码部分分为三大主体:feature_extractor.py, offline.py, server.py。

feature_extractor.py:调用深度学习模型,定义方法extract(self, img)进行图像预处理并
利用ImageNet预训练模型VGG-16进行特征提取,最后对提取的特征矩阵正则处理。
Offline.py:对数据库里的每个图片进行一个特征提取,每个4096D特征存入./static/feature以便后期搜索。
server.py:此文件运行网络服务器。 我们可以通过 Flask 网络界面将我们的查询图像发送到服务器。 服务器通过简单的线性搜索找到与查询相似的图像。

2 图像预处理

在框架飞速发展的今天,每个框架都有自己处理图片的方式,每个框架都有自己的规范。 因此,在一个框架中开发的 CV 解决方案在另一个框架中可能无法按预期工作。[5] “Tensorflow 的 tf.image.resize 如何偷走了我生命中的 60 天” 是这种情况的一个例子。 找出问题所在可能需要数天时间,并且可能会大大延迟项目进度。

2.1读取和预处理

因为计算机视觉实验均使用opencv完成,当最初使用OpenCV读取图片时,会出现部分图片颜色不正常情况,如下图1:

通常,图像具有红、绿和蓝 (RGB) 三种颜色通道,它们在像素中产生颜色。 这些通道的顺序会改变像素的颜色,因为像素总是将第一个通道解释为红色,第二个通道解释为绿色,第三个通道解释为蓝色。当我们使用 OpenCV 打开图像时,默认情况下 OpenCV 在蓝色、绿色和红色通道 (BGR) 中打开图像。但是当我们显示图像时,像素会误解通道(即像素会混淆并将蓝色解释为红色,反之亦然)。 这就是我们在图像中得到上述错误颜色的原因。另外当使用TensorFlow读取图片时,其默认的Discrete Cosine Transform会时图片像素点数值出现偏差,影响后续特征提取过程。所以经过尝试,使用PIL(python image libraries)读取图片,并统一到(224,224)大小以便后续训练,可以通过简单步骤完成同时避免上述问题:

from PIL import Image
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_inputimg = Image.open(file)
img = img.resize((224, 224)).convert(‘RGB’)x = image.img_to_array(img)  # To np.array
x = np.expand_dims(x, axis=0)  # (H,W,C) -> (1, H, W, C),也可以用reshape方法完成
x = preprocess_input(x)  # 将数组转化为模型需要的格式

3 神经网络模型

3.1 什么是VGG16

[6]VGG16 是一种简单且广泛使用的卷积神经网络 (CNN) 架构,用于 ImageNet,这是一个用于视觉对象识别软件研究的大型视觉数据库项目。 VGG16 架构是由牛津大学的 Karen Simonyan 和 Andrew Zisserman 在 2014 年通过他们的文章“用于大规模图像识别的非常深的卷积网络”开发和介绍的。 ‘VGG’是Visual Geometry Group的缩写,是牛津大学的一组研究人员开发了这种架构,’16’意味着这个架构有16层.
VGG16 模型在 ImageNet 中达到了 92.7% 的 top-5 测试准确率,ImageNet 是一个包含 1000 个类别的超过 1400 万张图像的数据集。 它是 2014 年提交给 ImageNet 大规模视觉识别挑战 (ILSVRC) 的著名模型之一。 它通过替换大内核大小的过滤器(第一和第二卷积层分别为 11 和 5)对 AlexNet 架构进行了改进 一个接一个地使用多个 3 × 3 内核大小的过滤器。 VGG16 使用 NVIDIA Titan Black GPU 进行了数周的训练。
VGG16 被用于许多深度学习图像分类技术,并因其易于实现而广受欢迎。 由于 VGG16 具有的优势,它被广泛用于学习应用程序。
VGG16是一种CNN架构,用于在2014年赢得ImageNet大规模视觉识别挑战赛(ILSVRC),至今仍是最好的视觉架构之一。

3.2为什么选择VGG16

当下有许多主流神经网络可以使用以提供极其高效的特征提取。但大多提取的特征数过多,众多的特征面对某些特定的任务可能回表现出更好的准确率,但是过多的零数据为图像搜索系统带来了不必要的冗余,导致之后必须进行特征的linear regression来提高搜索效率。
如下是其他流行神经网络提取的特征信息:
inception:
Convolutional features
Shape: (5, 5, 2048)
Num Features: 51200
Features that are Zero: 34326
Ratio Features that are non-Zero: 0.33
xception:
Convolutional features
Shape: (7, 7, 2048)
Num Features: 100352
Features that are Zero: 70827
Ratio Features that are non-Zero: 29.42
vgg19:
Convolutional features
Shape: (7, 7, 512)
Num Features: 25088
Features that are Zero: 21182
Ratio Features that are non-Zero: 15.57
mobile:
Convolutional features
Shape: (7, 7, 1024)
Num Features: 50176
Features that are Zero: 40395
Ratio Features that are non-Zero: 19.49
在上述神经网络中VGG16提取4096个特征值,且具有易于移植使用的特点,故本项目使用VGG16模型。

3.3特征提取

首先从keras上下载并使用预先训练好的VGG16模型:

def __init__(self):base_model = VGG16(weights='/Users/xu/Downloads/   vgg16_weights_tf_dim_ordering_tf_kernels.h5')self.model = Model(inputs=base_model.input, outputs=base_model.get_layer('fc1').output)

之后提取特征并求其范数:

feature = self.model.predict(x)[0]
return feature / np.linalg.norm(feature)  # Normalize

4 搜索

4.1利用 L2 Norm 计算距离

向量的长度可以使用 L2 范数计算,其中 2 是 L 的上标,例如 L^2。
向量的 L2 范数的表示法是 ||v||2,其中 2 是下标。
L2范数计算向量坐标到向量空间原点的距离。 因此,它也被称为欧几里得范数,因为它计算为与原点的欧式距离。 结果是正距离值。L2 范数计算为平方矢量值之和的平方根。
与 L1 范数一样,L2 范数通常用于拟合机器学习算法作为正则化方法,例如一种保持模型系数较小的方法,从而使模型不那么复杂。

dists = np.linalg.norm(features - query, axis=1)  # L2 distances to the features
ids = np.argsort(dists)[:30]  # top 30 results
scores = [(dists[id], img_paths[id]) for id in ids]

4.2图片数据库

通过谷歌图片搜索,我随机针对一些图片类别爬取了下述图片:
ls google_images_sample/*
/google_images_sample/botanical:
apple_tree/ crocus/ japanese_cherry_blossom/ oak_tree/ tulips/
cactus/ daffodil/ lavender/ park/ willow_tree/
cat_mint/ garden/ lilac/ roses/
cherry_tree/ hyacinth/ maple_tree/ sakura/

/google_images_sample/food:
bahn_mi/ chocolate_bar/ ice_cream_sundae/ pho/
brunch/ dumplings/ omlette/ poached_eggs/
burrito/ gumbo/ orange_juice/ spaghetti/
cheeseburger/ hand_pulled_noodles/ perogies/ sushi/

/google_images_sample/industrial:
airplane/ building/ museum/ skatepark/ street_corner/ train/
boat/ bus/ office/ statue/ street_light/
bodega/ downtown/ scaffolding/ storefront/ town_square/

/google_images_sample/landlife:
brown_bear/ cougar/ elk/ geckos/ jackals/ puffin/
cat/ cow_herd/ flamingos/ gorillas/ orangutan/ wolves/
chimpanzees/ dog/ foxes/ hawk/ pigeons/

/google_images_sample/memes:
alt_right_meme/ kermit_meme/ racist_meme/ spongebob_meme/
bad_meme/ meme/ runny_meme/ trump_meme/
dank_meme/ nazi_meme/ shrek_meme/ tumlbr_meme/
hank_hill_meme/ political_meme/ simpsons_meme/

/google_images_sample/people:
blue_collar_worker/ people_planting_trees/ people_working_out/
city_people/ people_playing_basketball/ pilates/
downtown_people/ people_playing_soccer/ selfie/
people_brunch/ people_playing_tennis/ times_square_people/
people_excited/ people_riding_bikes/ white_collar_worker/
people_exercising/ people_riding_horses/ working_out/
people_farming/ people_riding_motorcycles/ working_out_gym/
people_jogging/ people_skateboarding/ yoga/
people_lifting_weights/ people_voting/ yoga_people/
people_picnic/ people_watching_fireworks/

/google_images_sample/sealife:
big_mouth_bass/ dolphins/ otter/ puffer_fish/ sunfish/
clown_fish/ green_coral/ penguin/ sea_turtle/ tuna_fish/
coral_reef/ jellyfish/ pink_coral/ seaweed_kelp/ whales/

5 总结

回顾上述说明,image retrieval engine由下述步骤实现:
1.将图像读取到 numpy 数组,
2.调整大小和预处理
3.实例化VGG16 模型
4.将 numpy 图像转换为 conv 特征
5.保存到带有 img 文件路径的文件
6.输入图片特征计算L2欧式距离
7.反馈前30最相似结果
下阶段可展开的工作:
·扩展数据库图片范围。
·随着图片数据库增大是否可以利用K-Nearest Neighbors(KNN)来优化搜索过程,达到更加准确的相似搜索。
·是否可以将程序优化应用于更加小领域、范围,实现特定领域高精度搜索例如搜索相似画作、服装、T恤图案等等。

TensorFlow-similarity 学习笔记13相关推荐

  1. mybatis学习笔记(13)-延迟加载

    2019独角兽企业重金招聘Python工程师标准>>> mybatis学习笔记(13)-延迟加载 标签: mybatis [TOC] resultMap可以实现高级映射(使用asso ...

  2. TensorFlow 深度学习笔记 TensorFlow实现与优化深度神经网络

    TensorFlow 深度学习笔记 TensorFlow实现与优化深度神经网络 转载请注明作者:梦里风林 Github工程地址:https://github.com/ahangchen/GDLnote ...

  3. opencv进阶学习笔记13:图像形态学操作大全(膨胀,腐蚀,开闭,黑帽,顶帽,梯度)python版

    基础版学习笔记: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) 基础版形态学: opencv学 ...

  4. TensorFlow Lite学习笔记

    TensorFlow Lite学习笔记 目录 TensorFlow Lite学习笔记 Tensorflow LIte Demo 模型固化freeze_graph和模型优化optimize_for_in ...

  5. Linux学习笔记13

    Linux学习笔记13 Linux学习笔记13 配置Nagios 基本介绍 Nagios安装 - 服务端 Nagios安装 - 客户端 监控中心添加被监控主机 配置文件的简单说明 继续添加需要服务端通 ...

  6. Hadoop学习笔记—13.分布式集群中节点的动态添加与下架

    Hadoop学习笔记-13.分布式集群中节点的动态添加与下架 开篇:在本笔记系列的第一篇中,我们介绍了如何搭建伪分布与分布模式的Hadoop集群.现在,我们来了解一下在一个Hadoop分布式集群中,如 ...

  7. 台大李宏毅Machine Learning 2017Fall学习笔记 (13)Semi-supervised Learning

    台大李宏毅Machine Learning 2017Fall学习笔记 (13)Semi-supervised Learning 本博客参考整理自: http://blog.csdn.net/xzy_t ...

  8. java 量化指标_量化投资学习笔记13——各种指标的绘图、计算及交易策略

    <量化投资:以python为工具>第五部分笔记 先来画k线图,要注意finance模块已经从matplotlib库中去除,现在要用mpl_finance库,单独安装. 其中有candles ...

  9. 【计算机网络学习笔记13】交换技术(下)

    [计算机网络学习笔记13]交换技术(下) 一.生成树的诞生和发展 1. 环路问题 两个网桥之间的连接网线如果只有一根,而这根网线或者接口有问题,网络就会出现单点故障.所以为了提高可靠性,网桥在互连时一 ...

  10. R语言小白学习笔记13—基本统计

    R语言小白学习笔记13-基本统计 笔记链接 学习笔记13-基本统计 13.1 概括性统计量 13.2 相关系数和协方差 13.3 t-检验 13.3.1 单样本t检验 13.3.2 两样本t检验 13 ...

最新文章

  1. Openstack安装部署
  2. HDU 2519 新生晚会【求组合数】
  3. [转] GIS算法源码集合
  4. 河北工业机器人夹爪生产厂家_电动夹爪会成为“标配”吗?
  5. springmvc配置文件的主要内容
  6. 遍历同辈节电的方法_JQuery遍历DOM节点的方法
  7. (JAVA)File类
  8. 技术动态 | 知识可视化,连接和探究知识之间的联系!
  9. 删除当前文件夹下特定名称文件
  10. 解决未在此计算机注册ActiveX 控件
  11. Python爬取百度翻译-可以选择语言
  12. Hausdorff 距离
  13. 鸿蒙应用开发教程第12期:被央视点名!打破垄断志在必得?
  14. 如何创建一个虚拟机?
  15. 【AxureRP9】V1.0网易课堂课程
  16. 渗透测试的灵魂:信息收集
  17. 计算机打印机共享无法连接不上,电脑共享打印机连接不上怎么办? 爱问知识人...
  18. SpringBoot整合Mybatis mysql数据库增添查改,分页操作实现
  19. python如何使用geotools_ArcGIS工具之ET GeoWizards、GeoTools、GeoTools
  20. WordCloud库简介与使用示例

热门文章

  1. CAT实时监控预警系统
  2. android 获取SD、ROM容量
  3. Ubuntu下有线连接开无线WIFI的3种方式
  4. word中间空白页删除技巧
  5. 《PyCharm2019安装教程》
  6. 日行一pwn:pwn1_sctf_2016
  7. openwrt的自动挂载功能
  8. 管理每日日程提醒以及待办清单的备忘便签有哪些
  9. oracle orclpdb是什么,oracle cdb、pdb参考
  10. 干货:教你如何玩转信息流广告投放,整套信息流精准定向投放攻略!