Python 在Caffe中培训暹罗网络

Python 在Caffe中培训暹罗网络,python,c++,image-processing,deep-learning,caffe,Python,C++,Image Processing,Deep Learning,Caffe,我正试图建立一个暹罗网络来比较两个图像样本。我以MNIST为例 我试图做的不是使用完全连接的层,而是完全卷积的暹罗网络。我这样做只是为了学习和理解深度学习 我创建了自己的自定义网络,该网络采用32x32大小的RGB图像补丁,并在所附Prototxt文件中定义的网络的多个层中运行。注意:为了简短起见,我删除了网络的另一半,它只是一个镜像。我还试图学习如何在卷积层中使用填充,所以我在这里的示例中也在尝试。您将看到我在conv3层上添加了一个1填充 label1和label2是相同的,所以我使用静默层

我正试图建立一个暹罗网络来比较两个图像样本。我以MNIST为例

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

我创建了自己的自定义网络,该网络采用
32x32
大小的RGB图像补丁,并在所附Prototxt文件中定义的网络的多个层中运行。注意:为了简短起见,我删除了网络的另一半,它只是一个镜像。我还试图学习如何在卷积层中使用填充,所以我在这里的示例中也在尝试。您将看到我在
conv3
层上添加了一个1填充

label1
label2
是相同的,所以我使用静默层来阻止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规范化层,但我支持通过设置
    alpha=1
    beta=0.5
    来做同样的事情
  • 在我的网络中,我只是将
    conv4
    层平均化,并使用它来计算损失。这行得通吗,或者我需要规范化conv4的输出,或者我在这里做了一些完全错误的事情
  • 卷积层的输出能直接输入损耗函数吗

  • 如果你能帮我指明正确的方向,我将不胜感激。此外,我正在使用一些细胞的大约50K补丁的样本图像,这些图像由于分类而无法发布。补丁大小约为
    25x25
    ,因此我将其调整为
    32x32
    是的,可以安全地将填充添加到conv层。我认为您可以按照文档中描述的方式使用LRN层进行L2规范化。是的,CNN层的输出可以直接用于损耗函数,这没什么错,它只是一个blob。在完全卷积网络中,情况总是如此。至少在理论上,您的输出不需要受到限制,对比损失才能发挥作用,因为它是基于利润的损失。通常,将对比损失更改为具有softmax损失的二元分类问题通常是可行的,并且没有规范化问题

    感谢@Bharat的回复。所以我可以输入CNN的输出而不需要任何标准化,它应该可以工作吗?我不了解softmax,因为我认为softmax用于概率输出?最后,关于caffe中的LRN层,有两个选项跨通道和通道内,在我的情况下,我需要右内?应该在通道内。是的,即使没有标准化,它也可以工作,但它不能保证工作。softmax除了提供概率输出外,还具有一些很好的特性,有助于训练过程。它处理了在训练神经网络时发生的大多数规范化问题。