如何在keras中保存自定义图层中的变量

时间:2018-05-19 16:24:05

标签: tensorflow keras

我想创建一个(4,1)维矩阵,以便在我的自定义图层中使用带有(4,)维度的输入相乘。所以我做如下:

class MyLayer(Layer):

def __init__(self, output_dim = 4, **kwargs):
    self.output_dim = output_dim
    super(MyLayer, self).__init__(**kwargs)

def build(self, input_shape):
    # Create a trainable weight variable for this layer.
    k1 = K.variable(1, dtype=tf.float32, name='k1')
    k2 = K.variable(1, dtype=tf.float32, name='k2')
    k3 = K.variable(1, dtype=tf.float32, name='k3')
    k4 = K.variable(1, dtype=tf.float32, name='k4')
    weights = tf.stack([k1,k2,k3,k4], name='weight_stack')
    weights = tf.expand_dims(weights,1)
    weights = tf.expand_dims(weights, 1)
    weights = tf.expand_dims(weights, 1)
    weights = tf.expand_dims(weights, 1)
    self.kernel=tf.nn.softmax(weights,name='weights_softmax')


    super(MyLayer, self).build(input_shape)  # Be sure to call this somewhere!

def call(self, inputs):
    self.inputs = inputs
    P = tf.multiply(self.inputs, self.kernel)
    P = tf.add_n([P[0],P[1],P[2],P[3]])
    self.shape = P.shape
    return P

def compute_output_shape(self, input_shape ):
    return (input_shape, 1, 1, 1, 1)

我称之为:

x = [x1, x2, x3, x4]
x = MyLayer(name = "weight_matrix")(x)

当我使用这种自行设计的图层训练网络时,它可以正常工作。但是,当我用回调保存它时如下:

keras.callbacks.ModelCheckpoint(self.checkpoint_path,
                                        verbose=0, save_weights_only=True)

当我尝试重新加载模型时,我发现无法重新加载“权重”(表示k1到k4)。 我看一下保存模型的文件,我找不到“weight_matrix”的权重。

如果我做得不对,我该如何解决它或如何在keras中实现它? THX。

1 个答案:

答案 0 :(得分:0)

您无处调用self.add_weight

您的图层根本没有权重。

build

def build(self, input_shape):
    def customWeights(shape, dtype=None):

        #k1 = K.variable(1, dtype=tf.float32, name='k1')
        #k2 = K.variable(1, dtype=tf.float32, name='k2')
        #k3 = K.variable(1, dtype=tf.float32, name='k3')
        #k4 = K.variable(1, dtype=tf.float32, name='k4')
        #weights = tf.stack([k1,k2,k3,k4], name='weight_stack')
        weights = K.ones((4,))  
           #you can also use the shape passed to this function to build a flexible layer


        #weights = tf.expand_dims(weights,1)
        #weights = tf.expand_dims(weights, 1)
        #weights = tf.expand_dims(weights, 1)
        #weights = tf.expand_dims(weights, 1)
        weights = K.reshape(weights,(-1,1,1,1,1))

        #this should be applied later
        #return tf.nn.softmax(weights,name='weights_softmax')

        return weights

    self.kernel= self.add_weight(name='kernel', 
                                  shape=notBeingUsedButItMayBeGoodForFlexibleLayers,
                                  initializer=customWeights,
                                  trainable=True)

    super(MyLayer, self).build(input_shape)  # Be sure to call this somewhere!

call {...}}中,您可以在权重上调用softmax

def call(self, inputs):
    #don't call this! You're replacing an important property of the layer
    #self.inputs = inputs

    kernel = K.softmax(self.kernel)

    P = tf.multiply(inputs, kernel)
    P = tf.add_n([P[0],P[1],P[2],P[3]])

    #not sure if this is a good idea either
    #self.shape = P.shape

    return P