如何使用来自Caffe的预训练重量在Keras上实现CaffeNet

时间:2019-01-05 22:26:20

标签: keras deep-learning caffe

我想在imagenet上进行预培训,从而在keras上实现caffeNet。所以我在那里得到了来自caffe github的重量 ring mesh

我使用caffe_weight_converter将其转换为weight.h5。我在“ conv2”层上获得的重量具有形状(256,48,5,5),但我的工具模型需要(256,96,5,5)。

我从https://github.com/BVLC/caffe/tree/master/models/bvlc_reference_caffenet中看到,这是因为在“ conv2”层中分成了2组。我想问问,keras可以将conv图层拆分为分组吗?或有什么解决方案可以使我在keras上获得预训练的caffeNet?

2 个答案:

答案 0 :(得分:0)

我尝试实现CaffeNet的下部(省略了LN层):

A = Input((277,277,3))
B = Convolution2D(filters=96, kernel_size=(11,11), strides=(4,4), activation='relu')(A)
C = MaxPooling2D(pool_size=(3,3), strides=(2,2))(B)
D1 = Lambda(lambda x: x[:,:,:,:48])(C)
D2 = Lambda(lambda x: x[:,:,:,48:])(C)
E = Concatenate()([D1,D2])
F = Convolution2D(filters=256, kernel_size=(5,5), padding="same")(E)
model = Model(A,F)

参考:Caffe Convolution "Group" parameter conversion to Keras Conv2D

Splitting the output of a layer over the channels

答案 1 :(得分:0)

@ keineahnung2345我无法在评论中发布代码,因为评论太长了,所以我发布了新答案。

model_input= Input((227,227,3))
#conv1
x=Conv2D(filters=96, kernel_size=(11,11), strides=(4,4), name="conv1",activation="relu")(model_input)
x=MaxPooling2D(pool_size=(3,3), strides=(2,2), name="pool1")(x)
x=BatchNormalization()(x)

#conv2
x=ZeroPadding2D((2, 2))(x)
con2_split1 = Lambda(lambda z: z[:,:,:,:48])(x)
con2_split2 = Lambda(lambda z: z[:,:,:,48:])(x)
a=x=Concatenate(axis=0)([con2_split1, con2_split2])
x=Conv2D(filters=256, kernel_size=(5,5), strides=(1,1), name="conv2",activation="relu")(x)
x=MaxPooling2D(pool_size=(3,3), strides=(2,2), name="pool2")(x)
x=BatchNormalization()(x)

#conv3
x= ZeroPadding2D((1, 1))(x)
x=Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), name="conv3",activation="relu")(x)

#conv4
x= ZeroPadding2D((1, 1))(x)
con4_split1 = Lambda(lambda z: z[:,:,:,:192])(x)
con4_split2 = Lambda(lambda z: z[:,:,:,192:])(x)
x=Concatenate(axis=0)([con4_split1, con4_split2])
x=Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), name="conv4",activation="relu")(x)

#con5
x= ZeroPadding2D((1, 1))(x)
con5_split1 = Lambda(lambda z: z[:,:,:,:192])(x)
con5_split2 = Lambda(lambda z: z[:,:,:,192:])(x)
x=Concatenate(axis=0)([con5_split1, con5_split2])
x=Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), name="conv5",activation="relu")(x)
#pool5
x=MaxPooling2D(pool_size=(3,3), strides=(2,2), name="pool5")(x)
x=Flatten()(x)

#fc6
x=Dense(4096,activation='relu',name="fc6")(x)
#dropout6
x=Dropout(0.5,name="droupout6")(x)
#fc7
x=Dense(4096,activation='relu',name="fc7")(x)
#dropout7
x=Dropout(0.5,name="droupout7")(x)
#fc8
x=Dense(1000,activation='softmax',name="fc8")(x)
model=Model(inputs=model_input, outputs=x)
model.summary()
model.load_weights("caffeNet_kerasWeight.h5",by_name=True)