【问题标题】:How to excluded layers weight and only keep the weights I want and predict model by using keras?如何排除层权重并仅保留我想要的权重并使用 keras 预测模型?
【发布时间】:2023-07-14 12:15:01
【问题描述】:

我想提取一些选定层的权重并将它们保存为一个名为 encoding_weight.h5 的 Hdf5 文件,然后预测模型以获得输出。

原始模型包含所有我不需要的权重。

model =  Autoencoder(input_shape=x_train.shape[1:])  #this is the original model
model.summary()
layer_name_list = ['dense2048','batch2048','act2048',
                   'dense1024','batch1024','act1024',
                   'dense512','batch512','act512']

layer_dict = dict([(layer.name, layer) for layer in model.layers])
for i in (layer_name_list):
    layer_name = i
    layer_output = layer_dict[layer_name].get_weights()

上面的代码可以得到我想要的权重作为数组列表,但是我不知道如何将它们保存为“encoded_weight.h5”,以便我可以在下面的代码中使用它来预测原始模型。

model.load_weights(‘encoded_weight.h5’, by_name=True) 
model.compile(optimizer = Adam(), loss = 'mean_squared_error' , metrics = ['mae'])
z_train = model.predict(x= x_train_z,verbose=2)

【问题讨论】:

  • 你想存储整个模型的权重吗?
  • 嗨 Aniket。不,我只想保存编码层权重,我不知道如何在 keras 中做到这一点。

标签: python tensorflow keras autoencoder


【解决方案1】:

您可以使用 tensorflow 的 save_weights 方法保存模型的权重。

model.save_weights(
    'encoded_weight.h5', overwrite=True, save_format=None, options=None
)

您可以将这些权重加载为

model.load_weights('encoded_weight.h5')

如果您想访问各个层的各个权重。你可以这样做。

代码:

# A recursive function to get path of dataset element inside the 'encoded_weight.h5'

def traverse_datasets(hdf_file):

    def h5py_dataset_iterator(g, prefix=''):
        for key in g.keys():
            item = g[key]
            path = f'{prefix}/{key}'
            if isinstance(item, h5py.Dataset): # test for dataset
                yield (path, item)
            elif isinstance(item, h5py.Group): # test for group (go down)
                yield from h5py_dataset_iterator(item, path)

    for path, _ in h5py_dataset_iterator(hdf_file):
        yield path

import h5py
filename = "encoded_weight.h5"

hf = h5py.File(filename, "r")

for dset in traverse_datasets(hf):
    print('Path:', dset)
    print(hf[dset])
#     print(np.array(hf[dset]))   # Contains you array
    print('-----------------------')

输出:

Path: /conv1d/conv1d/bias:0
<HDF5 dataset "bias:0": shape (64,), type "<f4">
-----------------------
Path: /conv1d/conv1d/kernel:0
<HDF5 dataset "kernel:0": shape (3, 1, 64), type "<f4">
-----------------------
Path: /dense/dense/bias:0
<HDF5 dataset "bias:0": shape (128,), type "<f4">
-----------------------
Path: /dense/dense/kernel:0
<HDF5 dataset "kernel:0": shape (3712, 128), type "<f4">
-----------------------
Path: /dense_1/dense_1/bias:0
<HDF5 dataset "bias:0": shape (5,), type "<f4">
-----------------------
Path: /dense_1/dense_1/kernel:0
<HDF5 dataset "kernel:0": shape (128, 5), type "<f4">
-----------------------

使用它,您可以使用 set_weights 方法更新各个层的权重。

我的模型层:

model.layers

输出:

[<tensorflow.python.keras.layers.convolutional.Conv1D at 0x209a3b41e08>,
 <tensorflow.python.keras.layers.pooling.MaxPooling1D at 0x209a9e40cc8>,
 <tensorflow.python.keras.layers.core.Flatten at 0x209a9e49708>,
 <tensorflow.python.keras.layers.core.Dense at 0x209a9e49588>,
 <tensorflow.python.keras.layers.core.Dropout at 0x209a9e4fa48>,
 <tensorflow.python.keras.layers.core.Dense at 0x209a9e56f08>]

更新 conv1d 层的权重。

代码:

w = [tf.constant(hf['/conv1d/conv1d/kernel:0']),tf.constant(hf['/conv1d/conv1d/bias:0'])]
model.layers[0].set_weights(w)

【讨论】:

  • 如果它有效,请您接受并支持答案。
  • 嗨!谢谢你的评论!我可能不清楚我的问题。如果我使用 model.save_weights 我会保存所有的权重。但是,我只想保存前半部分的权重,我该怎么做呢?
  • 如果您只想保存某些层的权重,您只需使用 layer.get_weights() 访问它们并将其存储为任何格式,如 npy、h5、pickle 等。
  • 知道了!谢谢!
最近更新 更多