使用Keras函数式API引入自定义层时出现问题

我正在使用Keras函数式API引入一个自定义层GaussianLayer,该层返回一个包含两个元素的列表(见下面的call方法):

import tensorflow as tffrom keras.layers import Input, Densefrom keras.models import Modelfrom tensorflow.keras.layers import Layerdef gaussian_loss(y_true, y_pred):    """    y_true是标量(浮点数)    y_pred是张量[mu, sigma]    """    print(y_pred.shape)    return tf.reduce_mean(0.5*tf.log(y_pred[1]) + 0.5*tf.div(tf.square(y_true - y_pred[0]), y_pred[0])) + 1class GaussianLayer(Layer):    def __init__(self, output_dim, **kwargs):        self.output_dim = output_dim        super(GaussianLayer, self).__init__(**kwargs)    def build(self, input_shape):        self.kernel_1 = self.add_weight(name='kernel',                                       shape=(30, self.output_dim),                                      initializer='uniform',                                      trainable=True)        self.kernel_2 = self.add_weight(name='kernel',                                       shape=(30, self.output_dim),                                      initializer='uniform',                                      trainable=True)        self.bias_1 = self.add_weight(name='bias',                                    shape=(self.output_dim),                                    initializer='zeros',                                    trainable=True)        self.bias_2 = self.add_weight(name='bias',                                    shape=(self.output_dim),                                    initializer='zeros',                                    trainable=True)        super(GaussianLayer, self).build(input_shape)     def call(self, x):        output_mu  = K.dot(x, self.kernel_1) + self.bias_1        output_sig = K.dot(x, self.kernel_2) + self.bias_2        output_sig_pos = K.log(1 + K.exp(output_sig)) + 1e-06          return [output_mu, output_sig_pos]    def compute_output_shape(self, input_shape):        return (input_shape[0], self.output_dim)# This returns a tensorinputs = Input(shape=(1,))x = Dense(24, activation='relu')(inputs)x = Dense(30, activation='relu')(x)predictions = GaussianLayer(1)(x)model = Model(inputs, predictions)model.compile(loss=gaussian_loss, optimizer='adam')model.fit(train_x, train_y, epochs=600)

遗憾的是这段代码在执行时出现了AttributeError错误:

----------------------------------------------------------------AttributeError                 Traceback (most recent call last)<ipython-input-200-e93218491799> in <module>()     49 x = Dense(24, activation='relu')(inputs)     50 x = Dense(30, activation='relu')(x)---> 51 predictions = GaussianLayer(1)(x)     52      53 model = Model(inputs, predictions)/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py in __call__(self, inputs, *args, **kwargs)    783       if in_deferred_mode or build_graph and have_all_keras_metadata(inputs):    784         inputs, outputs = self._set_connectivity_metadata_(--> 785             inputs, outputs, args, kwargs)    786       if context.executing_eagerly():    787         return outputs/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py in _set_connectivity_metadata_(self, inputs, outputs, args, kwargs)    895     kwargs.pop('mask', None)  # `mask` should not be serialized.    896     self._add_inbound_node(--> 897         input_tensors=inputs, output_tensors=outputs, arguments=kwargs)    898     return inputs, outputs    899 /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py in _add_inbound_node(self, input_tensors, output_tensors, arguments)   1076         input_tensors=input_tensors,   1077         output_tensors=output_tensors,-> 1078         arguments=arguments)   1079    1080     # Update tensor history metadata./Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py in __init__(self, outbound_layer, inbound_layers, node_indices, tensor_indices, input_tensors, output_tensors, arguments)   1747         # For compatibility with external Keras, we use the deprecated   1748         # accessor here.-> 1749         layer.outbound_nodes.append(self)   1750     # For compatibility with external Keras, we use the deprecated   1751     # accessor here.AttributeError: 'Dense' object has no attribute 'outbound_nodes'

我知道为了将列表传递给gaussian_loss,我需要使用函数式API,但遗憾的是这似乎也行不通。


回答:

首先,不要混合使用kerastensorflow.keras模块。在你的代码中只使用其中一个。

其次,通过在bias变量的形状后面添加一个,来修正它们的形状,使其成为元组,即shape=(self.output_dim,)

第三,如果你的自定义层返回一个包含两个张量的列表作为输出,那么输出形状必须与此一致,即:

def compute_output_shape(self, input_shape):    return [(input_shape[0], self.output_dim), (input_shape[0], self.output_dim)]

Related Posts

Flatten and back keras

我正在尝试使用自编码器获取简单向量中的值 这是我的代码…

如何按索引访问PyTorch模型参数

如果我的网络有10层,包括偏置项,如何仅通过索引访问第…

Python中多元逻辑回归显示错误

我试图使用逻辑回归进行预测,并使用Python和skl…

在MACOS上安装NLTK

我在我的2015款Mac Pro上尝试安装NLTK,操…

如何在R中将通过RFE选择的变量插入到机器学习模型中?

我想使用递归特征消除方法来选择最重要的特征,然后将这些…

CountVectorizer 错误:ValueError: setting an array element with a sequence

我有一个包含144条学生反馈的数据集,其中有72条正面…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注