Caffe学习笔记系列4—基于改进的Saimese网络的模型训练和特征提取
本小节主要讲解改进的Siamese网络的模型训练,其实也算不上改进,主要讲的还是如何准备改进的Siamese网络的数据准备,对于特征提取部分则不再介绍,跟前面的方法雷同。所谓的改进是在传统的Siamese网络的对比损失函数中添加softmax损失,及损失函数是对比损失和softmax损失的权重和。对于改进的Siamese网络模型文件,本小节主要讲将Caffe里面的Siamese网络进行改进,添加softmax损失函数,本部分也是针对该模型操作。首先感性认识一下添加了softmax损失函数的改进的Siamese网络结构,如下:
图1 改进的Siamese结构
此外,本人也设计了一个改进的Siamese网络文件,在“Caffe学习笔记系列”文件夹—>“CaffeTest4”文件夹—>“MySiameseNet”文件夹中,主要借鉴了ALexNet网络的参数设置,并进行了一些调整,该文件夹加密了的,如果需要的话请私。
但是该节还是针对图1进行讲解。这部分也是比较难的,一方面需要更改Caffe源码,一方面要准备输入数据格式。下面着重讲解这两部分。
一、修改源码
为了实现softmax和contrastive的结合,需要尝试修改caffe源码,包括accuracy_layer.cpp,contrastive_loss_layer.cpp,softmax_loss_layer.cpp等。
即修改三个涉及到label的cpp:
src/caffe/layers/accuracy_layer.cpp,
src/caffe/layers/contrastive_loss_layer.cpp,
src/caffe/layers/softmax_loss_layer.cpp,
修改的细节主要是对应的label处,具体见Caffe工程代码。
二、创建训练用的leveldb
写些代码生成训练和测试leveldb用的两个txt文件,如trainData.txt,valData.txt。生成后的txt内容如下:
Data/0/41_20160503071203/0_1.jpg 0 Data/0/81_20160503071250/0_15.jpg 0
Data/77/41_20160505072228/0_37.jpg 77 Data/56/81_20160505083311/0_23.jpg 56
… …
即每一行都有两个图像的名称和它的label(取值1~93),比如在第一行中,第一个图像名是Data/0/41_20160503071203/0_1.jpg,它的label是0,第二个图像名是Data/77/41_20160505072228/0_37.jpg,它的label是77。
这里Data/0/41_20160503071203/0_1.jpg和Data/0/81_20160503071250/0_15.jpg是相同label的contrastivepair,而Data/77/41_20160505072228/0_37.jpg
和Data/56/81_20160505083311/0_23.jpg是不同label的contrastivepair。如何生成该形式的.txt文件可以参考“CaffeTest4”文件夹下面的“getTrainTxt”工程。
接着,利用trainData.txt和valData.txt生成leveldb,通过“CaffeTest4”文件夹下面的“getSiameseNetFormatLeveled”工程,它读取txt里的信息并生成leveldb,这个工程有个主要的函数是ReadImageToDatum_double(),它是在include/caffe/util/io.hpp定义的(注:仿照已有的函数ReadImageToDatum()自定义的),实现是在src/caffe/util/io.cpp中。
由于使用shuffle方法,所以也修改了include/caffe/util/rng.hpp,即在rng.hpp中添加了template<class RandomAccessIterator, class RandomGenerator> inline voidshuffle_double()函数。
小结,以上为了生成训练用的leveldb,我们修改的caffe源码文件有:
include/caffe/util/io.hpp
src/caffe/util/io.cpp
include/caffe/util/rng.hpp
特别的,我们对于ReadImageToDatum_double()生成leveldb时label的处理如下:
label = 第一张图像的label*100+ 第二张图像的label;
这样的处理是为了:
Softmax层,可以提取出第一张图像的label;
contrastive层,可以提取出第一张和第二张图像的label以判断它们的label是不是相同
注:关于第一张图像乘以的100,如果库里的人数大于100时,应该考虑修改此处label的计算公式。
生成leveldb 格式的数据可以参考“CaffeTest4”文件夹下面的“getSiameseNetFormatLeveled”工程。
三、网络模型训练
具体训练部分不再讲解,模型文件都在“CaffeTest4”。
该系列的代码链接如下:https://pan.baidu.com/s/1Z314A-FJ57wXsaJqbdaAew 密码:g3kv