【发布时间】:2019-02-16 20:50:04
【问题描述】:
我正在尝试将大型 Caffe 网络复制到 Keras(基于 tensorflow 后端)。但是即使在单个卷积层上我也遇到了很大的麻烦。
一般的简单卷积:
假设我们有一个形状为 (1, 500, 500, 3) 的 4D 输入,我们必须使用 96 过滤器对这个输入执行单个卷积,内核大小为 11 和 4x4 步幅。
让我们设置权重和输入变量:
w = np.random.rand(11, 11, 3, 96) # weights 1
b = np.random.rand(96) # weights 2 (bias)
x = np.random.rand(500, 500, 3)
Keras 中的简单卷积:
这就是它在 Keras 中的定义方式:
from keras.layers import Input
from keras.layers import Conv2D
import numpy as np
inp = Input(shape=(500, 500, 3))
conv1 = Conv2D(filters=96, kernel_size=11, strides=(4, 4), activation=keras.activations.relu, padding='valid')(inp)
model = keras.Model(inputs=[inp], outputs=conv1)
model.layers[1].set_weights([w, b]) # set weights for convolutional layer
predicted = model.predict([x.reshape(1, 500, 500, 3)])
print(predicted.reshape(1, 96, 123, 123)) # reshape keras output in the form of Caffe
Caffe 中的简单卷积:
simple.prototxt:
name: "simple"
input: "inp"
input_shape {
dim: 1
dim: 3
dim: 500
dim: 500
}
layer {
name: "conv1"
type: "Convolution"
bottom: "inp"
top: "conv1"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
convolution_param {
num_output: 96
kernel_size: 11
pad: 0
stride: 4
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "conv1"
top: "conv1"
}
Python 中的 Caffe:
import caffe
net = caffe.Net('simple.prototxt', caffe.TEST)
net.params['conv1'][0].data[...] = w.reshape(96, 3, 11, 11) # set weights 1
net.params['conv1'][1].data[...] = b # set weights 2 (bias)
net.blobs['inp'].reshape(1, 3, 500, 500) # reshape input layer to fit our input array x
print(net.forward(inp=x.reshape(1, 3, 500, 500)).get('conv1'))
问题:
如果我们执行两个 sn-ps 代码,我们会注意到输出彼此不同。我知道Caffe的对称填充等差异很少,但我什至没有在这里使用填充。然而 Caffe 的输出与 Keras 的输出不同......
为什么会这样?我知道 Theano 后端没有像 Caffe 那样利用相关性,因此它需要内核旋转 180 度,但对于 tensorflow 是否相同?据我所知,Tensorflow 和 Caffe 都使用互相关而不是卷积。
如何在 Keras 和 Caffe 中制作两个使用卷积的相同模型?
任何帮助将不胜感激,谢谢!
【问题讨论】:
标签: python keras conv-neural-network caffe convolution