1. Layer重写的基本思路?
Keras层的骨架。只需要实现三个方法即可:
build(input_shape): 这是你定义权重的地方。这个方法必须设self.built = True,可以通过调用super([Layer], self).build()完成。build,这个函数用来确立这个层都有哪些参数,哪些参数是可训练的哪些参数是不可训练的。
call(x): 这里是编写层的功能逻辑的地方。你只需要关注传入call的第一个参数:输入张量,除非你希望你的层支持masking。这个函数在调用层对象时自动使用,里面就是该层的计算逻辑,或计算图了。显然,这个层的核心应该是一段符号式的输入张量到输出张量的计算过程。
compute_output_shape(input_shape): 如果你的层更改了输入张量的形状,你应该在这里定义形状变化的逻辑,这让Keras能够自动推断各层的形状。
2. 在重写layer的时候是否需要考虑batchsize?
Keras的Layer就是一个Tensor到Tensor的映射
自定义层,只要不是输入层,都不用考虑batch,因为batch是从前面传进来的,自己只是在原来的基础上增加一个后续操作。个人感觉这样导致灵活性变差。
3. Build的输入input_shape究竟是什么?
Keras的所有的层有一个“input_shape”的参数,用来指定输入张量的shape。然而这
个input_shape,或者有时候是input_dim,只需要在模型的首层加以指定。一旦模型的首层的input_shape指定了,后面的各层就不用再指定,而会根据计算图自动推断。这个功能称为shape的自动推断。
4. Call 的输入input、state(RNN)究竟是什么?
计算图中上一层中的返回值,因RNN中循环结构,同一层中下一个cell的x就是上一个call的return值???此处不明白
def call(self,x):
return K.dot(x,self.kernel)
5. 如果该层输入和输出Tensor的shape不一致怎么办?
get_output_shape_for:如果你的层计算后,输入张量和输出张量的shape不一致,那么你需要把这个函数也重新写一下,返回输出张量的shape,以保证Keras可以进行shape的自动推断。如果你的网络层改变了输入张量的shape,就应该复写get_output_shape_for这个函数,以使后面的层能知道本层输出的shape。
在所有的Keras中都有这样一个函数,因此后面的层可以通过查看这个函数的返回值获取前层的输入shape,并通过自己的get_output_shape_for将这个信息传递下去。然而,有时候,这个自动推断会出错。这种情况发生在一个RNN层后面接Flatten然后又接Dense的时候,这个时候Dense的output_shape无法自动推断出。这时需要指定RNN的输入序列长度input_length,或者在网络的第一层通过input_shape就指定。这种情况极少见,大致有个印象即可,遇到的话知道大概是哪里出了问题就好。
6. 示例:
参考: keras官方文档
https://zhuanlan.zhihu.com/p/22129301