基于深度学习的图像匹配技术专题- [patch based matching3]-mnist siamese 学习

我们想要复盘 matchNet的实验,可能需要从 mnist siamese example 入手。

note: 这种网络是 共享权重的,使用对比的loss function.

1.数据准备。

./data/mnist/get_mnist.sh
./examples/siamese/create_mnist_siamese.sh
打开creat_mnist_siamese文件
#!/usr/bin/env sh
# This script converts the mnist data into leveldb format.
set -e

EXAMPLES=./build/examples/siamese
DATA=./data/mnist

echo "Creating leveldb..."

rm -rf ./examples/siamese/mnist_siamese_train_leveldb   //删除trian 和 test数据集。
rm -rf ./examples/siamese/mnist_siamese_test_leveldb

$EXAMPLES/convert_mnist_siamese_data.bin \
    $DATA/train-images-idx3-ubyte \
    $DATA/train-labels-idx1-ubyte \
    ./examples/siamese/mnist_siamese_train_leveldb
$EXAMPLES/convert_mnist_siamese_data.bin \
    $DATA/t10k-images-idx3-ubyte \
    $DATA/t10k-labels-idx1-ubyte \
    ./examples/siamese/mnist_siamese_test_leveldb

echo "Done."
———————————————————————————网络模型——————————————————————————————————

2.修改Lenet网络模型

网络模型在这个文件中,./examples/siamese/mnist_siamese.prototxt

这个模型是:输入-卷积层/pooling+卷积层/pooling+ Innerproduct /Relu+ Innerproduct+Innerproduct-输出 (就是常说的全连接层)

可以看到第二个 inner product, “feature”层输出两维数组 (这就是模型改变的地方)。

layer {
  name: "feat"
  type: "InnerProduct"
  bottom: "ip2"
  top: "feat"
  param {
    name: "feat_w"
    lr_mult: 1
  }
  param {
    name: "feat_b"
    lr_mult: 2
  }
  inner_product_param {
    num_output: 2
  }
}


3.建立siameses 网络

首先,我们要完成文件mnist_siamese_train_test.prototxt,即编写共生网络结构。

输入数据

Data层输入可以是LMDB和LevelDB格式的数据,这种格式的数据可以通过参照$CAFFE_ROOT/examples/siamese/create_mnist_siamese.sh来生成(该脚本是从MNIST原先的格式生成DB文件,如果要从JPEG格式的图片来生成DB文件,需要进行一定的修改)。Data层有2个输出,一个是pair_data,表示配对好的图片对;另一个是sim,表示图片对是否属于同一个label。可以在本文最后的网络结构图中看到,sim进入loss function, pair_data在卷积层学习。

基于深度学习的图像匹配技术专题- [patch based matching3]-mnist siamese 学习_第1张图片

layer {
  name: "pair_data"
  type: "Data"
  top: "pair_data"
  top: "sim"
  include { phase: TRAIN }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "examples/siamese/mnist_siamese_train_leveldb"
    batch_size: 64
  }
}

slice_pair

Slice层是Caffe中的一个工具层,功能就是把输入的层(bottom)切分成几个输出层(top)。官网给出解释:

We want to be able to work with these two images separately,so we add a slice layer after the data layer. This takes the pair_data andslices it along the channel dimension so that we have a single image in dataand its paired image in data_p.

在pair_data层后面加入 slice_layer 是为了或的分离的图片(相对与图片对)。

data_p和data中数据的关系是什么样的呢?

layer {
  name: "slice_pair"
  type: "Slice"
  bottom: "pair_data"
  top: "data"   //这里把pair_data数据切分成data和data_p
  top: "data_p"
  slice_param {
    slice_dim: 1    //axis表示划分的维度,这里1表示在第二个维度上划分
    slice_point: 1  //划分中间点,在1-2层
siameses网络

网络分为两部分,他们的结构是一样的:the first side和the second side。这个网络的写法,没有什么特殊之处,就是把前一层和后一层(bottom)写清楚就可以了。从slice_pair出来以后,两边的结构是一样的,名字上,second side多了一个p.

param { name: "conv1_w" ...  }
param { name: "conv1_b" ...  }
...
param { name: "conv2_w" ...  }
param { name: "conv2_b" ...  }
...
param { name: "ip1_w" ...  }
param { name: "ip1_b" ...  }
...
param { name: "ip2_w" ...  }
param { name: "ip2_b" ...  }

关于共享参数

siamese中的共享参数很简单,在每路中对应的层里面都定义一个同名的参数,这样更新参数的时候就可以共享参数了。如下面的例子:

layer {
  name: "ip2"
  type: "InnerProduct"
  bottom: "ip1"
  top: "ip2"
  param {
    name: "ip2_w"    //这里的ip2_w 在ip2_p中也是出现的,就能实现公用权重。
    lr_mult: 1
  }
  param {
    name: "ip2_b"
    lr_mult: 2
  }
  inner_product_param {
    num_output: 10
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
基于深度学习的图像匹配技术专题- [patch based matching3]-mnist siamese 学习_第2张图片
  
在卷积层 之后使用了两次全连接层(ip1,ip2),然后用了 feature layer, 这个全连接层输出2维向量。

基于深度学习的图像匹配技术专题- [patch based matching3]-mnist siamese 学习_第3张图片

损失函数

在两个feature产生后,就可以利用2个feature和前面定义的sim来计算loss了。Siamese网络采用了一个叫做“ContrastiveLoss”的loss计算方式,如果两个图片越相似,则loss越小;如果越不相似,则loss越大。

基于深度学习的图像匹配技术专题- [patch based matching3]-mnist siamese 学习_第4张图片

这个函数在LeCun的论文中有介绍,the contrastive lose function [Raia Hadsell, Sumit Chopra, and Yann LeCun “Dimensionality Reduction by Learningan Invariant Mapping]. 这个损失函数我不太了解CONTRASTIVE_LOSS layer:

layer {
    name: "loss"
    type: "ContrastiveLoss"
    contrastive_loss_param {
        margin: 1.0
    }
    bottom: "feat"
    bottom: "feat_p"
    bottom: "sim"    //3个输入的数据
    top: "loss"
}
——————————————————————————————网络的模型——————————————————————

slover的数据在这个文件中r、./examples/siamese/mnist_siamese_solver.prototxt.

net: "examples/siamese/mnist_siamese_train_test.prototxt"
# test_iter specifies how many forward passes the test should carry out.
# In the case of MNIST, we have test batch size 100 and 100 test iterations,
# covering the full 10,000 testing images.
test_iter: 100
# Carry out testing every 500 training iterations.
test_interval: 500
# The base learning rate, momentum and the weight decay of the network.
base_lr: 0.01
momentum: 0.9
weight_decay: 0.0000
# The learning rate policy
lr_policy: "inv"
gamma: 0.0001
power: 0.75
# Display every 100 iterations
display: 100
# The maximum number of iterations
max_iter: 50000
# snapshot intermediate results
snapshot: 5000
snapshot_prefix: "examples/siamese/mnist_siamese"
# solver mode: CPU or GPU
solver_mode: GPU


基于深度学习的图像匹配技术专题- [patch based matching3]-mnist siamese 学习_第5张图片最后可以 使用工具,把网络结构画出来,上面已经分层介绍了,最下方是一个全局图。

./python/draw_net.py \
    ./examples/siamese/mnist_siamese.prototxt \
    ./examples/siamese/mnist_siamese.png

./python/draw_net.py \
    ./examples/siamese/mnist_siamese_train_test.prototxt \
    ./examples/siamese/mnist_siamese_train_test.png



————————————————————————————————————————————————————————

希望对你有帮助,你的资助会让我,更有动力:)


你可能感兴趣的:(Deep,Learning,matchNet)