Keras 简明教程

Keras - Customized Layer

Keras 允许创建我们自己的自定义层。一旦创建一个新层,它就可以在任何模型中毫无限制地使用。让我们在这章中学习如何创建新层。

Keras 提供了一个基础 layer 类,Layer 可以对其进行子类化以创建我们自己的自定义层。让我们创建一个简单的层,它将根据正态分布找到权重,然后在训练期间对输入及其权重的乘积求和进行基本计算。

Step 1: Import the necessary module

首先,让我们导入必要的模块 −

from keras import backend as K
from keras.layers import Layer

在此,

  1. backend 用于访问 dot 函数。

  2. Layer 是基础类,我们将对其进行子类化以创建我们的层

Step 2: Define a layer class

让我们通过对 Layer class 进行子类化来创建一个新类 MyCustomLayer

class MyCustomLayer(Layer):
   ...

Step 3: Initialize the layer class

让我们如下所示初始化我们的新类 −

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

在此,

  1. Line 2 设置输出维度。

  2. Line 3 调用基础层或超层的 init 函数。

Step 4: Implement build method

build 是主要方法,其唯一目的是正确构建层。它可以执行与层内部工作相关的任何操作。完成自定义功能后,我们可以调用基础类 build 函数。我们的自定义 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. Line 1 使用一个参数 input_shape 定义 build 方法。输入数据的形状由 input_shape 引用。

  2. Line 2 创建与输入形状相对应的权重,并将其设置在 kernel 中。这是我们层的自定义功能。它使用“正态”初始化器创建权重。

  3. Line 6 调用基础类 build 方法。

Step 5: Implement call method

call 方法在训练过程中执行层的精确工作。

我们的自定义 call 方法如下

def call(self, input_data):
   return K.dot(input_data, self.kernel)

在此,

  1. Line 1 用一个参数 input_data 定义 call 方法。input_data 是我们层的输入数据。

  2. Line 2 返回输入数据 input_data 和我们层的核 self.kernel 的点积

Step 6: Implement compute_output_shape method

def compute_output_shape(self, input_shape): return (input_shape[0], self.output_dim)

在此,

  1. Line 1compute_output_shape 方法定义了一个参数 input_shape

  2. Line 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)

Using our customized layer

我们创建一个简单的模型,使用如下指定得自定义层:

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()

在此,

  1. 我们的 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
_________________________________________________________________