● 问题描述:

在一个二分类任务上,我训练好的keras模型的准确率是0.9。但是,当我用tf.keras.models.load_modeld重新加载该模型后,它的准确率却变成了0.5(显然是因为网络的参数变成随机值了)。

● 问题原因:

导致该问题的原因是,我的模型用到了自建的keras layer,但是我的自建layer写错了。错误点是,我在自建layer里调用了其它layer。该错误会导致用load_modeld重载权重时,其它layer的权重不会被载入,而会被随机初始化。(详细原因可查阅tf.keras.models.load_modeld的源码)

● 解决方法:

自建层里需要保存的参数,都需要使用add_weight来注册。

● 举例说明:

下面通过一个例子,来进一步说明该错误以及其解决方法。

错误写法:

下面这段代码自建了一个keras layer,实现的是dense layer的功能。这个错误例子里,我是通过调用keras的Dense来实现该功能的。

import tensorflow as tf
class MyLayer(tf.keras.layers.Layer):
    def __init__(self,**config):
        super(MyLayer, self).__init__(config)

    def build(self,input_shape):
        self.detector_layer_dense = tf.keras.layers.Dense(20, activation='sigmoid')
        super(MyLayer,self).build(input_shape)

    def call(self,input):
        output = self.detector_layer_dense_1(merged_feature_of_each_steps)
        return output

正确写法:

首先要build()函数中用add_weight创建一个dense kernel,然后在call()函数中用矩阵相乘实现dense layer.

import tensorflow as tf
class MyLayer(tf.keras.layers.Layer):
    def __init__(self,**config):
        super(MyLayer, self).__init__(config)

    def build(self,input_shape):
        self.dense_kernel = add_weight(shape=[20,1],name='kernel')
        super(MyLayer,self).build(input_shape)

    def call(self,input):
        output = tf.matmul(input,self.dense_kernel)
        return output
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐