SuccessiveAutoencoder预测输出形状异常求助:期望(6000,5)得(6000,23)
问题排查与修复
你的问题核心在于移除输出层后没有重新定义模型结构,导致最终保存的self.model仍然指向包含原始输出层(23维)的完整自编码器,而非仅保留编码器部分。
具体分析
在fit方法的最后,你执行了model.layers.pop()来移除输出层,但Keras的Model对象是不可变的——一旦创建,它的输入输出计算路径就固定了。仅仅从layers列表中移除元素并不会改变现有Model实例的计算逻辑,所以self.model仍然会按照原来的完整路径(输入→所有隐藏层→输出层)进行预测,最终输出23维结果。
修复步骤
需要在移除输出层后,基于输入层和最后一个隐藏层的输出重新创建Model,这样才能得到仅输出压缩特征的编码器模型。
修改fit方法的最后部分:
# Get rid of last layer, and stored the model model.layers.pop() # 关键修复:重新构建编码器模型,仅保留输入到最后一个隐藏层的路径 self.model = Model(inputs=model.layers[0].input, outputs=model.layers[-1].output) # 预测阶段不需要编译,可省略此步骤 # model.compile(loss = 'mean_squared_error', optimizer = 'adam')
额外验证点
另外,检查你的初始化参数:默认hidden_layers=5、units_nbr=5,最终编码器的输出是第5个隐藏层的输出(5维),完全符合你的预期维度。
完整修改后的fit方法片段
def fit(self, X, epochs): """Run the algorithm, creating the autoencoder and calibrating it""" # Create the model and train it print('/ Training Hidden Layer 1') model = self.create_model(X) model.compile(loss = 'mean_squared_error', optimizer = 'adam') h = model.fit(X, X, epochs = epochs, verbose = 0) print('Last loss: {}'.format(h.history['loss'][-1])) # Incrementally add layer, and train these new layers for incr in range(2, self.hidden_layers + 1): print('/ Training Hidden Layer {}'.format(str(incr))) model = self.add_layer(model, incr) model.compile(loss = 'mean_squared_error', optimizer = 'adam') h = model.fit(X, X, epochs = epochs, verbose = 0) print('Last loss: {}'.format(h.history['loss'][-1])) # If the user wants to run the calibration again over the complete model if self.fine_tuning == 'y': # Final training print('/ Final Tuning') for layer in model.layers: layer.trainable = True model.compile(loss = 'mean_squared_error', optimizer = 'adam') h = model.fit(X, X, epochs = epochs, verbose = 0) print('Last loss: {}'.format(h.history['loss'][-1])) # Get rid of last layer, and stored the model model.layers.pop() # 重新构建编码器模型 self.model = Model(inputs=model.layers[0].input, outputs=model.layers[-1].output)
测试验证
修改后,调用predict(x)时,输入形状(6000,23)会输出预期的(6000,5)结果。
内容的提问来源于stack exchange,提问作者Gaël Pagès




