我正在构建一个支持复数的NN。目前正在从事复杂的激活。根据Benjio的论文,这是一个很好的方法:
其中b是要学习的可训练参数。因此,我正在建立一个特殊的层来执行此激活。我是Keras的新手,已经被卡住了。我在下面创建了此代码,但是生成功能出错。我不知道发生了什么,我只是试图复制模板。请帮忙。
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 中,我没有添加任何内容,因为它是一个激活层,在实例化时不需要任何输入。
在build方法中,我尝试添加b。不知道我是否应该使用self.add_weight方法。理想情况下,我希望与输入的维数一样多。
在调用方法中,我很确定自己在做什么。很简单,我刚刚实现了该功能。
最后一个,compute_output_shape,我只是复制粘贴了模板。输出应该与输入相同,因为它只是一个激活层。
最后,关于它的价值的错误,我知道这是胡说八道
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
答案 0 :(得分:1)
您未正确编码图层,build
函数使用一个input_shape
参数,您可以使用该参数初始化图层的权重/参数。
您可以在Keras' source code中看到一个示例。
答案 1 :(得分:1)
您的代码有几个问题。
首先,我应该解决您从解释器得到的错误:
import numpy as np
a = np.array([[0, 1, 1, 1, 0, 0, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 1, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 1, 0, 0, 1, 0]])
ones = 5
to_add = ones - np.count_nonzero(a, axis=1)
for i in range(a.shape[0]):
idx = np.random.choice(np.flatnonzero(a[i, :] == 0), size=to_add[i], replace=False)
a[i, idx] = 1
TypeError: build() takes 1 positional argument but 2 were given
方法应采用build
参数。因此,您应该将构建方法声明为input_shape
第二个问题是build(self, input_shape)
方法中变量的形状不确定。您应该显式声明变量的形状。在您的情况下,build
数组应为np.random.rand
形状。
另一个问题是,您试图在input_shape
方法中返回2个结果([op_r, op_i]
)。我不是Keras的专家,但据我所知您做不到。每个Keras层应该只有一个输出。有关详情,请参见此处:https://github.com/keras-team/keras/issues/3061
但是,如果您使用tensorflow后端,则可以使用复数(call
)来返回复数的实数部分(tf.complex
和虚数部分(op_r
)。
这是op_i
层的有效实现,并带有简单的用法示例。它是TensorFlow 1.12.0的写法,它随其自己的Keras API实现一起分发,但我认为您可以轻松地将其用于原始Keras:
modrelu
附言::我没有检查数学,所以您应该自己检查。