fit() 方法 returns 使用 Keras 子类时出现 ValueError API

fit() method returns ValueError when using Keras subclassing API

我正在尝试通过从 Keras 功能 API 转移到子 classing API 来整理我的代码。到目前为止,我想出的 class 如下:

class FeedForwardNN(Model):
    def __init__(self, params):

        super().__init__()
        self.params = params
        self.layout = params['layout']

        # Define layers
        self.dense = Dense(units=params['layout'][1],
                           activation=params['activation'],
                           kernel_initializer=params['initializer'])
        
        self.output_layer = Dense(units=params['layout'][-1],
                            kernel_initializer=params['initializer'])
        
        self.dropout = Dropout(params['dropout'])
        self.batch_norm = BatchNormalization()
    
    def call(self, x):

        for layer in self.layout[1:-1]:
            x = self.dropout(self.dense(x))

            if self.params['batch_norm']:
                x = self.batch_norm(x)
        
        x = self.output_layer(x)
        
        return x

其中布局是每一层(包括输入和输出层)中神经元的列表。

但是在拟合模型的时候,出现如下错误:

        ValueError: Input 0 of layer "dense" is incompatible with the layer: expected axis -1 of input shape to have value 5, but received input with shape (None, 100)
    
    
    Call arguments received:
      • x=tf.Tensor(shape=(None, 5), dtype=float32)

这似乎发生在线上:

x = self.dropout(self.dense(x))

我检查了传递给 fit() 方法的训练数据 X 的形状,它似乎具有正确的形状,即(观察数,预测变量数)。

有谁知道我的错误在哪里?

问题是您在 for 循环中一遍又一遍地使用 相同 self.dense

for layer in self.layout[1:-1]:
    x = self.dropout(self.dense(x))

第一个循环后,x 的形状为 (batch, 100)。然后在第二个循环中,不是将此 x 传递给第二个 Dense 层(您似乎没有首先创建),而是 re-pass 它到第一个Dense 层,需要形状 (batch, 5),导致错误。

您可以在__init__

中创建如下密集层列表
self.denses = [Dense(units=self.layout[i],
                   activation=params['activation'],
                   kernel_initializer=params['initializer']) for i in self.layout[1:-1]]

并依次调用它们

for dense_layer in self.denses:
    x = self.dropout(dense_layer(x))