首页 文章

在Caffe培训Siamese网络

提问于
浏览
1

我正在尝试构建一个用于比较两个图像样本的连体网络 . 我跟着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 
    }
}

我很困惑的事情很少:

  • 在卷积层上添加填充是否安全,或者它是否具有破坏性影响?

  • 在我在siamaese网络上阅读的一些论文中,他们在完全连接层之后使用L2标准化 . 我没有在caffe上找到任何L2-Normalization层,但我支持LRN可以通过设置 alpha = 1beta = 0.5 来做同样的事情 .

  • 在我的网络中,我只是平均汇集 conv4 图层并使用它来计算使用ContrastiveLoss的损失 . 可以,或者我需要规范化 conv4 的输出,或者我在这里做了一些完全错误的事情 .

  • 卷积层的输出可以直接输入损失函数吗?

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

1 回答

  • 2

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

相关问题