python - 从之前保存的 hdf5 文件中加载部分模型权重

标签 python keras hdf5 h5py

您好,我有一个模型想要使用迁移学习。我有另一个模型,我已经训练并保存了它的权重。我想做的是将之前训练的模型中的前几个权重加载到这个具有相同层的新模型中,但我在最后添加了更多层。如何将前几层的权重加载到我的新模型中?

这是我尝试过的:

def load_custom_weights(model, data, layer_indices):
  weights = [data[p] for p in layer_indices]
  print(model.weights)
  model.set_weights(weights)
  print(model.get_weights())
  return model

filename = 'unimodal_weights/best_weight_image_only_k-fold_1.hdf5'
f = h5py.File(filename, 'r')
img_data = f['model_weights']['Image_Branch']['Image_Branch_2']

img = get_img_branch()
img = load_custom_weights(img, img_data, list(img_data))

该模型似乎加载了权重,但即使我们从中获取权重的模型得分很好,但我的准确性非常低。

有什么方法可以检查我的模型是否确实加载了权重?

编辑:它们都是多 GPU 模型

编辑2:

所以我的模型有点棘手,我的模型中嵌入了一个顺序模型。我想将权重加载到其中一个分支,特别是图像分支

这是我的模型的样子:

图像分支:

def get_img_branch():
    Image_Branch = Sequential(name='Image_Branch')
    #block 1
    Image_Branch.add(Conv2D(64, kernel_size=(3,3), activation='relu', padding='valid', kernel_initializer='he_normal', name='block1_conv1'))
    Image_Branch.add(BatchNormalization())
    Image_Branch.add(Conv2D(64, kernel_size=(3,3), activation='relu', padding='valid', kernel_initializer='he_normal', name='block1_conv2'))
    Image_Branch.add(BatchNormalization())
    Image_Branch.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='block1_pool'))
...SNIP...
    #Flatten
    Image_Branch.add(Flatten())
    return Image_Branch

封装模型

image_input = Input(shape, name='image_input')
#get branches
img = get_img_branch()
#set up our image branch
image_branch = (img)(image_input)
...SNIP

我们可以看到我们已经获取了作为顺序模型的图像分支,并将其插入到新模型中。这里的关键是,在 HDF5 格式中,有一个名为 ['model_weights'] 的键,在该字典中,还有另一个名为 ['Image_Branch'] 的键,它对应于我的模型。

我们所做的就是调用:

load_weights(img_loc, by_name=True)

而不是:

img = get_img_branch()
img.load_weights(img_loc, by_name=True)

因为执行后者将尝试查找图像分支键 ['Image_Branch'] 但不会找到它,因为当我们在后一个示例中加载图像分支时,它是图像分支。名为“Image_Branch”的层仅存在于封装它的模型中。

此外,如果您想加载多 GPU 模型并插入权重,您将执行以下操作:

model.layers[-2].load_weights(img_loc, by_name=True)

最佳答案

您可以通过仔细命名图层并使用 documentation 中的现有 model.load_weights(filename, by_name=True) 来实现此目的:

model.load_weights(filepath, by_name=False) loads the weights of the model from a HDF5 file (created by save_weights). By default, the architecture is expected to be unchanged. To load weights into a different architecture (with some layers in common), use by_name=True to load only those layers with the same name.

名称所指的是例如 Dense(21, ..., name='dense_layer_1') 或您的 Image_Branch 子模型。因此,请检查图层的原始名称,然后使用匹配的名称重新创建新模型,同时新图层具有不同的新名称。

关于python - 从之前保存的 hdf5 文件中加载部分模型权重,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54313305/

相关文章:

c++ - 在磁盘 C++ 上存储科学数据集的最佳方法

python - 将用-v7.3(HDF5)保存的Matlab稀疏矩阵加载到Python中并对其进行操作

Python Gtk+3 Window.present 不适用于 GNOME Builder

python - 如何使用 BeautifulSoup 发送 key

tensorflow - 使用keras在tensorflow中自定义损失

python - Keras适合生成器-ValueError : Failed to find data adapter that can handle input

mysql - 如何存储历史时间序列数据

python - 如何使用递归但不使用 for 或 while 循环来获得不重复的字符串排列?

python - PIL 可以用于获取 svg 文件的尺寸吗?

tensorflow - 使用 keras 进行分类 : input data shape