我们想要复盘 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在卷积层学习。
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)。官网给出解释:
pair_data
andslices it along the channel dimension so that we have a single image in
data
and its paired image in
data_p.
在pair_data层后面加入 slice_layer 是为了或的分离的图片(相对与图片对)。
data_p和data中数据的关系是什么样的呢?
siameses网络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层
网络分为两部分,他们的结构是一样的: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"
}
}
}
在两个feature产生后,就可以利用2个feature和前面定义的sim
来计算loss了。Siamese网络采用了一个叫做“ContrastiveLoss”的loss计算方式,如果两个图片越相似,则loss越小;如果越不相似,则loss越大。
这个函数在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
最后可以 使用工具,把网络结构画出来,上面已经分层介绍了,最下方是一个全局图。
./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
————————————————————————————————————————————————————————
希望对你有帮助,你的资助会让我,更有动力:)