Keras - 自定义层

  • 简述

    Keras 允许创建我们自己的自定义层。一旦创建了一个新层,它就可以在任何模型中使用,没有任何限制。让我们在本章中学习如何创建新层。
    Keras 提供了一个基础类,Layer 可以进行子类化以创建我们自己的自定义层。让我们创建一个简单的层,它将根据正态分布找到权重,然后在训练期间进行基本计算,即找到输入乘积与其权重的总和。

    第一步:导入必要的模块

    首先,让我们导入必要的模块 -
    
    
    from keras import backend as K 
    
    from keras.layers import Layer
    
    
    说明
    • backend用于访问函数。
    • Layer是基类,我们将对其进行子类化以创建我们的层

    第二步:定义图层类

    让我们通过子类化Layer 类创建一个新类MyCustomLayer -
    
    
    class MyCustomLayer(Layer): 
    
       ...
    
    

    第三步:初始化图层类

    让我们初始化我们的新类,如下所示 -
    
    
    def __init__(self, output_dim, **kwargs):    
    
       self.output_dim = output_dim 
    
       super(MyCustomLayer, self).__init__(**kwargs)
    
    
    参数
    • 第 2 行设置输出维度。
    • 第 3 行调用基层或超层的init函数。

    第四步:实现构建方法

    build是主要方法,其唯一目的是正确构建图层。它可以做任何与层的内部工作相关的事情。自定义功能完成后,我们可以调用基类构建函数。我们的自定义构建功能如下 -
    
    
    def build(self, input_shape): 
    
       self.kernel = self.add_weight(name = 'kernel', 
    
          shape = (input_shape[1], self.output_dim), 
    
          initializer = 'normal', trainable = True) 
    
       super(MyCustomLayer, self).build(input_shape)
    
    
    参数
    • 第 1 行使用一个参数input_shape定义了构建方法。输入数据的形状由 input_shape 引用。
    • 第 2 行创建与输入形状对应的权重并将其设置在内核中。这是我们层的自定义功能。它使用“正常”初始化程序创建权重。
    • 第 6 行调用基类build方法。

    第五步:实现调用方法

    call方法在训练过程中执行层的确切工作。
    我们自定义的调用方式如下
    
    
    def call(self, input_data): 
    
       return K.dot(input_data, self.kernel)
    
    
    参数
    • 第 1 行使用一个参数input_data定义调用方法。input_data 是我们层的输入数据。
    • 第 2 行返回输入数据input_data和我们层的内核self.kernel的点积

    第六步:实现 compute_output_shape 方法

    
    
    def compute_output_shape(self, input_shape): return (input_shape[0], self.output_dim)
    
    
    参数
    • 第 1 行定义了带有一个参数input_shape的compute_output_shape方法
    • 第 2 行在初始化层时使用输入数据的形状和输出维度集计算输出形状。
    实现build、callcompute_output_shape完成了自定义层的创建。最终完整的代码如下
    
    
    from keras import backend as K from keras.layers import Layer
    
    class MyCustomLayer(Layer): 
    
       def __init__(self, output_dim, **kwargs): 
    
          self.output_dim = output_dim 
    
          super(MyCustomLayer, self).__init__(**kwargs) 
    
       def build(self, input_shape): self.kernel = 
    
          self.add_weight(name = 'kernel', 
    
          shape = (input_shape[1], self.output_dim), 
    
          initializer = 'normal', trainable = True) 
    
          super(MyCustomLayer, self).build(input_shape) # 
    
          Be sure to call this at the end 
    
       def call(self, input_data): return K.dot(input_data, self.kernel) 
    
       def compute_output_shape(self, input_shape): return (input_shape[0], self.output_dim)
    
    

    使用我们的自定义层

    让我们使用我们的自定义层创建一个简单的模型,如下所示 -
    
    
    from keras.models import Sequential 
    
    from keras.layers import Dense 
    
    
    
    model = Sequential() 
    
    model.add(MyCustomLayer(32, input_shape = (16,))) 
    
    model.add(Dense(8, activation = 'softmax')) model.summary()
    
    
    参数
    • 我们的MyCustomLayer使用 32 个单位和(16,)作为输入形状添加到模型中
    运行应用程序将打印模型摘要如下 -
    
    
    Model: "sequential_1" 
    
    _________________________________________________________________ 
    
    Layer (type) Output Shape Param 
    
    #================================================================ 
    
    my_custom_layer_1 (MyCustomL (None, 32) 512 
    
    _________________________________________________________________
    
    dense_1 (Dense) (None, 8) 264 
    
    ================================================================= 
    
    Total params: 776 
    
    Trainable params: 776 
    
    Non-trainable params: 0 
    
    _________________________________________________________________