Я пытаюсь взять вес из очень простой модели Caffe и интерпретировать ее как полностью функциональную модель Keras.
Это оригинальное определение модели в Caffe, назовем его simple.prototxt
:
input: "im_data"
input_shape {
dim: 1
dim: 3
dim: 1280
dim: 1280
}
layer {
name: "conv1"
type: "Convolution"
bottom: "im_data"
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: 5
stride: 4
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "conv1"
top: "conv1"
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 3
pad: 0
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 {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
convolution_param {
num_output: 256
kernel_size: 5
pad: 2
group: 2
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "conv2"
top: "conv2"
}
Определение слоя в Caffe может выглядеть сложным, но оно просто берет изображение измерений 1280x1280x3
, передает его в сверточный слой, затем максимально объединяет его и передает в последний сверточный слой.
Вот его реализация в Keras , которая намного проще:
from keras.models import Model
from keras.layers import Input, BatchNormalization,
from keras.activations import relu, softmax
im_data = Input(shape=(1280, 1280, 3),
dtype='float32',
name='im_data')
conv1 = Conv2D(filters=96,
kernel_size=11,
strides=(4, 4),
activation=relu,
padding='same',
name='conv1')(im_data)
pooling1 = MaxPooling2D(pool_size=(3, 3),
strides=(2, 2),
padding='same',
name='pooling1')(conv1)
normalized1 = BatchNormalization()(pooling1) # https://stats.stackexchange.com/questions/145768/importance-of-local-response-normalization-in-cnn
conv2 = Conv2D(filters=256,
kernel_size=5,
activation=relu,
padding='same',
name='conv2')(normalized1)
model = Model(inputs=[im_data], outputs=conv2)
Проблема:
Хотя обе модели, кажется, имеютаналогичные параметры в каждом слое, но проблема в том, что их весовые формы не равны .Я знаю, что Caffe имеет другой порядок форм по сравнению с Keras, но порядок здесь не имеет значения.
Проблема в том, что последний слой свертки Keras имеет другое значение в 3-м измерении по сравнению с последним слоем свертки в Caffe.См. Ниже.
Весовые формы для Кафе :
>>> net = caffe.net('simple.prototxt', 'premade_weights.caffemodel', caffe.TEST)
>>> for i in range(len(net.layers)):
... if len(net.layers[i].blobs) != 0: # if layer has no weights
... print(("name", net._layer_names[i]))
... print("weight_shapes", [v.data.shape for v in net.layers[i].blobs])
('name', 'conv1')
('weight_shapes', [(96, 3, 11, 11), (96,)])
('name', 'conv2')
('weight_shapes', [(256, 48, 5, 5), (256,)])
Весовые формы для Керас :
>>> for layer in model.layers:
... if len(layer.get_weights()) != 0:
... print(("name", layer.name))
... print(("weight_shapes", [w.shape for w in layer.get_weights()]))
('name', 'conv1')
('weight_shapes', [(11, 11, 3, 96), (96,)])
('name', 'conv2')
('weight_shapes', [(5, 5, 96, 256), (256,)])
Это кажется странным поведением.Как видите, форма conv1
в Caffe и Keras одинакова (игнорируя порядок).Но в Caffe conv2
форма равна [(256, 48, 5, 5), (256,)])
, тогда как в Keras 'conv2' форма равна [(5, 5, 96, 256), (256,)]
, , обратите внимание , что 48*2=96
.
Кроме того, замечают , что слой conv2
находится непосредственно после слоя максимального пула, поэтому может быть что-то не так с слоем максимального пула в Keras.
Вопрос:
Правильно ли я интерпретировал определение модели от Caffe до Keras?Особенно максимальный уровень пула и его параметры?
Большое спасибо!