基于自编码器处理NASA JM1.csv进行软件缺陷预测时的维度匹配错误及解码特征输出问题
解决自编码器处理JM1.csv时的两个问题
Let's break down and fix your two issues step by step:
1. 维度匹配错误 (ValueError: Input 0 of layer sequential_7 incompatible with the layer...)
问题原因
你错误地将解码器层当作编码器来调用了。从代码里的层名称来看,sequential_7大概率是你的解码器(因为你先定义了encoder再定义decoder,自动命名会按顺序生成sequential_6和sequential_7)。解码器的输入要求是编码器输出的5维特征,但你直接传入了21维的原始缩放数据,自然会出现维度不匹配的错误。
另外,你的解码器结构存在冗余:最后连续两层都是21维的Dense层,这不仅没必要,还可能影响模型性能。
2. 获取解码器输出的21维原始特征
问题原因
你当前只提取了编码器的输出(5维降维特征),而自编码器的完整输出就是解码器重建的21维特征,直接调用整个模型的predict方法就能得到。
修改后的完整代码
import pandas as pd import tensorflow as tf import matplotlib.pyplot as plt from sklearn.preprocessing import MinMaxScaler from sklearn.model_selection import train_test_split TRAIN_DATA_PATH = 'NASA/JM1.csv' TEST_DATA_PATH = 'NASA/JM1.csv' TARGET_NAME = 'HALSTEAD_LEVEL' train_data = pd.read_csv(TRAIN_DATA_PATH) test_data = pd.read_csv(TEST_DATA_PATH) x_train, y_train = train_data.drop(TARGET_NAME, axis=1), train_data[TARGET_NAME] x_test, y_test = test_data.drop(TARGET_NAME, axis=1), test_data[TARGET_NAME] def scale_datasets(x_train, x_test): """ Scale test and train data using MinMaxScaler """ standard_scaler = MinMaxScaler() x_train_scaled = pd.DataFrame( standard_scaler.fit_transform(x_train), columns=x_train.columns ) x_test_scaled = pd.DataFrame( standard_scaler.transform(x_test), columns = x_test.columns ) return x_train_scaled, x_test_scaled x_train_scaled, x_test_scaled = scale_datasets(x_train, x_test) class AutoEncoders(tf.keras.Model): def __init__(self): super().__init__() # 给编码器显式命名,避免依赖自动生成的名称 self.encoder = tf.keras.Sequential( [ tf.keras.layers.Dense(21, activation="relu"), tf.keras.layers.Dense(10, activation="relu"), tf.keras.layers.Dense(5, activation="relu") ], name="encoder" ) # 简化解码器结构,去掉冗余层,确保输出维度匹配输入的21维 self.decoder = tf.keras.Sequential( [ tf.keras.layers.Dense(10, activation="relu"), tf.keras.layers.Dense(21, activation="sigmoid") # 用sigmoid匹配MinMaxScaler的0-1范围 ], name="decoder" ) def call(self, inputs): encoded = self.encoder(inputs) decoded = self.decoder(encoded) return decoded # 初始化自编码器 auto_encoder = AutoEncoders() auto_encoder.compile( loss='mae', metrics=['mae'], optimizer='adam' ) # 训练模型 history = auto_encoder.fit( x_train_scaled, x_train_scaled, epochs=15, batch_size=32, validation_data=(x_test_scaled, x_test_scaled) ) # 获取编码器输出的5维降维特征 encoder = auto_encoder.get_layer("encoder") reduced_df = pd.DataFrame(encoder.predict(x_train_scaled)) reduced_df = reduced_df.add_prefix('feature_') print("5维降维特征:") display(reduced_df) # 获取解码器输出的21维重建特征 reconstructed_features = auto_encoder.predict(x_train_scaled) reconstructed_df = pd.DataFrame(reconstructed_features, columns=x_train_scaled.columns) print("21维重建特征:") display(reconstructed_df)
关键修改点说明
- 给编码器和解码器显式命名,避免依赖自动生成的
sequential_X名称,防止调用错误的层。 - 简化了解码器的结构,去掉了冗余的
Dense(5)和重复的Dense(21)层,确保输入输出维度匹配。 - 直接调用
auto_encoder.predict(x_train_scaled)获取解码器的21维重建特征,这是自编码器的默认输出。 - 用
sigmoid作为解码器最后一层的激活函数,匹配MinMaxScaler将数据缩放到0-1范围的预处理逻辑。
内容的提问来源于stack exchange,提问作者user9479133
相关产品推荐
相关产品推荐

