我可以在 Keras 中定义两个不同的调用函数,一个用于正向映射,另一个用于反向映射

Can I define two different call functions in Keras, one for a foward map and another for an inverse map

我正在尝试使用 this paper 中描述的结构来实现 INN(可逆神经网络)。

我想知道是否可以创建一个块(如论文中所建议的那样)作为具有两个不同调用函数的自定义 keras 层。

基本结构如下所示:

import tensorflow as tf
import tensorflow.keras.layers as layers

class INNBlock(tf.keras.Model):
#inheriting from model instead of keras.layers.Layer, because I want manage the 
#underlying layer as well
    def __init__(self, size):
        super(INNBlock, self).__init__(name='innblock')
        #define layers
        self.denseL1 = layers.Dense(size,activation='relu')

    def call(self, inputs):
        #define the relationship between the layers for a foward call
        out = self.denseL1(inputs)
        return out

    def inverse_call(self, inputs):
        #define inverse relationship between the layer
        out = -self.denseL1(inputs) #use the same weights as the foward call
        return out

class INN(tf.keras.Model):
    def __init__(self,kenel_size,input_dim,min_clip,max_clip):
        super(INN, self).__init__()
        self.block_1 = INNBlock(size)
        self.block_2 = INNBlock(size)

    def call(self, inputs):
        x = self.block_1(inputs)
        x = self.block_2.inverse_call(y)
        x = self.block_1.inverse_call(x)
        return (y,x)

我已经想到的解决方案(但不是特别喜欢):

我希望有人知道,是否有办法实现这个。 提前谢谢你:)

您的代码没有任何问题。你可以试一下,它会正常运行。

call 方法是您只需执行 model_instance(input_tensor)layer_instance(input_tensor) 时的标准方法。

但是如果您定义另一个方法并在模型的调用方法中使用该方法也没有错。将会发生的只是:

  • 如果您使用 the_block(input_tensor),它将使用 the_block.call(input_tensor)
  • 如果你在 layer/model 之外的某个地方使用 the_block.inverse_call(input_tensor),它将无法构建 Keras 模型(任何东西都不能在层之外)
  • 如果你在layer/model中使用the_block.inverse_call(input_tensor)(这就是你在做的),它和直接写操作是完全一样的。您只是将它包装在另一个函数中。

对于Keras/Tensorflow来说,inverse_call没有什么特别的。您可以在任何可以使用任何其他 keras/tensorflow 函数的地方使用它。


梯度会更新两次吗?

不完全是两次,但是肯定会算进去的。系统在计算loss相对于权重的梯度时,如果loss是用inverse_call构建的,那么它将参与梯度计算。

但像往常一样,每批更新一次。