我试图实现zReLU提出的“关于复杂的价值卷积神经网络”,从尼坦古伯曼(2016)。
这个激活函数让我们把输出作为输入,如果实部和虚部都是正的。我设想了如何实现它的几种方法,但它们都使用tf.keras.backend.switch,这只是执行else if语句的一种方式。这里有一个例子。
def zrelu(z: Tensor) -> Tensor:
angle = tf.math.angle(z)
return tf.keras.backend.switch(0 <= angle,
tf.keras.backend.switch(angle <= pi / 2,
z,
tf.cast(0., dtype=z.dtype)),
tf.cast(0., dtype=z.dtype))这给了我想要的输出,当用数据测试激活函数时,它正确工作,但是,在像这样的模型上使用它时,我遇到了问题:
model = tf.keras.Sequential([
cvnn.layers.ComplexInput((4)),
cvnn.layers.ComplexDense(1, activation=tf.keras.layers.Activation(zrelu)),
cvnn.layers.ComplexDense(1, activation='linear')
])它在初始化程序行:TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'上给出了return tf.math.sqrt(6. / (fan_in + fan_out))。我相信,由于有一个开关,tf忽略了激活函数输出的大小,因此输出None形状,然后与下一个层发生冲突。这很奇怪,因为输出形状实际上是由tf.keras.layers.Activation强制的,因为有函数compute_output_shape,据我所知,函数compute_output_shape告诉tf输出将具有该形状。
我的问题可以通过以下两种方案中的任何一种解决:
compute_output_shape和如何告诉tf不要担心发布于 2021-08-28 10:46:15
我找到了一个解决这个问题的选择:
def zrelu(z: Tensor, epsilon=1e-7) -> Tensor:
imag_relu = tf.nn.relu(tf.math.imag(z))
real_relu = tf.nn.relu(tf.math.real(z))
ret_real = imag_relu*real_relu / (imag_relu + epsilon)
ret_imag = imag_relu*real_relu / (real_relu + epsilon)
ret_val = tf.complex(ret_real, ret_imag)
return ret_val这是可行的,但必须使用epsilon值,我不喜欢这个想法,因为它稍微改变了结果。我仍然愿意接受更好的选择(如果更好的话,我会把它们标记为新的解决方案)。
https://stackoverflow.com/questions/68963542
复制相似问题