简体   繁体   English

从 .h5 文件加载权重时出现 Tensorflow 2.0 ValueError

[英]Tensorflow 2.0 ValueError while Loading weights from .h5 file

I have a VAE architecture script as follows:我有一个 VAE 架构脚本如下:

import numpy as np

import tensorflow as tf

from tensorflow.keras.layers import Input, Conv2D, Flatten, Dense, Conv2DTranspose, Lambda, Reshape, Layer
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import backend as K

INPUT_DIM = (64,64,3)

CONV_FILTERS = [32,64,64, 128]
CONV_KERNEL_SIZES = [4,4,4,4]
CONV_STRIDES = [2,2,2,2]
CONV_ACTIVATIONS = ['relu','relu','relu','relu']

DENSE_SIZE = 1024

CONV_T_FILTERS = [64,64,32,3]
CONV_T_KERNEL_SIZES = [5,5,6,6]
CONV_T_STRIDES = [2,2,2,2]
CONV_T_ACTIVATIONS = ['relu','relu','relu','sigmoid']

Z_DIM = 32

BATCH_SIZE = 100
LEARNING_RATE = 0.0001
KL_TOLERANCE = 0.5




class Sampling(Layer):
    def call(self, inputs):
        mu, log_var = inputs
        epsilon = K.random_normal(shape=K.shape(mu), mean=0., stddev=1.)
        return mu + K.exp(log_var / 2) * epsilon


class VAEModel(Model):


    def __init__(self, encoder, decoder, r_loss_factor, **kwargs):
        super(VAEModel, self).__init__(**kwargs)
        self.encoder = encoder
        self.decoder = decoder
        self.r_loss_factor = r_loss_factor

    def train_step(self, data):
        if isinstance(data, tuple):
            data = data[0]
        def compute_kernel(x, y):
            x_size = tf.shape(x)[0]
            y_size = tf.shape(y)[0]
            dim = tf.shape(x)[1]
            tiled_x = tf.tile(tf.reshape(x, tf.stack([x_size, 1, dim])), tf.stack([1, y_size, 1]))
            tiled_y = tf.tile(tf.reshape(y, tf.stack([1, y_size, dim])), tf.stack([x_size, 1, 1]))
            return tf.exp(-tf.reduce_mean(tf.square(tiled_x - tiled_y), axis=2) / tf.cast(dim, tf.float32))

        def compute_mmd(x, y):
            x_kernel = compute_kernel(x, x)
            y_kernel = compute_kernel(y, y)
            xy_kernel = compute_kernel(x, y)
            return tf.reduce_mean(x_kernel) + tf.reduce_mean(y_kernel) - 2 * tf.reduce_mean(xy_kernel)

        with tf.GradientTape() as tape:
            z_mean, z_log_var, z = self.encoder(data)
            reconstruction = self.decoder(z)
            reconstruction_loss = tf.reduce_mean(
                tf.square(data - reconstruction), axis = [1,2,3]
            )
            reconstruction_loss *= self.r_loss_factor
            kl_loss = 1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var)
            kl_loss = tf.reduce_sum(kl_loss, axis = 1)
            kl_loss *= -0.5

            true_samples = tf.random.normal(tf.stack([BATCH_SIZE, Z_DIM]))
            loss_mmd = compute_mmd(true_samples, z)
            

            total_loss = reconstruction_loss + loss_mmd
        grads = tape.gradient(total_loss, self.trainable_weights)
        self.optimizer.apply_gradients(zip(grads, self.trainable_weights))
        return {
            "loss": total_loss,
            "reconstruction_loss": reconstruction_loss,
            "kl_loss": kl_loss,
            "mmd_loss": loss_mmd
        }
    
    def call(self,inputs):
        latent = self.encoder(inputs)
        return self.decoder(latent)



class VAE():
    def __init__(self):
        self.models = self._build()
        self.full_model = self.models[0]
        self.encoder = self.models[1]
        self.decoder = self.models[2]

        self.input_dim = INPUT_DIM
        self.z_dim = Z_DIM
        self.learning_rate = LEARNING_RATE
        self.kl_tolerance = KL_TOLERANCE

    def _build(self):
        vae_x = Input(shape=INPUT_DIM, name='observation_input')
        vae_c1 = Conv2D(filters = CONV_FILTERS[0], kernel_size = CONV_KERNEL_SIZES[0], strides = CONV_STRIDES[0], activation=CONV_ACTIVATIONS[0], name='conv_layer_1')(vae_x)
        vae_c2 = Conv2D(filters = CONV_FILTERS[1], kernel_size = CONV_KERNEL_SIZES[1], strides = CONV_STRIDES[1], activation=CONV_ACTIVATIONS[0], name='conv_layer_2')(vae_c1)
        vae_c3= Conv2D(filters = CONV_FILTERS[2], kernel_size = CONV_KERNEL_SIZES[2], strides = CONV_STRIDES[2], activation=CONV_ACTIVATIONS[0], name='conv_layer_3')(vae_c2)
        vae_c4= Conv2D(filters = CONV_FILTERS[3], kernel_size = CONV_KERNEL_SIZES[3], strides = CONV_STRIDES[3], activation=CONV_ACTIVATIONS[0], name='conv_layer_4')(vae_c3)

        vae_z_in = Flatten()(vae_c4)

        vae_z_mean = Dense(Z_DIM, name='mu')(vae_z_in)
        vae_z_log_var = Dense(Z_DIM, name='log_var')(vae_z_in)

        vae_z = Sampling(name='z')([vae_z_mean, vae_z_log_var])
        

        #### DECODER: 
        vae_z_input = Input(shape=(Z_DIM,), name='z_input')

        vae_dense = Dense(1024, name='dense_layer')(vae_z_input)
        vae_unflatten = Reshape((1,1,DENSE_SIZE), name='unflatten')(vae_dense)
        vae_d1 = Conv2DTranspose(filters = CONV_T_FILTERS[0], kernel_size = CONV_T_KERNEL_SIZES[0] , strides = CONV_T_STRIDES[0], activation=CONV_T_ACTIVATIONS[0], name='deconv_layer_1')(vae_unflatten)
        vae_d2 = Conv2DTranspose(filters = CONV_T_FILTERS[1], kernel_size = CONV_T_KERNEL_SIZES[1] , strides = CONV_T_STRIDES[1], activation=CONV_T_ACTIVATIONS[1], name='deconv_layer_2')(vae_d1)
        vae_d3 = Conv2DTranspose(filters = CONV_T_FILTERS[2], kernel_size = CONV_T_KERNEL_SIZES[2] , strides = CONV_T_STRIDES[2], activation=CONV_T_ACTIVATIONS[2], name='deconv_layer_3')(vae_d2)
        vae_d4 = Conv2DTranspose(filters = CONV_T_FILTERS[3], kernel_size = CONV_T_KERNEL_SIZES[3] , strides = CONV_T_STRIDES[3], activation=CONV_T_ACTIVATIONS[3], name='deconv_layer_4')(vae_d3)
        

        #### MODELS

    
        vae_encoder = Model(vae_x, [vae_z_mean, vae_z_log_var, vae_z], name = 'encoder')
        vae_decoder = Model(vae_z_input, vae_d4, name = 'decoder')

        vae_full = VAEModel(vae_encoder, vae_decoder, 10000)

        opti = Adam(lr=LEARNING_RATE)
        vae_full.compile(optimizer=opti)
        
        return (vae_full,vae_encoder, vae_decoder)

    def set_weights(self, filepath):
        self.full_model.load_weights(filepath)

    def train(self, data):

        self.full_model.fit(data, data,
                shuffle=True,
                epochs=1,
                batch_size=BATCH_SIZE)
        
    def save_weights(self, filepath):
        self.full_model.save_weights(filepath)

Problem:问题:

vae = VAE()
vae.set_weights(filepath)

throws:抛出:

 File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py", line 2200, in load_weights 'Unable to load weights saved in HDF5 format into a subclassed ' ValueError: Unable to load weights saved in HDF5 format into a subclassed Model which has not created its variables yet. Call the Model first, then load the weights.

I am not sure what this means since I am not that proficient in OOP.我不确定这意味着什么,因为我不精通 OOP。 The surprising bit is that the above code was working until it stopped working.令人惊讶的是,上面的代码一直在工作,直到它停止工作。 The model is training from scratch and it saves the weights in filepath .该模型从头开始训练,并将权重保存在filepath But when I am loading the same weights now it is throwing the above error!但是当我现在加载相同的权重时,它会抛出上述错误!

如果您在加载模型权重之前设置model.built = True它将起作用。

What version of TF are you running?你运行的是什么版本的TF? For a while the default saving format was hdf5, but this format cannot support subclassed models as easily, so you get this error.有一段时间默认的保存格式是 hdf5,但是这种格式不能那么容易地支持子类模型,所以你会得到这个错误。 It may be solvable by first training it on a single batch and then loading the weights (to determine how the parts are connected, which is not saved in hdf5).它可以通过首先在单个批次上训练它然后加载权重来解决(以确定零件的连接方式,这未保存在 hdf5 中)。

In the future I would recommend making sure that all saves are done with the TF file format though, it will save you from extra work.将来,我建议确保所有保存都使用 TF 文件格式完成,这样可以免除您的额外工作。

As alwaysmvp45 pointed out "hdf5 does not store how the layers are connected".正如alwaysmvp45指出的那样“hdf5 不存储层的连接方式”。 To make these layers be connected, another way is that you call the model to predict a zeros array with input shape ( (1,w,h,c) ) before loading weights:为了使这些层连接起来,另一种方法是在加载权重之前调用模型来预测具有输入形状 ( (1,w,h,c) ) 的零数组:

model(np.zeros((1,w,h,c)))

i was getting same same error while loading weights via我在通过加载权重时遇到同样的错误

model.load_weights("Detection_model.h5")

ValueError: Unable to load weights saved in HDF5 format into a subclassed Model which has not created its variables yet. ValueError:无法将以 HDF5 格式保存的权重加载到尚未创建其变量的子类模型中。 Call the Model first, then load the weights.首先调用模型,然后加载权重。

solved it by building model before loading weights通过在加载权重之前构建模型来解决它

model.build(input_shape = <INPUT_SHAPE>)
model.load_weights("Detection_model.h5")

ps, tensorflow Version: 2.5.0 ps,张量流版本:2.5.0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 是否有将来自不同折叠的 .h5 权重组合成一组权重的 tensorflow 函数? - Is there a tensorflow function that combines .h5 weights from different folds into 1 set of weights? 加载 Tensorflow keras Model (.h5) 时出错 - Error loading Tensorflow keras Model (.h5) 在 TensorFlow 2.0 中加载 numpy 权重 - Loading numpy weights in TensorFlow 2.0 将 tensorflow model 转换为 tensorflow lite (.h5 to.tflite) = ValueError: bad marshal data (unknown type code) 时出错 - Error while converting tensorflow model to tensorflow lite (.h5 to .tflite) = ValueError: bad marshal data (unknown type code) 导入 VGG16 h5 文件时出错 ValueError: 在配置文件中找不到 model - Error while importing VGG16 h5 file ValueError: No model found in config file (AttributeError: &#39;NoneType&#39; 对象没有属性 &#39;get&#39; ) 在 tensorflow 2.1 中加载带有 .h5 扩展名的已保存 keras 模型 - (AttributeError: 'NoneType' object has no attribute 'get' ) while loading saved keras model with .h5 extension in tensorflow 2.1 从python中的.h5文件获取帧时出现Unicode错误 - Unicode Error while getting frame from .h5 file in python 是否可以将google protobuffer文件(从tensorflow)转换为keras .h5文件? - Is it possible to convert a google protobuffer file (from tensorflow) into a keras .h5 file? Tensorflow对象检测:使用.h5(hdf5)文件从头开始训练 - Tensorflow Object Detection: training from scratch using a .h5 (hdf5) file 我们可以在keras中更改训练后的神经网络结构(.json或.h5文件)及其权重(.h5文件)吗? - Can we alter the trained neural network structure (.json or .h5 file) and its weights(.h5 file) in keras?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM