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

How to Implement CaffeNet on Keras with pretrained weight from Caffe

我想在 keras 上实现 caffeNet,并在 imagenet 上进行预训练。所以我从那里的咖啡 github 得到了重量 https://github.com/BVLC/caffe/tree/master/models/bvlc_reference_caffenet

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

我从 看到那是因为在层 "conv2" 中分成了 2 组。请问keras可以把conv层拆分成group吗?或者有什么解决方案可以让我在 keras 上获得预训练的 caffeNet?

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

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

@keineahnung2345 我不能 post 评论中的代码太长了所以我 post 在新的答案中。

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)