深度学习P6周:VGG-16算法-Pytorch实现人脸识别
本文为365天深度学习训练营中的学习记录博客原作者K同学啊学习目的1.在理解CNN的基础上认识VGG-16架构。2.调用官方的VGG-16架构。注VGG-16由16个卷积层和3个全连接层组成因此具有较深的网络结构。有助于网络学习到更加抽象和复杂的特征。卷积层的设计VGG-16的卷积层全部采用3×3的卷积核和步长为1的卷积操作同时在卷积层之后都接有Relu激活函数。这种设计的好处在于通过堆叠多个较小的卷积核可以提高网络的非线性建模能力同时减少了参数数量从而降低了过拟合的风险。池化层在卷积层之后VGG-16使用最大池化层来减少特征图的空间尺寸帮助提取更加显著的特征并减少计算量。全连接层VGG-16在卷积层之后接有3个全连接层最后一个全连接层输出与类别数相对应的向量用于进行分类。VGG-16包含了16个隐藏层13个卷积层和3个全连接层故称为 VGG-16。网络架构图前期准备导入相关库并确定使用GPUimport torch import torch.nn as nn import torchvision.transforms as transforms import torchvision from torchvision import transforms, datasets import os,PIL,pathlib,warnings warnings.filterwarnings(ignore) #忽略警告信息 device torch.device(cuda if torch.cuda.is_available() else cpu) device导入数据查看子文件import os,PIL,random,pathlib data_dir ./6-data/ data_dir pathlib.Path(data_dir) data_paths list(data_dir.glob(*)) classeNames [str(path).split(\\)[1] for path in data_paths] classeNames对图像进行标准化RGB彩图常规操作# 关于transforms.Compose的更多介绍可以参考https://blog.csdn.net/qq_38251616/article/details/124878863 train_transforms transforms.Compose([ transforms.Resize([224, 224]), # 将输入图片resize成统一尺寸 # transforms.RandomHorizontalFlip(), # 随机水平翻转 transforms.ToTensor(), # 将PIL Image或numpy.ndarray转换为tensor并归一化到[0,1]之间 transforms.Normalize( # 标准化处理--转换为标准正太分布高斯分布使模型更容易收敛 mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) # 其中 mean[0.485,0.456,0.406]与std[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。 ]) total_data datasets.ImageFolder(./6-data/,transformtrain_transforms) total_data划分数据集并加载数据查看数据sizetrain_size int(0.8 * len(total_data)) test_size len(total_data) - train_size train_dataset, test_dataset torch.utils.data.random_split(total_data, [train_size, test_size]) train_dataset, test_datasetbatch_size 32 train_dl torch.utils.data.DataLoader(train_dataset, batch_sizebatch_size, shuffleTrue, num_workers1) test_dl torch.utils.data.DataLoader(test_dataset, batch_sizebatch_size, shuffleTrue, num_workers1) for X, y in test_dl: print(Shape of X [N, C, H, W]: , X.shape) print(Shape of y: , y.shape, y.dtype) break下载调用官方VGG-16模型from torchvision.models import vgg16 device cuda if torch.cuda.is_available() else cpu print(Using {} device.format(device)) # 加载预训练模型并且对模型进行微调 model vgg16(pretrained True).to(device) # 加载预训练的vgg16模型 for param in model.parameters(): param.requires_grad False # 冻结模型的参数这样子在训练的时候只训练最后一层的参数 # 修改classifier模块的第6层即(6): Linear(in_features4096, out_features2, biasTrue) # 注意查看我们下方打印出来的模型 model.classifier._modules[6] nn.Linear(4096,len(classeNames)) # 修改vgg16模型中最后一层全连接层输出目标类别个数 model.to(device) model编写训练函数# 训练循环 def train(dataloader, model, loss_fn, optimizer): size len(dataloader.dataset) # 训练集的大小 num_batches len(dataloader) # 批次数目, (size/batch_size向上取整) train_loss, train_acc 0, 0 # 初始化训练损失和正确率 for X, y in dataloader: # 获取图片及其标签 X, y X.to(device), y.to(device) # 计算预测误差 pred model(X) # 网络输出 loss loss_fn(pred, y) # 计算网络输出和真实值之间的差距targets为真实值计算二者差值即为损失 # 反向传播 optimizer.zero_grad() # grad属性归零 loss.backward() # 反向传播 optimizer.step() # 每一步自动更新 # 记录acc与loss train_acc (pred.argmax(1) y).type(torch.float).sum().item() train_loss loss.item() train_acc / size train_loss / num_batches return train_acc, train_loss编写测试函数def test (dataloader, model, loss_fn): size len(dataloader.dataset) # 测试集的大小 num_batches len(dataloader) # 批次数目, (size/batch_size向上取整) test_loss, test_acc 0, 0 # 当不进行训练时停止梯度更新节省计算内存消耗 with torch.no_grad(): for imgs, target in dataloader: imgs, target imgs.to(device), target.to(device) # 计算loss target_pred model(imgs) loss loss_fn(target_pred, target) test_loss loss.item() test_acc (target_pred.argmax(1) target).type(torch.float).sum().item() test_acc / size test_loss / num_batches return test_acc, test_loss设置动态学习率调用官方的方法learn_rate 1e-4 # 初始学习率 # optimizer torch.optim.SGD(model.parameters(), lrlearn_rate) lambda1 lambda epoch: 0.92 ** (epoch // 4) optimizer torch.optim.SGD(model.parameters(), lrlearn_rate) scheduler torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambdalambda1) #选定调整方法正式训练import copy loss_fn nn.CrossEntropyLoss() # 创建损失函数 epochs 40 train_loss [] train_acc [] test_loss [] test_acc [] best_acc 0 # 设置一个最佳准确率作为最佳模型的判别指标 for epoch in range(epochs): # 更新学习率使用自定义学习率时使用 # adjust_learning_rate(optimizer, epoch, learn_rate) model.train() epoch_train_acc, epoch_train_loss train(train_dl, model, loss_fn, optimizer) scheduler.step() # 更新学习率调用官方动态学习率接口时使用 model.eval() epoch_test_acc, epoch_test_loss test(test_dl, model, loss_fn) # 保存最佳模型到 best_model if epoch_test_acc best_acc: best_acc epoch_test_acc best_model copy.deepcopy(model) train_acc.append(epoch_train_acc) train_loss.append(epoch_train_loss) test_acc.append(epoch_test_acc) test_loss.append(epoch_test_loss) # 获取当前的学习率 lr optimizer.state_dict()[param_groups][0][lr] template (Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%, Test_loss:{:.3f}, Lr:{:.2E}) print(template.format(epoch1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss, lr)) # 保存最佳模型到文件中 PATH ./best_model.pth # 保存的参数文件名 torch.save(best_model.state_dict(), PATH) print(Done)模型训练结果可视化import matplotlib.pyplot as plt #隐藏警告 import warnings warnings.filterwarnings(ignore) #忽略警告信息 plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 用来正常显示负号 plt.rcParams[figure.dpi] 100 #分辨率 from datetime import datetime current_time datetime.now() # 获取当前时间 epochs_range range(epochs) plt.figure(figsize(12, 3)) plt.subplot(1, 2, 1) plt.plot(epochs_range, train_acc, labelTraining Accuracy) plt.plot(epochs_range, test_acc, labelTest Accuracy) plt.legend(loclower right) plt.title(Training and Validation Accuracy) plt.xlabel(current_time) # 打卡请带上时间戳否则代码截图无效 plt.subplot(1, 2, 2) plt.plot(epochs_range, train_loss, labelTraining Loss) plt.plot(epochs_range, test_loss, labelTest Loss) plt.legend(locupper right) plt.title(Training and Validation Loss) plt.show()调用模型对于指定图片进行预测预测函数构建from PIL import Image classes list(total_data.class_to_idx) def predict_one_image(image_path, model, transform, classes): test_img Image.open(image_path).convert(RGB) plt.imshow(test_img) # 展示预测的图片 test_img transform(test_img) img test_img.to(device).unsqueeze(0) model.eval() output model(img) _,pred torch.max(output,1) pred_class classes[pred] print(f预测结果是{pred_class})预测训练集中的某张图片# 预测训练集中的某张照片 predict_one_image(image_path./6-data/Angelina Jolie/001_fe3347c0.jpg, modelmodel, transformtrain_transforms, classesclasses)查看最优模型的准确率best_model.eval() epoch_test_acc, epoch_test_loss test(test_dl, best_model, loss_fn) epoch_test_acc, epoch_test_loss心得体会1.本次任务人脸识别难度较大且类别较多导致准确率较低不过模型的训练依然收敛私以为VGG-16更适用自然物体等简单图像。2.复杂背景对于模型进行人脸识别干扰较大应当适当裁剪3.尝试了更换优化器和数据增强的方法准确率提升较少只有小幅提升4%~5%因此认为应从网络架构本身出发在后续的学习中会更加注意对于人脸识别这一类细粒度识别的任务用哪一类网络会比较好。

相关新闻

2026年十大低代码平台横向测评:谁是企业级开发的终极王者?

2026年十大低代码平台横向测评:谁是企业级开发的终极王者?

引言 在数字化转型浪潮下,低代码开发平台凭借其“快速构建、降低门槛”的核心优势,已成为企业和开发者提升效率的重要工具。相较于国外平台,国内低代码平台更贴合本土业务场景、数据合规要求及使用习惯。本文将系统梳理国内主流的低代码平台&…

2026/11/13 9:44:35 阅读更多 →
电力负荷预测基准测试:时间序列Transformer模型表现超越传统方法

电力负荷预测基准测试:时间序列Transformer模型表现超越传统方法

这次我们来看一个电力负荷预测领域的基准测试项目,重点不是介绍某个具体的预测模型,而是评估不同方法在跨电网层级负荷预测任务中的表现。该项目由研究团队开源,旨在为电力系统负荷预测提供一个标准化的评估框架。 最值得关注的是&#xff0…

2026/11/5 18:15:49 阅读更多 →
揭秘D2数字磁带录像机的无压缩技术与专业应用

揭秘D2数字磁带录像机的无压缩技术与专业应用

1. 项目概述:揭秘D2数字磁带录像机的极限性能 第一次见到索尼DVR-20工作时,我被监视器上跳出的142Mbps码率数值震惊了——这相当于现在主流4K视频的3倍数据量,而它记录的仅仅是标清画面。这台诞生于1996年的专业设备,代表着模拟向…

2026/11/3 0:42:30 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/13 5:13:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/13 5:13:25 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/13 5:13:25 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/13 22:08:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/12 18:22:25 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/13 5:13:25 阅读更多 →

日新闻

周新闻

月新闻