将.caffemodel转换为keras h5

我想使用我自己的数据集对在Caffe中训练的性别检测器进行微调。这个模型是使用大约五十万张人脸图像训练的。他们对在ImageNet上预训练的VGG16进行了微调。我想使用这个模型作为我的基础模型。我从以下链接下载了gender.caffemodel文件:

IMDB-Wiki

我使用以下链接提供的工具将此模型转换为在Keras中使用的h5文件:

https://github.com/pierluigiferrari/caffe_weight_converter

这个工具只转换权重。我想使用Keras来训练我的模型。因此,我这样定义VGG-16架构:

tmp_model = Sequential()tmp_model.add(ZeroPadding2D((1,1),input_shape=(224, 224, 3)))tmp_model.add(Convolution2D(64, 3, 3, activation='relu'))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(64, 3, 3, activation='relu'))tmp_model.add(MaxPooling2D((2,2), strides=(2,2)))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(128, 3, 3, activation='relu'))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(128, 3, 3, activation='relu'))tmp_model.add(MaxPooling2D((2,2), strides=(2,2)))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(256, 3, 3, activation='relu'))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(256, 3, 3, activation='relu'))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(256, 3, 3, activation='relu'))tmp_model.add(MaxPooling2D((2,2), strides=(2,2)))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(512, 3, 3, activation='relu'))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(512, 3, 3, activation='relu'))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(512, 3, 3, activation='relu'))tmp_model.add(MaxPooling2D((2,2), strides=(2,2)))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(512, 3, 3, activation='relu'))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(512, 3, 3, activation='relu'))tmp_model.add(ZeroPadding2D((1,1)))tmp_model.add(Convolution2D(512, 3, 3, activation='relu'))tmp_model.add(MaxPooling2D((2,2), strides=(2,2)))tmp_model.add(Flatten())tmp_model.add(Dense(4096, activation='relu'))tmp_model.add(Dropout(0.5))tmp_model.add(Dense(4096, activation='relu'))tmp_model.add(Dropout(0.5))tmp_model.add(Dense(2, activation='softmax'))tmp_model.load_weights('/home/gender.h5')

这段代码成功加载了权重。现在我想使用这个模型的权重来微调另一个网络,用于其他分类任务,类别数量不同。由于tmp_model中的类别数量与新模型不同,我将tmp_model的权重复制到新模型的层中,除了最后一层,即softmax层。新模型的代码与tmp_model完全相同,只是最后一层不同。现在我所做的,是将tmp_model的权重逐层复制到新模型中:

for i, weights in enumerate(weights_list[0:31]):    model.layers[i].set_weights(weights)

问题就出现在这里。当我运行代码时,出现了以下错误:

ValueError: You called `set_weights(weights)` on layer "zero_padding2d_14" with a  weight list of length 3, but the layer was expecting 0 weights. Provided weights: [[[[ 0.27716994  0.05686508  0.0098957  ... -0.055...

正如我所说,tmp_model和model具有完全相同的架构,除了最后一层。这就是为什么我只是复制所有层的权重,除了最后一层。我做错了什么?


回答:

在我看来,weights_list只包括包含权重的层,通常它只有16层,因为VGG16有16个包含权重的层。但model.layers的范围是从0到N,这里N大于16,因为model.layers包括不包含权重的层,比如relu层、padding层和max_pooling层等等。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注