编写自己的层

对于简单的定制操作,我们或许可以通过使用layers.core.Lambda层来完成。但对于任何具有可训练权重的定制层,你应该自己来实现。

这里是一个Keras2的层应该具有的框架结构(如果你的版本更旧请升级),要定制自己的层,你需要实现下面三个方法

  • build(input_shape):这是定义权重的方法,可训练的权应该在这里被加入列表`self.trainable_weights中。其他的属性还包括self.non_trainabe_weights(列表)和self.updates(需要更新的形如(tensor, new_tensor)的tuple的列表)。你可以参考BatchNormalization层的实现来学习如何使用上面两个属性。这个方法必须设置self.built = True,可通过调用super([layer],self).build()实现

  • call(x):这是定义层功能的方法,除非你希望你写的层支持masking,否则你只需要关心call的第一个参数:输入张量

  • compute_output_shape(input_shape):如果你的层修改了输入数据的shape,你应该在这里指定shape变化的方法,这个函数使得Keras可以做自动shape推断

  1. from keras import backend as K
  2. from keras.engine.topology import Layer
  3. import numpy as np
  4. class MyLayer(Layer):
  5. def __init__(self, output_dim, **kwargs):
  6. self.output_dim = output_dim
  7. super(MyLayer, self).__init__(**kwargs)
  8. def build(self, input_shape):
  9. # Create a trainable weight variable for this layer.
  10. self.kernel = self.add_weight(name='kernel',
  11. shape=(input_shape[1], self.output_dim),
  12. initializer='uniform',
  13. trainable=True)
  14. super(MyLayer, self).build(input_shape) # Be sure to call this somewhere!
  15. def call(self, x):
  16. return K.dot(x, self.kernel)
  17. def compute_output_shape(self, input_shape):
  18. return (input_shape[0], self.output_dim)

现存的Keras层代码可以为你的实现提供良好参考,阅读源代码吧!