从先前保存的hdf5文件中加载模型权重的一部分

时间:2019-01-22 17:13:18

标签: python keras hdf5

嗨,我有一个模型,希望将其用于转移学习。我有另一个模型,我已经对其进行了训练并节省了权重。我想做的是将以前训练过的模型的前几个权重加载到这个具有相同图层的新模型中,但是最后我增加了更多的图层。如何将前几层的权重加载到新模型中?

这是我尝试过的:

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)

1 个答案:

答案 0 :(得分:0)

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

  

model.load_weights(filepath, by_name=False)从HDF5文件(由save_weights创建)中加载模型的权重。默认情况下,该架构应保持不变。要将权重加载到不同的体系结构中(共有一些层),请使用by_name=True仅加载具有相同名称的那些层。

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