在tensorflow 2中将keras功能模型转换为keras类

时间:2019-10-14 18:41:20

标签: tensorflow tf.keras

我正在尝试将Keras功能模型转换为从tensorflow.keras.models.Model派生的类,而我面临2个问题。   1.我需要使用tensorflow.keras.layers.multiply乘以2层,但是它返回一个ValueError: A merge layer should be called on a list of inputs。   2.如果我删除此layern从而使用经典的CNN,它将返回tensorflow.python.eager.core._SymbolicException:Inputs to eager execution function cannot be Keras symbolic tensors, but found [<tf.Tensor 'patch:0' shape=(None, 64, 64, 3) dtype=float32>]

我希望获得一些有关转换代码的指导。我正在使用Python 3.7,TensorFlow 2.0rc2和Keras 2.3.0。我定义的类如下:

class TestCNN(Model):
    """
      conv1 > conv2 > fc1 > fc2 > alpha * fc2 > Sigmoid > output
    """

    def __init__(self, input_dimension, n_category,**kwargs):
        """
        Instanciator
        :param input_dimension: tuple of int, theoretically (patch_size x patch_size x channels)
        :param n_category: int, the number of categories to classify,
        :param weight_decay: float, weight decay parameter for all the kernel regularizers
        :return: the Keras model
        """

        super(TestCNN, self).__init__(name='milcnn', **kwargs)

        self.input_dimension = input_dimension
        self.n_category = n_category

        self.conv1 = Conv2D(36, activation='relu', name='conv1/relu')
        self.conv1_maxpooling = MaxPooling2D((2, 2), name='conv1/maxpooling')
        self.conv2 = Conv2D(48, activation='relu', name='conv2/relu')
        self.conv2_maxpooling = MaxPooling2D((2, 2), name='conv2/maxpooling')
        self.flatten1 = Flatten(name='flatten1')

        self.fc1 = Dense(512, activation='relu', name='fc1/relu')
        self.fc2 = Dense(512, activation='relu', name='fc2/relu')
        self.alpha = TestLayer(layer_dim=128, name='alpha')
        self.output1 = TestSigmoid(output_dimension=n_category, name='output_layer')

    @tensorflow.function
    def call(self, x):

        x = self.conv1(x)
        x = self.conv1_maxpooling(x)

        x = self.conv2(x)
        x = self.conv2_maxpooling(x)
        x = self.flatten1(x)

        x = self.fc1(x)
        x = self.fc2(x)

        alpha_times_fc2 = multiply([alpha_output, fc2_output], name='alpha_times_fc2')

        return self.output1(alpha_times_fc2)


    def build(self, **kwargs):

        inputs = Input(shape=self.input_dimension, dtype='float32', name='patch')
        outputs = self.call(inputs)
        super(TestCNN, self).__init__(name="TestCNN", inputs=inputs, outputs=outputs, **kwargs)

然后,在主循环中,按如下所示创建实例:

testcnn = TestCNN(input_dimension=input_dimension, n_category=training_set.category_count)

optimizer = tensorflow.keras.optimizers.Adam(
            lr=parameter['training']['adam']['learning_rate'],
            beta_1=parameter['training']['adam']['beta1'],
            beta_2=parameter['training']['adam']['beta2'])

metrics_list = [tensorflow.keras.metrics.TruePositives]

loss_function = tensorflow.keras.losses.categorical_crossentropy
loss_metrics = tensorflow.keras.metrics.Mean()

milcnn.build()
milcnn.summary()

此代码引发tensorflow.python.eager.core._SymbolicException。如果我注释掉某些行并直接返回fc2层的结果,那么我得到了ValueError

1 个答案:

答案 0 :(得分:0)

我在模型中添加了build()函数的注释器,并在主脚本中按如下所示对其进行了调用:

testcnn.build(input_dimension)
testcnn.compile(optimizer=adam_optimizer, loss=loss_function, metrics=metrics_list)
testcnn.summary()

输入维度是一个格式如下的列表:

input_dimension = (batch_size, image_size, image_size, channels)