我正在尝试构建一个用于比较两个图像样本的连体网络 . 我跟着caffe中的MNIST示例 .
我想要做的是不使用完全连接的层,而是使用完全卷积连体网络 . 我这样做是为了学习和理解深度学习 .
我创建了自己的自定义网络,它采用 32 x 32
大小的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-Normalization层,但我支持LRN可以通过设置
alpha = 1
和beta = 0.5
来做同样的事情 . -
在我的网络中,我只是平均汇集
conv4
图层并使用它来计算使用ContrastiveLoss的损失 . 可以,或者我需要规范化conv4
的输出,或者我在这里做了一些完全错误的事情 . -
卷积层的输出可以直接输入损失函数吗?
我非常感谢你帮助向我展示正确的方向 . 此外,我正在使用大约50K补丁的一些细胞的样本图像,因为它被分类,我无法发布 . 补丁大小约为 25x25
所以我调整大小为 32x32
1 回答
是的,向conv层添加填充是安全的 . 我认为您可以按照文档中描述的方式使用LRN层进行L2规范化 . 是的,CNN层的输出可以直接用于损失函数,没有错,它只是一个blob . 在完全卷积网络中,情况总是如此 . 至少从理论上讲,您的输出不需要受到对比损失的约束,因为它是基于保证金的损失 . 通常,将对比损失改变为具有softmax损失的二元分类问题通常是有效的,并且没有归一化问题 .