神经网络学习小记录53——TF2搭建孪生神经网络(Siamese network)比较图片相似性

  • 学习前言
  • 什么是孪生神经网络
  • 代码下载
  • 孪生神经网络的实现思路
    • 一、预测部分
      • 1、主干网络介绍
      • 2、比较网络
    • 二、训练部分
      • 1、数据集的格式
      • 2、Loss计算
  • 训练自己的孪生神经网络
    • 1、训练本文所使用的Omniglot例子
    • 2、训练自己相似性比较的模型

学习前言

实现一下TF2版本的孪生神经网络。

什么是孪生神经网络

简单来说,孪生神经网络(Siamese network)就是“连体的神经网络”,神经网络的“连体”是通过共享权值来实现的,如下图所示。

所谓权值共享就是当神经网络有两个输入的时候,这两个输入使用的神经网络的权值是共享的(可以理解为使用了同一个神经网络)。

很多时候,我们需要去评判两张图片的相似性,比如比较两张人脸的相似性,我们可以很自然的想到去提取这个图片的特征再进行比较,自然而然的,我们又可以想到利用神经网络进行特征提取

如果使用两个神经网络分别对图片进行特征提取,提取到的特征很有可能不在一个域中,此时我们可以考虑使用一个神经网络进行特征提取再进行比较。这个时候我们就可以理解孪生神经网络为什么要进行权值共享了。

孪生神经网络有两个输入(Input1 and Input2),利用神经网络将输入映射到新的空间,形成输入在新的空间中的表示。通过Loss的计算,评价两个输入的相似度。

代码下载

https://github.com/bubbliiiing/Siamese-tf2

孪生神经网络的实现思路

一、预测部分

1、主干网络介绍


孪生神经网络的主干特征提取网络的功能是进行特征提取,各种神经网络都可以适用,本文使用的神经网络是VGG16。
关于VGG的介绍大家可以看我的另外一篇博客https://blog.csdn.net/weixin_44791964/article/details/102779878

这是一个VGG被用到烂的图,但确实很好的反应了VGG的结构:
1、一张原始图片被resize到指定大小,本文使用105x105。
2、conv1包括两次[3,3]卷积网络,一次2X2最大池化,输出的特征层为64通道。
3、conv2包括两次[3,3]卷积网络,一次2X2最大池化,输出的特征层为128通道。
4、conv3包括三次[3,3]卷积网络,一次2X2最大池化,输出的特征层为256通道。
5、conv4包括三次[3,3]卷积网络,一次2X2最大池化,输出的特征层为512通道。
6、conv5包括三次[3,3]卷积网络,一次2X2最大池化,输出的特征层为512通道。

实现代码为:

import os
import numpy as np
from tensorflow.keras.layers import Input,Dense,Conv2D
from tensorflow.keras.layers import MaxPooling2D,Flatten,Lambda
from tensorflow.keras.models import Model
from PIL import Imageclass VGG16:def __init__(self):self.block1_conv1 = Conv2D(64,(3,3),activation = 'relu',padding = 'same',name = 'block1_conv1')self.block1_conv2 = Conv2D(64,(3,3),activation = 'relu',padding = 'same', name = 'block1_conv2')self.block1_pool = MaxPooling2D((2,2), strides = (2,2), name = 'block1_pool')self.block2_conv1 = Conv2D(128,(3,3),activation = 'relu',padding = 'same',name = 'block2_conv1')self.block2_conv2 = Conv2D(128,(3,3),activation = 'relu',padding = 'same',name = 'block2_conv2')self.block2_pool = MaxPooling2D((2,2),strides = (2,2),name = 'block2_pool')self.block3_conv1 = Conv2D(256,(3,3),activation = 'relu',padding = 'same',name = 'block3_conv1')self.block3_conv2 = Conv2D(256,(3,3),activation = 'relu',padding = 'same',name = 'block3_conv2')self.block3_conv3 = Conv2D(256,(3,3),activation = 'relu',padding = 'same',name = 'block3_conv3')self.block3_pool = MaxPooling2D((2,2),strides = (2,2),name = 'block3_pool')self.block4_conv1 = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block4_conv1')self.block4_conv2 = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block4_conv2')self.block4_conv3 = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block4_conv3')self.block4_pool = MaxPooling2D((2,2),strides = (2,2),name = 'block4_pool')# 第五个卷积部分self.block5_conv1 = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block5_conv1')self.block5_conv2 = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block5_conv2')self.block5_conv3 = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block5_conv3')   self.block5_pool = MaxPooling2D((2,2),strides = (2,2),name = 'block5_pool')self.flatten = Flatten(name = 'flatten')def call(self, inputs):x = inputsx = self.block1_conv1(x)x = self.block1_conv2(x)x = self.block1_pool(x)x = self.block2_conv1(x)x = self.block2_conv2(x)x = self.block2_pool(x)x = self.block3_conv1(x)x = self.block3_conv2(x)x = self.block3_conv3(x)x = self.block3_pool(x)x = self.block4_conv1(x)x = self.block4_conv2(x)x = self.block4_conv3(x)x = self.block4_pool(x)x = self.block5_conv1(x)x = self.block5_conv2(x)x = self.block5_conv3(x)x = self.block5_pool(x)outputs = self.flatten(x)return outputs

2、比较网络


在获得主干特征提取网络之后,我们可以获取到一个多维特征,我们可以使用flatten的方式将其平铺到一维上,这个时候我们就可以获得两个输入的一维向量了

将这两个一维向量进行相减,再进行绝对值求和,相当于求取了两个特征向量插值的L1范数。也就相当于求取了两个一维向量的距离。

然后对这个距离再进行两次全连接,第二次全连接到一个神经元上,对这个神经元的结果取sigmoid,使其值在0-1之间,代表两个输入图片的相似程度。

实现代码如下:

import os
import numpy as np
import tensorflow.keras.backend as K
from PIL import Image
from nets.vgg import VGG16
from tensorflow.keras.layers import Input,Dense,Conv2D
from tensorflow.keras.layers import MaxPooling2D,Flatten,Lambda
from tensorflow.keras.models import Modeldef siamese(input_shape):vgg_model = VGG16()input_image_1 = Input(shape=input_shape)input_image_2 = Input(shape=input_shape)encoded_image_1 = vgg_model.call(input_image_1)encoded_image_2 = vgg_model.call(input_image_2)l1_distance_layer = Lambda(lambda tensors: K.abs(tensors[0] - tensors[1]))l1_distance = l1_distance_layer([encoded_image_1, encoded_image_2])out = Dense(512,activation='relu')(l1_distance)out = Dense(1,activation='sigmoid')(out)model = Model([input_image_1,input_image_2],out)return model

二、训练部分

1、数据集的格式

本文所使用的数据集为Omniglot数据集。
其包含来自 50不同字母(语言)的1623 个不同手写字符。每一个字符都是由 20个不同的人通过亚马逊的 Mechanical Turk 在线绘制的。

相当于每一个字符有20张图片,然后存在1623个不同的手写字符,我们需要利用神经网络进行学习,去区分这1623个不同的手写字符,比较输入进来的字符的相似性。

本博客中数据存放格式有三级:

- image_background- Alphabet_of_the_Magi- character01- 0709_01.png- 0709_02.png- ……- character02- character03- ……- Anglo-Saxon_Futhorc- ……

最后一级的文件夹用于分辨不同的字体,同一个文件夹里面的图片属于同一文字。在不同文件夹里面存放的图片属于不同文字。


上两个图为.\images_background\Alphabet_of_the_Magi\character01里的两幅图。它们两个属于同一个字。

上一个图为.\images_background\Alphabet_of_the_Magi\character02里的一幅图。它和上面另两幅图不属于同一个字。

2、Loss计算

对于孪生神经网络而言,其具有两个输入。

当两个输入指向同一个类型的图片时,此时标签为1。

当两个输入指向不同类型的图片时,此时标签为0。

然后将网络的输出结果和真实标签进行交叉熵运算,就可以作为最终的loss了。

本文所使用的Loss为binary_crossentropy。

当我们输入如下两个字体的时候,我们希望网络的输出为1。


我们会将预测结果和1求交叉熵。

当我们输入如下两个字体的时候,我们希望网络的输出为0。


我们会将预测结果和0求交叉熵。

训练自己的孪生神经网络

1、训练本文所使用的Omniglot例子


下载数据集,放在根目录下的dataset文件夹下。

运行train.py开始训练。

2、训练自己相似性比较的模型

如果大家想要训练自己的数据集,可以将数据集按照如下格式进行摆放。

每一个chapter里面放同类型的图片。
之后将train.py当中的train_own_data设置成True,即可开始训练。

神经网络学习小记录53——TF2搭建孪生神经网络(Siamese network)比较图片相似性相关推荐

  1. 神经网络学习小记录52——Pytorch搭建孪生神经网络(Siamese network)比较图片相似性

    神经网络学习小记录52--Pytorch搭建孪生神经网络(Siamese network)比较图片相似性 学习前言 什么是孪生神经网络 代码下载 孪生神经网络的实现思路 一.预测部分 1.主干网络介绍 ...

  2. 神经网络学习小记录50——Pytorch 利用efficientnet系列模型搭建yolov3目标检测平台

    神经网络学习小记录50--Pytorch 利用efficientnet系列模型搭建yolov3目标检测平台 学习前言 什么是EfficientNet模型 源码下载 EfficientNet模型的实现思 ...

  3. 神经网络学习小记录26——Keras 利用efficientnet系列模型搭建yolov3目标检测平台

    神经网络学习小记录26--Keras 利用efficientnet系列模型搭建efficientnet-yolov3目标检测平台 学习前言 什么是EfficientNet模型 源码下载 Efficie ...

  4. 神经网络学习小记录-番外篇——常见问题汇总

    神经网络学习小记录-番外篇--常见问题汇总 前言 问题汇总 1.下载问题 a.代码下载 b. 权值下载 c. 数据集下载 2.环境配置问题 a.20系列所用的环境 b.30系列显卡环境配置 c.CPU ...

  5. 神经网络学习小记录2——利用tensorflow构建循环神经网络(RNN)

    神经网络学习小记录2--利用tensorflow构建循环神经网络(RNN) 学习前言 RNN简介 tensorflow中RNN的相关函数 tf.nn.rnn_cell.BasicLSTMCell tf ...

  6. 神经网络学习小记录45——Keras常用学习率下降方式汇总

    神经网络学习小记录45--Keras常用学习率下降方式汇总 2020年5月19日更新 前言 为什么要调控学习率 下降方式汇总 1.阶层性下降 2.指数型下降 3.余弦退火衰减 4.余弦退火衰减更新版 ...

  7. 神经网络学习小记录58——Keras GhostNet模型的复现详解

    神经网络学习小记录58--Keras GhostNet模型的复现详解 学习前言 什么是GhostNet模型 源码下载 GhostNet模型的实现思路 1.Ghost Module 2.Ghost Bo ...

  8. 神经网络学习小记录39——MobileNetV3(small)模型的复现详解

    神经网络学习小记录39--MobileNetV3(small)模型的复现详解 学习前言 什么是MobileNetV3 代码下载 large与small的区别 MobileNetV3(small)的网络 ...

  9. 神经网络学习小记录19——微调VGG分类模型训练自己的数据(猫狗数据集)

    神经网络学习小记录19--微调VGG分类模型训练自己的数据(猫狗数据集) 注意事项 学习前言 什么是VGG16模型 VGG模型的复杂程度 训练前准备 1.数据集处理 2.创建Keras的VGG模型 3 ...

  10. 神经网络学习小记录17——使用AlexNet分类模型训练自己的数据(猫狗数据集)

    神经网络学习小记录17--使用AlexNet分类模型训练自己的数据(猫狗数据集) 学习前言 什么是AlexNet模型 训练前准备 1.数据集处理 2.创建Keras的AlexNet模型 开始训练 1. ...

最新文章

  1. 独家 | 盘点9个适用所有学科的R数据可视化包(附链接)
  2. Microsoft SharePoint Portal Server 2003 订制开发研讨(流水帐)
  3. DM8 jdbc调用存储过程传参list<实体类>
  4. 记录一个SpringBoot集成邮件及工具类博客
  5. Vsphere初试——基本安装
  6. 跳打开hdu 1208 (DP)
  7. 利用PDF.JS插件解决了本地pdf文件在线浏览问题(根据需要隐藏下载功能,只保留打印功能)
  8. 字符数组中查找字符串或字符数组
  9. 个人对回调函数的理解(personal understanding of callback function)
  10. word文档总让正文与目录分开在不同的页——分页符的使用
  11. 任务悬赏APP系统源码-活动营销三级分销返佣积分商城版
  12. Keil5编译环境搭建流程----STM32和GD32
  13. android fastboot模式,fastboot
  14. 697小说源码PC端+手机端+采集工具(源码带3000本小说的数据)
  15. Wechart 饼图
  16. 使用css实现产品分类,DIV+CSS实现京东商城分类适合所有版本
  17. ICA算法的数学原理
  18. 【渝粤题库】陕西师范大学165104 组织行为学原理 作业(高起专)
  19. C语言求阶乘尾数零的个数
  20. httpclient用法大全

热门文章

  1. SLAM机器人开发(一)系统框图
  2. linux下R及Rstudio及Rhadoop安装
  3. 史上最全的统计学基础知识!错过这次再等一年!!
  4. java-日记本(一)
  5. 二进制转8421bcd码_绝对值编码器当中的格雷码
  6. 牢筑企业安全屏障,护航邮箱使用无忧【网易企业邮箱】
  7. Kaggle Tabular Playground Series - Jan 2022 学习笔记1(数据分析)
  8. List转json 顺序不一致
  9. Android中经纬度与度分秒互转
  10. JAVA对象转Json对象