在Caffe培训Siamese网络

时间:2017-04-11 17:20:27

标签: python c++ image-processing deep-learning caffe

我正在尝试构建一个用于比较两个图像样本的连体网络。我在caffe中跟踪了MNIST示例。

我要做的是不使用完全连接的层,而是使用完全卷积连体网络。我这样做是为了学习和理解深度学习。

我创建了自己的自定义网络,它采用Test03\Test04\Test05\Test06大小的RGB图像补丁,并运行在附加的Prototxt文件中定义的网络的多个层。注意保持简短,我删除了网络的另一半只是一面镜子。此外,我正在尝试学习如何在卷积层中使用填充,所以我也在这里尝试这个。您会看到我在32 x 32图层上填充了1。

conv3label1相同,因此我使用静默图层来阻止label2

label2

我很困惑的事情是:

  1. 在卷积层上添加填充是否安全,还是会产生破坏性影响?
  2. 在我在siamaese网络上阅读的一些论文中,他们在完全连接层之后使用L2标准化。我没有在caffe上找到任何L2-Normalization层,但我支持LRN可以通过设置layer { name: "data1" type: "Data" top: "data1" top: "label" include { phase: TRAIN } data_param { source: "Desktop/training/lmdb/train_1" batch_size: 512 backend: LMDB } } layer { name: "data2" type: "Data" top: "data2" top: "label2" include { phase: TRAIN } data_param { source: "/Desktop/training/lmdb/train_2" batch_size: 512 backend: LMDB } } layer { name: "conv1" type: "Convolution" bottom: "data1" top: "conv1" param { name: "conv1_w" lr_mult: 1 } param { name: "conv1_b" lr_mult: 2 } convolution_param { num_output: 32 pad: 0 kernel_size: 5 stride: 1 weight_filler { type: "xavier" std: 0.03 } bias_filler { type: "constant" value: 0.2 } } } layer { name: "relu1" type: "ReLU" bottom: "conv1" top: "conv1" } layer { name: "pool1" type: "Pooling" bottom: "conv1" top: "pool1" pooling_param { pool: MAX kernel_size: 2 stride: 2 } } layer { name: "norm1" type: "LRN" bottom: "pool1" top: "norm1" lrn_param { local_size: 5 alpha: 0.0001 beta: 0.75 } } layer { name: "conv2" type: "Convolution" bottom: "norm1" top: "conv2" param { name: "conv2_w" lr_mult: 1 } param { name: "conv2_b" lr_mult: 2 } convolution_param { num_output: 64 pad: 0 kernel_size: 1 stride: 1 weight_filler { type: "xavier" std: 0.03 } bias_filler { type: "constant" value: 0.2 } } } layer { name: "relu2" type: "ReLU" bottom: "conv2" top: "conv2" } layer { name: "conv3" type: "Convolution" bottom: "conv2" top: "conv3" param { name: "conv3_w" lr_mult: 1 } param { name: "conv3_b" lr_mult: 2 } convolution_param { num_output: 128 pad: 1 kernel_size: 3 stride: 2 weight_filler { type: "xavier" std: 0.03 } bias_filler { type: "constant" value: 0.2 } } } layer { name: "relu3" type: "ReLU" bottom: "conv3" top: "conv3" } # layer { # name: "dropout" # type: "Dropout" # bottom: "conv3" # top: "dropout" # dropout_param { # dropout_ratio: 0.5 # } # } layer { name: "conv4" type: "Convolution" bottom: "conv3" top: "conv4" param { name: "conv4_w" lr_mult: 1 } param { name: "conv4_b" lr_mult: 2 } convolution_param { num_output: 1 pad: 0 kernel_size: 1 stride: 1 weight_filler { type: "xavier" std: 0.03 } bias_filler { type: "constant" value: 0.2 } } } layer { name: "pool2" type: "Pooling" bottom: "conv4" top: "pool2" pooling_param { pool: AVE kernel_size: 7 stride: 1 } } ################# layer { name: "loss" type: "ContrastiveLoss" bottom: "pool2" bottom: "pool2_p" bottom: "label" top: "loss" contrastive_loss_param { margin: 1 } include { phase: TRAIN } } alpha = 1来做同样的事情。
  3. 在我的网络中,我只是平均汇总了beta = 0.5图层并使用它来计算使用ContrastiveLoss的损失。这可行,或者我需要规范化conv4的输出,或者我在这里做了一些完全错误的事情。
  4. 卷积层的输出可以直接输入损失函数吗?
  5. 我真的很感谢你帮助向我展示正确的方向。此外,我正在使用大约50K补丁的一些细胞的样本图像,因为它被分类,我无法发布。补丁大小约为conv4,因此我调整为25x25

1 个答案:

答案 0 :(得分:2)

是的,向conv层添加填充是安全的。我认为您可以按照文档中描述的方式使用LRN层进行L2规范化。是的,CNN层的输出可以直接用于损失函数,没有错,它只是一个blob。在完全卷积网络中,情况总是如此。至少从理论上讲,您的输出不需要受到对比损失的约束,因为它是基于保证金的损失。通常,将对比损失改变为具有softmax损失的二元分类问题通常是有效的,并且没有归一化问题。