日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 神经网络学习小记录53——TF2搭建孪生神经网络(Siamese network)比较图片相似性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

神經網絡學習小記錄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)比较图片相似性的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。