将.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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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