如何在Keras中构建此自定义图层? [英] How to build this custom layer in Keras?

查看:133
本文介绍了如何在Keras中构建此自定义图层?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个支持复数的NN.目前正在从事复杂的激活.根据Benjio的论文,这是一个很好的方法:

I'm building a NN that supports complex numbers. Currently working on complex activation. According to a Benjio paper, this is a good one:

其中b是要学习的可训练参数.因此,我正在建立一个特殊的层来执行此激活.我是Keras的新手,已经被卡住了.我在下面创建了此代码,但是生成功能出错.我不知道发生了什么,我只是试图复制模板.请帮忙.

Where b is a trainable parameter to be learnt. So I'm building a special layer to do this activation. I'm new to Keras and stuck already. I created this code below, but it gives an error with the build function. I have no idea what's happening, I just tried to copy the template. Please help.

class modrelu(Layer):
    def __init__(self, **kwargs):
        super(modrelu, self).__init__(**kwargs)

    def build(self):
        self.b= K.variable(value=np.random.rand()-0.5, dtype='float64')
        super(modrelu, self).build()  # Be sure to call this at the end

    def call(self, x):
        assert isinstance(x, list)
        ip_r, ip_i = x
        comp= tf.complex(ip_r, ip_i ) 
        ABS= tf.math.abs(comp)
        ANG= tf.math.angle(comp)

        ABS= K.relu( self.b + ABS) 

        op_r=  ABS * K.sin(angle) #K.dot ??
        op_i= ABS * K.cos(angle)
        return [op_r, op_i]

    def compute_output_shape(self, input_shape):
        assert isinstance(input_shape, list)
        shape_a, shape_b = input_shape
        return [shape_a, shape_b]

对我的代码的评论: 在 init 中,我没有添加任何内容,因为它是一个激活层,在实例化时不需要任何输入.

Comments on my code: In the init I didn't add anything, cause it is an activation layer that takes no input when instantiated.

在build方法中,我尝试添加b.不知道我是否应该使用self.add_weight方法.理想情况下,我希望b与输入的维数一样多.

In the build method, I tried to add the b's. Not sure if I should use the self.add_weight method. Ideally, I want to have as many b's as the dimension of input.

在调用方法(这一方法)中,我很确定自己在做什么.很简单,我刚刚实现了该功能.

In the call method, this one, I'm pretty sure what I'm doing. It is easy, I just implemented the function.

最后一个,compute_output_shape,我只是复制粘贴了模板.输出应该与输入相同,因为它只是一个激活层.

The last one, compute_output_shape, I just copied-pasted the template. The output should be the same as the input, cause it is just an activation layer.

最后,关于它的价值的错误,我知道这是胡说八道

Finally, the error for what its worth, I know it is nonsense

TypeError                                 Traceback (most recent call last)
<ipython-input-5-3101a9226da5> in <module>
      1 a=K.variable(np.array([1,2]))
      2 b=K.variable(np.array([3,4]))
----> 3 act([a,b])

~\AppData\Local\conda\conda\envs\python36\lib\site-packages\keras\engine\base_layer.py in __call__(self, inputs, **kwargs)
    429                                          'You can build it manually via: '
    430                                          '`layer.build(batch_input_shape)`')
--> 431                 self.build(unpack_singleton(input_shapes))
    432                 self.built = True
    433 

TypeError: build() takes 1 positional argument but 2 were given

推荐答案

您的代码有几个问题.

There are several issues with your code.

首先,我应该解决您从解释器得到的错误:

First of all I should address the error you get from interpreter:

TypeError: build() takes 1 positional argument but 2 were given

build方法应采用input_shape自变量.因此,您应该将构建方法声明为build(self, input_shape)

The build method should take input_shape argument. Therefore you should declare build method as build(self, input_shape)

第二个问题是build方法中变量的形状不确定.您应该显式声明变量的形状.在您的情况下,np.random.rand数组应为input_shape形状.

The second issue is undefined shape of the variables in the build method. You should explicitly declare shape of the variables. In your case the np.random.rand array should be of input_shape shape.

另一个问题是您试图在call方法中返回2个结果([op_r, op_i]).我不是Keras的专家,但据我所知你做不到.每个Keras层应该只有一个输出.有关详细信息,请参见此处: https://github.com/keras-team/keras/Issues/3061

Another issue is that you are trying to return 2 results ([op_r, op_i]) in the call method. I'm not specialist in Keras but as far as I know you can't do it. Every Keras layer should have one and only one output. See here for the details: https://github.com/keras-team/keras/issues/3061

但是,如果您使用tensorflow后端,则可以使用复数(tf.complex)来返回复数的实数部分(op_r)和虚数部分(op_i).

However if you use tensorflow backend you may use complex numbers (tf.complex) to return both real (op_r) and imagenary (op_i) parts of the complex number.

这是modrelu层的有效实现,并带有简单的用法示例.它是TensorFlow 1.12.0的写法,它随其自己的Keras API实现一起分发,但我认为您可以轻松地将其用于原始Keras:

Here is the working implementation of modrelu layer with simple usage example. It is writtern for TensorFlow 1.12.0 which is distributed with it's own implementation of Keras API but I think you can easily adopt it for original Keras:

import tensorflow as tf
from tensorflow.python.keras import backend as K
from tensorflow.python.keras.engine import Layer
import numpy as np


class modrelu(Layer):

    def __init__(self, **kwargs):
        super(modrelu, self).__init__(**kwargs)

    # provide input_shape argument in the build method
    def build(self, input_shape):
        # You should pass shape for your variable
        self.b= K.variable(value=np.random.rand(*input_shape)-0.5,
                           dtype='float32')
        super(modrelu, self).build(input_shape)  # Be sure to call this at the end

    def call(self, inputs, **kwargs):
        assert inputs.dtype == tf.complex64

        ip_r = tf.math.real(inputs)
        ip_i = tf.math.imag(inputs)

        comp = tf.complex(ip_r, ip_i )
        ABS = tf.math.abs(comp)
        ANG = tf.math.angle(comp)

        ABS = K.relu(self.b + ABS)

        op_r = ABS * K.sin(ANG) #K.dot ??
        op_i = ABS * K.cos(ANG)

        # return single tensor in the call method
        return tf.complex(op_r, op_i)


real = tf.constant([2.25, 3.25])
imag = tf.constant([4.75, 5.75])

x = tf.complex(real, imag)

y = modrelu()(x)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    print(sess.run(y))

附言::我没有检查数学,所以您应该自己检查.

P.S.: I didn't check the math so you should check it by yourself.

这篇关于如何在Keras中构建此自定义图层?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆