CNN模型训练准确率100%但测试预测用户失效,数据集还是模型问题?
项目问题分析:训练准确率100%但测试预测失效
项目核心模块
数据集创建模块
- 实时图像采集:捕获用户实时图像
- 添加随机图像:获取实时图像后,添加随机图像扩充数据集
- 训练测试划分:将数据集拆分至训练与测试文件夹
- CSV文件创建:为训练和测试数据集生成标注用CSV文件
- 图像缩放:统一图像尺寸并替换至原路径
CNN模型评估模块
- 图像转数组:将训练与测试文件夹中的图像转换为数组
- 模型训练:使用转换后的数组训练模型,若准确率低于0.85可切换模型架构
- 模型细节:采用Adam优化器,以准确率为评估指标,具体实现代码:
def train_test_save_cnn_model(self,arch_type=1): #assigns trauin_path in src_train src_train=self.train_d_path #assigns trauin_path in src_test src_test=self.test_d_path #stores the x_train,y_train data by calling images_to_input_array function with src_train path [x_train,y_train]=self.images_to_input_array(src_train) #stores the x_test,y_test data by calling images_to_input_array function with src_test path [x_test,y_test]=self.images_to_input_array(src_test) #if arch_type is 1 enters 1 st model_architecture if arch_type==1: #cnn architeture model = Sequential() model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(int(self.org_img_height),int(self.org_img_width),3))) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(128, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Flatten()) model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(1, activation='sigmoid')) elif arch_type==2: model = Sequential() model.add(Conv2D(32, (3, 3), activation='relu', padding='same', name='conv_1', input_shape=(150, 150, 3))) model.add(MaxPooling2D((2, 2), name='maxpool_1')) model.add(Conv2D(64, (3, 3), activation='relu', padding='same', name='conv_2')) model.add(MaxPooling2D((2, 2), name='maxpool_2')) model.add(Conv2D(128, (3, 3), activation='relu', padding='same', name='conv_3')) model.add(MaxPooling2D((2, 2), name='maxpool_3')) model.add(Conv2D(128, (3, 3), activation='relu', padding='same', name='conv_4')) model.add(MaxPooling2D((2, 2), name='maxpool_4')) model.add(Flatten()) model.add(Dropout(0.5)) model.add(Dense(512, activation='relu', name='dense_1')) model.add(Dense(128, activation='relu', name='dense_2')) model.add(Dense(1, activation='sigmoid', name='output')) #It initialize optimizer,loss_functin,metrics before fitting to train data. model.compile(optimizer='adam', loss='binary_crossentropy',metrics=['accuracy']) #Train_data fits to model model.fit(x_train, y_train, epochs=7) # Save the model architecture to a file model_json = model.to_json() with open(os.path.join(self.user_model_path,f"{self.username}_model_architecture.json"), "w") as json_file: json_file.write(model_json) #Saves the model weights in specific_folder model.save_weights(os.path.join(self.user_model_path,f"{self.username}_model_save_weights.h5")) model.save(os.path.join(self.user_model_path,f"{self.username}_model.h5")) #return the test_acc and test_loss by evaluting model test_loss, test_acc = model.evaluate(x_test,y_test,verbose=2) return [test_loss,test_acc]
已实施的模型优化
- 背景修正:采用Haarcascade裁剪图像,解决背景记忆问题
- 数据增强:添加更多用户图像提升多样性
训练与测试现状
- 训练准确率达到100%
- 测试阶段无法准确预测目标用户
数据集详情
- 目标用户样本:100张原始图像 + 200张扩充图像
- 负样本:200张Kaggle随机图像 + 100张其他两位用户的图像
问题根源分析
数据集层面可能的问题
- 训练/测试分布不一致:如果划分时未保证训练集和测试集的样本分布一致(比如训练集目标用户图像都是特定角度、光照,测试集是完全不同的场景;或负样本在训练/测试集中的类型差异大),模型无法泛化到测试数据。
- 样本类别不平衡:需确认训练集中正负样本比例是否合理。若训练集目标用户样本占比过高,模型会倾向于记住样本而非学习通用特征;若负样本与目标用户特征差异过大,模型会学到“非负样本即目标”的错误规律。
- 数据扩充有效性不足:如果扩充的用户图像只是简单复制或轻微变换,未覆盖足够的角度、光照、表情变化,模型只能记住训练集中的固定特征,无法适配测试场景。
- 预处理一致性问题:训练和测试阶段的Haarcascade裁剪逻辑是否完全一致?若测试时裁剪的人脸区域位置、大小与训练时偏差较大,模型无法匹配特征。
模型层面可能的问题
- 严重过拟合:训练准确率100%是典型的过拟合表现。当前模型虽有Dropout,但训练轮数(7轮)可能过多,或模型容量相对于数据集过大,导致模型记住了训练样本的噪声而非通用特征(尤其是第二个架构,层数和参数更多,更容易过拟合小数据集)。
- 缺失验证环节:训练流程中未使用验证集监控,无法及时发现过拟合趋势。加入
validation_data参数,观察验证准确率是否随训练轮数下降,可提前终止训练。 - 评估指标单一:仅用准确率评估不够,尤其是样本不平衡时。需查看混淆矩阵,确认模型是误判目标用户为负样本,还是误判负样本为目标用户,定位具体错误类型。
- 输入预处理不一致:训练和测试时的图像转数组、缩放、归一化等步骤是否完全一致?比如训练时做了像素值归一化(除以255)但测试时未做,会导致输入分布不一致,预测失效。
内容的提问来源于stack exchange,提问作者Pothula Vinitha reddy
相关产品推荐
相关产品推荐

