【问题标题】:Training Siamese Network in Caffe在 Caffe 中训练连体网络
【发布时间】:2017-09-07 05:24:58
【问题描述】:

我正在尝试建立一个连体网络来比较两个图像样本。我遵循了caffe 中的 MNIST 示例。

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

我创建了自己的自定义网络,它采用32 x 32 大小的 RGB 图像补丁,并通过附加的 Prototxt 文件中定义的网络的多个层运行。请注意保持简短,我删除了网络的另一半,它只是一个镜像。此外,我正在尝试学习如何在卷积层中使用填充,因此我也在此处的示例中尝试这样做。你会看到我在conv3 层上放置了一个 1 的填充。

label1label2 相同,所以我使用静默层来阻止 label2

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 
    }
}

我对以下几点感到困惑:

  1. 在卷积层上添加填充是否安全,还是会产生破坏性影响?
  2. 在我读到的siamaese network的一些论文中,他们在全连接层之后使用了L2-Normalization。我没有在 caffe 上找到任何 L2-Normalization 层,但我支持 LRN 可以通过设置 alpha = 1beta = 0.5 来做同样的事情。
  3. 在我的网络中,我只是平均汇集了conv4 层,并使用它来计算使用ContrastiveLoss 的损失。这可以工作吗,或者我需要标准化conv4 的输出,或者我在这里做错了什么。
  4. 卷积层的输出可以直接输入损失函数吗?

非常感谢您帮助我指明正确的方向。此外,我正在使用一些细胞的大约 50K 块的样本图像,因为它是分类的,所以我无法发布。补丁大小约为25x25,所以我调整为32x32

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 感谢@Bharat 的回复。所以我可以在没有任何标准化的情况下输入 CNN 的输出,它应该可以工作吗?我不了解softmax,因为我认为softmax 是用于概率输出?最后关于 caffe 中的 LRN 层,有两个选项 ACROSS 和 WITHIN CHANNEL,在我的情况下我需要 WITHIN 对吗?
    • 应该在里面。是的,即使没有规范化它也可以工作,但不能保证工作。 softmax 除了给出概率输出外,还具有一些有助于训练过程的好特性。它解决了训练神经网络中发生的大部分归一化问题。
    最近更新 更多