
简介本资源是一份面向高校人工智能课程学习者的完整大作业实践包聚焦图像情绪识别这一典型AI应用场景适用于计算机、人工智能、自动化等专业学生完成课程设计、期末项目或毕设初期开发。压缩包共25个文件含11个Python源码覆盖CNN/VGG/ResNet多模型实现、数据预处理、可视化及对比分析、6个Markdown文档含详细使用说明、模型测试指南与目录结构解析、3个辅助工具压缩包人脸标注、Fer2013数据集PyTorch适配、表情识别开源项目、2个PDF实验报告开题与终期报告、1个Haar级联XML人脸检测模型、1个MP4演示视频及1个DOC进展报告整体22.54MB。已有251人学习下载所有代码均经实机测试运行成功答辩平均分96分提供清晰的README引导、模块化代码结构与多模型横向对比脚本model_All_Compare.py便于理解算法差异、快速复现结果并在此基础上拓展功能。1. 这不是“调个API就能跑”的情绪识别demo它是一套可答辩、可复现、可拆解的完整课程级图像情绪分析流水线你手头那套「人脸识别表情分类」代码大概率只在Jupyter里跑通过单张图——而这份2021年广工大《人工智能导论》第二组课程设计是真正走完「数据采集→人脸裁剪→模型训练→对比实验→可视化分析→报告撰写」全链路的硬核作业。它不依赖云端API所有模型CNN/VGG/ResNet全部用PyTorch从零实现不靠预训练权重糊弄Fer2013数据集手动划分train/val/test三份连开题报告、进展报告、期末报告PDF都齐备答辩平均分96分不是虚的。适合两类人一是刚学完《机器学习》但卡在“怎么把课上公式变成能跑的代码”的本科生二是需要快速搭建教学案例、避免学生抄网上的残缺项目模板的授课老师。它解决的不是“能不能识别”而是“怎么让一个没跑过GPU训练的新手在3小时内复现baseline并理解每个模块为什么这么写”。提示这不是工业级部署方案没有Flask接口、没有Docker封装、不支持实时视频流推理。它的价值恰恰在于“裸露”——所有数据路径、超参、模型结构、评估逻辑全部摊开连haarcascade_frontalface_default.xml这种OpenCV老古董级检测器都保留原样方便你对照课本讲义逐行debug。2. 从Fer2013原始数据到可训练数据集四步数据工程实操2.1 数据来源与原始结构解析项目打包了Fer2013-pytorch-CNN-VGG-Resnet--master.zip解压后核心是fer2013.csv——这个CSV文件包含35887行每行格式为emotion,pixels,Usage其中pixels字段是2304个空格分隔的整数48×48灰度图展平emotion为0~6共7类anger/disgust/fear/happy/sad/surprise/neutral。注意原始Fer2013官方数据集的Usage列标记为Training/PublicTest/PrivateTest但本项目未直接使用该划分而是通过data_separation.py重采样生成自己的train/val/test集这是关键差异点。2.2 手动构建图像目录树为什么不用Pandas直接读CSVdata_separation.py脚本执行后会在face_images/下生成标准ImageFolder结构face_images/ ├── train/ │ ├── 0/ # anger │ ├── 1/ # disgust │ └── ... ├── val/ └── test/这样做有三个硬性理由PyTorch DataLoader兼容性避免每次训练都用pd.read_csv()加载整个CSV再reshape内存占用直降80%数据增强可插拔transforms.Compose([transforms.RandomHorizontalFlip(), transforms.ToTensor()])只能作用于ImageFolder对象跨模型复用CNN/VGG/ResNet三个模型的dataset参数完全一致无需为每个模型单独写数据加载逻辑。# data_separation.py 关键片段已加注释 import pandas as pd import numpy as np from PIL import Image import os # 1. 读取原始CSV过滤掉Usage为PrivateTest的样本因标签不可见仅用于最终评测 df pd.read_csv(fer2013.csv) df df[df[Usage] ! PrivateTest] # 2. 按emotion分组确保每类至少有500张图才参与训练防小类过拟合 min_samples_per_class 500 class_counts df[emotion].value_counts() valid_classes class_counts[class_counts min_samples_per_class].index.tolist() df df[df[emotion].isin(valid_classes)] # 3. 手动划分按7:1:2比例切分且保证每类在各集合中比例均衡 for emotion in range(7): class_df df[df[emotion] emotion] n_total len(class_df) n_train int(n_total * 0.7) n_val int(n_total * 0.1) # 随机打乱后切片非简单切片 shuffled class_df.sample(frac1, random_state42).reset_index(dropTrue) train_part shuffled.iloc[:n_train] val_part shuffled.iloc[n_train:n_trainn_val] test_part shuffled.iloc[n_trainn_val:] # 4. 写入对应目录核心像素转PIL.Image再保存为PNG for idx, row in train_part.iterrows(): pixels np.array(row[pixels].split(), dtypenp.uint8).reshape(48, 48) img Image.fromarray(pixels) img.save(fface_images/train/{row[emotion]}/{idx}.png)2.3 人脸区域裁剪为什么用haarcascade而不直接用MTCNNmodel_CNN.py中FaceDetector类调用cv2.CascadeClassifier(haarcascade_frontalface_default.xml)而非更准的深度学习检测器原因很务实课程约束《人工智能导论》课时有限要求“用OpenCV基础模块完成预处理”MTCNN需额外装torchvision且推理慢数据适配性Fer2013全是正脸灰度图haar检测器召回率92%误检主要在disgust类嘴角扭曲易被误判为闭眼但后续data_view.py提供了可视化校验工具可解释性教学让学生亲手调scaleFactor1.1和minNeighbors5参数理解检测器敏感度与漏检率的权衡。2.4 数据可视化验证data_view.py的三个救命功能运行python data_view.py --mode show_sample --class_id 3happy类会弹出9宫格样本图确认裁剪质量--mode show_distribution生成各类别数量柱状图避免训练集某类样本过少--mode show_heatmap对test集预测结果画混淆矩阵热力图——这是答辩时评委最爱看的一页图。注意data_view.py依赖matplotlib和seaborn若报错ModuleNotFoundError: No module named seaborn请先pip install seaborn0.12.2高版本seaborn在Python3.7下与旧版PyTorch有兼容问题。3. 三大模型源码级对比CNN/VGG/ResNet在Fer2013上的真实性能边界3.1 基础CNN模型model_CNN.py的三层卷积设计哲学class SimpleCNN(nn.Module): def __init__(self, num_classes7): super().__init__() self.conv1 nn.Conv2d(1, 32, kernel_size3, padding1) # 输入通道1灰度图 self.bn1 nn.BatchNorm2d(32) self.conv2 nn.Conv2d(32, 64, kernel_size3, padding1) self.bn2 nn.BatchNorm2d(64) self.conv3 nn.Conv2d(64, 128, kernel_size3, padding1) self.bn3 nn.BatchNorm2d(128) self.pool nn.MaxPool2d(2) self.dropout nn.Dropout(0.25) self.fc1 nn.Linear(128 * 6 * 6, 512) # 48-24-12-6三次池化后尺寸 self.fc2 nn.Linear(512, num_classes) def forward(self, x): x self.pool(F.relu(self.bn1(self.conv1(x)))) x self.pool(F.relu(self.bn2(self.conv2(x)))) x self.pool(F.relu(self.bn3(self.conv3(x)))) x torch.flatten(x, 1) x F.relu(self.fc1(x)) x self.dropout(x) x self.fc2(x) return x关键设计点padding1保证每次卷积后尺寸不变配合MaxPool2d(2)精准控制下采样节奏BatchNorm2d放在ReLU前非后这是2021年课程要求的“标准写法”虽非最优但符合教学规范fc1输入维度128*6*6来自48→24→12→6的三次2倍下采样必须手算验证否则torch.flatten报错。3.2 VGG变体model_VGG.py如何用11层网络榨干48×48小图VGG原始结构如VGG11输入需224×224本项目将其压缩为VGG_mini移除所有nn.AdaptiveAvgPool2d改用固定尺寸nn.AvgPool2d(2)将features中最后两个Conv2d(512-512)改为Conv2d(256-256)降低参数量classifier部分精简为[nn.Linear(256*3*3, 256), nn.ReLU(), nn.Dropout(0.5), nn.Linear(256, 7)]。这样调整后VGG_mini参数量约1.2M原VGG11为132M在GTX1050Ti上单batch训练时间仅比CNN多0.3秒但top1准确率提升4.2%见model_All_Compare.py输出表格。3.3 ResNet轻量化model_ResNet.py的残差块魔改标准ResNet18需输入≥112×112本项目采用ResNet18_mini第一个conv1将kernel_size从7改为3stride从2改为1避免48×48图被过度下采样layer1第一个残差块输出通道从64减至32layer2从128减至64全局平均池化层nn.AdaptiveAvgPool2d((1,1))保留但fc层输入维度从512改为64。这种改法使ResNet18_mini在Fer2013上达到最高准确率68.3%但训练不稳定——model_ResNet_test.py中设置了torch.backends.cudnn.benchmark True加速却导致首次epoch loss震荡剧烈这是典型的小图残差结构冲突现象。3.4 模型对比实验model_All_Compare.py的自动化评测框架该脚本会自动执行加载三个模型权重model_CNN.pth/model_VGG.pth/model_ResNet.pth在test集上分别计算accuracy/precision/recall/f1-score生成results_comparison.csv含每类详细指标绘制ROC曲线对7类做one-vs-rest。关键参数--batch_size 64显存不足时需降至32、--num_workers 2Windows系统必须设为0否则DataLoader卡死。4. 训练全流程避坑指南GPU环境、超参、收敛性三重雷区4.1 GPU环境配置CUDA版本与PyTorch的隐性绑定项目requirements.txt指定torch1.8.1cu111这意味着必须安装CUDA 11.1非11.0或11.2nvcc --version必须输出Cuda compilation tools, release 11.1若用RTX30系显卡Ampere架构torch1.8.1无法启用Tensor Cores但强行升级到torch1.10.0cu113会导致model_VGG_test.py中nn.AvgPool2d计算错误已验证解决方案保持CUDA 11.1 PyTorch 1.8.1用model_CNN_GPU.py中的torch.cuda.amp.autocast()手动开启混合精度提速18%且loss曲线更平滑。4.2 超参数陷阱学习率衰减与早停机制的致命组合model_CNN.py中lr_scheduler.StepLR(optimizer, step_size7, gamma0.1)与EarlyStopping(patience5)同时启用时现象第12 epoch后val_loss突然飙升但scheduler仍在第14 epoch才衰减lr导致模型崩溃原因patience5指连续5个epoch无改善即触发早停但step_size7意味着lr在第7/14/21...epoch衰减二者周期错位解决统一为patience7或改用ReduceLROnPlateau见model_VGG.py第89行监听val_loss下降时才衰减lr。4.3 收敛性玄学batch_size32时acc卡在62%不上升现象CNN模型在train集acc达95%但val集停滞在62%验证集loss波动剧烈原因Fer2013中disgust类样本仅958张占2.7%batch_size32时单个batch极可能不含该类样本导致梯度更新偏差解决在data_separation.py中启用WeightedRandomSampler按类别频率反比赋予权重代码已写在model_CNN_test.py第45行注释里取消注释即可生效。4.4 模型保存与加载.pth文件的序列化隐患model_ResNet.py中torch.save(model.state_dict(), model_ResNet.pth)看似标准但现象加载后model.eval()时BatchNorm2d.running_mean为全零导致推理结果全错原因训练时未调用model.train()BN层未更新统计量解决保存前必须执行model.train()或改用torch.save({model_state_dict: model.state_dict(), optimizer_state_dict: optimizer.state_dict()}, checkpoint.pth)保存完整状态。4.5 视频推理翻车example_dsh.mp4无法实时处理现象python video_inference.py --video example_dsh.mp4运行后CPU占用100%帧率1fps原因cv2.VideoCapture默认用CAP_ANY后端在Windows上常选错解码器解决强制指定后端cv2.VideoCapture(example_dsh.mp4, cv2.CAP_FFMPEG)并添加cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)减少缓存延迟。5. 实验报告写作实战从代码输出到答辩PPT的转化技巧5.1 图表生成data_view.py与model_All_Compare.py的报告直出能力运行python model_All_Compare.py --generate_report会自动生成confusion_matrix.png7×7混淆矩阵字体大小设为12确保答辩投影清晰roc_curve.png7条ROC曲线AUC值标在图例中training_history.png三模型loss/acc对比曲线用不同线型区分CNN实线/VGG虚线/ResNet点划线。这些图直接复制进Word报告不要截图——plt.savefig()已设置dpi300和bbox_inchestight矢量图缩放不失真。5.2 报告结构拆解《人工智能导论》第二组报告的黄金模板其《人工智能导论》第二组-期末课程项目报告.pdf采用五段式章节核心内容教学意图1. 问题定义用FER2013数据集统计表含各类样本数/占比说明任务难度引用2013年原始论文证明数据权威性展示问题意识非简单复述题目2. 方法论对比表格列出CNN/VGG/ResNet的层数/参数量/GPU显存占用/单epoch耗时强调“为何选这三种模型”体现技术选型能力非堆砌代码3. 实验结果混淆矩阵热力图TOP3错误案例如把fear误判为sad的原始图裁剪图预测概率附人工归因“因眉毛下压特征相似”展示分析深度非只报准确率4. 局限性明确写出“对侧脸/遮挡/光照变化鲁棒性差”并给出改进方向“可引入GAN生成对抗样本增强”体现批判性思维非回避缺陷5. 总结与致谢致谢指导教师时具体到“感谢张老师在ResNet梯度爆炸问题上提供的L2正则化建议”体现过程真实性非套话5.3 答辩话术设计如何把“调参失败”说成“主动探索”当评委问“为什么VGG准确率比CNN高但训练时间长”时标准回答是“我们刻意将VGG的卷积核数量减半从64→32使其参数量与CNN接近1.3M vs 1.1M此时VGG仍高出4.2%准确率证明更深的网络结构对小图特征提取有本质优势——这验证了课程中‘深度增加表达能力’的核心论点。”血泪经验答辩时绝不说“我试了很多次”而要说“我们设计了三组对照实验第一组固定lr0.01第二组用StepLR第三组用ReduceLROnPlateau最终选择第三组因其val_loss方差最小”。5.4 开题报告埋点如何让中期检查不尴尬开题报告.pdf中“预期困难”章节写了三条“Fer2013数据集存在标注噪声计划用交叉验证评估标签可靠性” → 后续data_view.py中--mode show_label_consistency功能即为此开发“ResNet在小图上易过拟合拟采用DropPath正则化” → 实际用了更简单的DropBlock见model_ResNet.py第152行“视频实时推理延迟高考虑用TensorRT优化” → 最终用FFmpeg硬解码解决但报告里仍保留此条体现规划前瞻性。后悔药从那以后我每次写开题报告都会在“预期困难”里故意写一条“技术上可行但工作量极大”的点如“尝试用Transformer替代CNN”这样中期检查时只要展示出“已调研但暂不实施”的记录评委就觉得你进度扎实。希望帮到你。本文还有配套的精品资源点击获取