我正在尝试加载预训练的网络,但出现以下错误
F1101 23:03:41.857909 73 net.cpp:757]无法复制参数0的权重 来自图层“ fc4”;形状不匹配。源参数形状为5124096 (2097152);目标参数形状为512 256 4 4(2097152)。要学习这个 层的参数从头开始,而不是从保存的网络中复制, 重命名图层。
我注意到512 x 256 x 4 x 4 == 512 x 4096,所以看来在保存和重新加载网络权重时,层以某种方式变平了。
如何解决此错误?
我正在尝试在this GitHub repository中使用D-CNN预训练网络。
我用
加载网络import caffe
net = caffe.Net('deploy_D-CNN.prototxt', 'D-CNN.caffemodel', caffe.TEST)
prototxt文件是
name: "D-CNN"
input: "data"
input_dim: 10
input_dim: 3
input_dim: 259
input_dim: 259
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
convolution_param {
num_output: 64
kernel_size: 5
stride: 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"
convolution_param {
num_output: 128
pad: 1
kernel_size: 3
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "conv2"
top: "conv2"
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "conv3"
type: "Convolution"
bottom: "pool2"
top: "conv3"
convolution_param {
num_output: 256
pad: 1
kernel_size: 3
stride: 1
}
}
layer {
name: "relu3"
type: "ReLU"
bottom: "conv3"
top: "conv3"
}
layer {
name: "fc4"
type: "Convolution"
bottom: "conv3"
top: "fc4"
convolution_param {
num_output: 512
pad: 0
kernel_size: 4
}
}
layer {
name: "relu4"
type: "ReLU"
bottom: "fc4"
top: "fc4"
}
layer {
name: "drop4"
type: "Dropout"
bottom: "fc4"
top: "fc4"
dropout_param {
dropout_ratio: 0.5
}
}
layer {
name: "pool5_spm3"
type: "Pooling"
bottom: "fc4"
top: "pool5_spm3"
pooling_param {
pool: MAX
kernel_size: 10
stride: 10
}
}
layer {
name: "pool5_spm3_flatten"
type: "Flatten"
bottom: "pool5_spm3"
top: "pool5_spm3_flatten"
}
layer {
name: "pool5_spm2"
type: "Pooling"
bottom: "fc4"
top: "pool5_spm2"
pooling_param {
pool: MAX
kernel_size: 14
stride: 14
}
}
layer {
name: "pool5_spm2_flatten"
type: "Flatten"
bottom: "pool5_spm2"
top: "pool5_spm2_flatten"
}
layer {
name: "pool5_spm1"
type: "Pooling"
bottom: "fc4"
top: "pool5_spm1"
pooling_param {
pool: MAX
kernel_size: 29
stride: 29
}
}
layer {
name: "pool5_spm1_flatten"
type: "Flatten"
bottom: "pool5_spm1"
top: "pool5_spm1_flatten"
}
layer {
name: "pool5_spm"
type: "Concat"
bottom: "pool5_spm1_flatten"
bottom: "pool5_spm2_flatten"
bottom: "pool5_spm3_flatten"
top: "pool5_spm"
concat_param {
concat_dim: 1
}
}
layer {
name: "fc4_2"
type: "InnerProduct"
bottom: "pool5_spm"
top: "fc4_2"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
inner_product_param {
num_output: 512
weight_filler {
type: "gaussian"
std: 0.005
}
bias_filler {
type: "constant"
value: 0.1
}
}
}
layer {
name: "relu4"
type: "ReLU"
bottom: "fc4_2"
top: "fc4_2"
}
layer {
name: "drop4"
type: "Dropout"
bottom: "fc4_2"
top: "fc4_2"
dropout_param {
dropout_ratio: 0.5
}
}
layer {
name: "fc5"
type: "InnerProduct"
bottom: "fc4_2"
top: "fc5"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
inner_product_param {
num_output: 19
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
name: "prob"
type: "Softmax"
bottom: "fc5"
top: "prob"
}
答案 0 :(得分:3)
似乎您正在使用预训练的网络,其中"fc4"
层是完全连接的层(也称为type: "InnerProduct"
层),并且已“重塑”为卷积层。
由于内积层和卷积层都对输入执行大致相同的线性运算,因此可以在某些假设下进行此更改(例如,参见here)。
正如您已经正确确定的那样,原始的经过预训练的完全连接层的权重已“平整”保存,而不会像caffe所期望的那样是卷积层。
我认为可以使用share_mode: PERMISSIVE
解决此问题:
layer {
name: "fc4"
type: "Convolution"
bottom: "conv3"
top: "fc4"
convolution_param {
num_output: 512
pad: 0
kernel_size: 4
}
param {
lr_mult: 1
decay_mult: 1
share_mode: PERMISSIVE # should help caffe overcome the shape mismatch
}
param {
lr_mult: 2
decay_mult: 0
share_mode: PERMISSIVE
}
}