在深度学习领域,Keras是一个高度封装的库并被普遍应用,能够经过调用其内置网络模块(各类网络层)实现针对性的模型结构;当所须要的网络层功能不被包含时,则须要经过自定义网络层或模型实现。网络
如何在keras框架下自定义层,基本“套路”以下。框架
这个方法是用来初始化并自定义自定义层所需的属性,好比output_dim;
此外,该方法须要执行super().__init __(**kwargs),这行代码是执行Layer类中的初始化函数;
当执行上述代码就没有必要去管input_shape,weights,trainable等关键字参数,由于父类(Layer)的初始化函数实现了它们与layer实例的绑定。函数
这个方法是用来建立层的权重;
在该方法中,根据以前的继承,经过Layer类的add_weight方法来自定义并添加一个权重矩阵,这个方法须要input_shape参数;
该方法必须设self.built = True,目的是为了保证这个层的权重定义函数build被执行过了;
在built函数中,须要说明这个权重各方面的属性,好比shape、初始化方式以及可训练性等信息。学习
这个方法是用来编写层的功能逻辑;
在该方法中,须要关注传入call的第一个参数:输入张量x;x只能是一种形式变量,不能是具体的变量,即它不能被定义;
这个call函数就是该层的计算逻辑,当建立好这个层实例后,该实例能够执行call函数;
可见,这个层的核心应该是一段符号式的输入张量到输出张量的计算过程。ui
这个方法是用来保证输出shape是正确的;
这里重写compute_output_shape方法去覆盖父类中的同名方法,来保证输出的shape符合实际;
父类Layer中的compute_output_shape方法直接返回的是input_shape这明显是不对的,因此须要重写该方法。blog
结合官方文档的例子,给出以下一个自定义层的代码:
继承
使用自定义层,就如同使用keras内置网络层同样,以下图所示:(另外,本例使用kears内置的激活函数层ReLU承接自定义层的输出,从而避免将激活函数的功能加入到自定义层中)
文档