项目简介
本项目是AI入门的应用项目,后续可以补充内容完善作为满足个人需要。通过构建自己的人脸数据集,此项目训练集为4580张图片,测试集为2308张图片,使用resnet50网络进行训练,最后进行效果展示。本项目也提供了量化内容,便于在硬件上部署。
模型介绍
研究AI网络的人拥有网络命名权。比如我研究出来一个网络,效果很好,要发一篇论文来介绍这个网络,论文中需要给网络起个名字,并且希望这个名字可以流传很广。那么,简单、好记同时又能概括网络思想的名字肯定是首选。Resnet50就是这样的名字,这个网络的核心思想,就藏在名字里。Res + net + 50,Res 是 Residual (残差)的缩写,50指的是整个网络中有50个卷积层。Resnet50的网络结构从第一层到最后一层,总共50个卷积算法。那么Res(Residual)残差又是个什么东西呢?
残差结构
所谓残差结构,其实就是在正常的神经网络中,增加一个short cut 分支结构,也称为高速公路。比如上图中,左侧是正常的卷积层,一层层往下传,在右侧增加一条连线,使得整个网络结构形成了一个残差结构。这样,网络的输出不再是单纯卷积的输出F(x),而是卷积的输出和前面输入的叠加F(x) + X。
度卷积神经网络在网络深度不断加深的过程中,神经网络会学到不同的特征。但是,能无限制地加深么?比如使用1000层卷积层进行网络的训练的。
答案显然是不行的。
原因在于神经网络训练的过程是不断与目标值进行拟合的过程,直到拟合的误差降低到人们的预期,代表着神经网络训练完毕,一个会识图的AI就诞生了。
但是在实际训练过程中,数据的传递除了从网络前端往后传之外,还需要将最后一层与目标值的误差传回到网络前端,从而进行下一轮的训练,得到更小的误差,这一过程称为神经网络的反向传播。在往回传的过程中,由于误差本身就很小,如果卷积层数过多,在经过激活函数时,很容易发生误差传着传着就消失了,称为梯度消失。
梯度消失的原因有很多种,不好的激活函数、过深的网络层数等都有可能导致误差消失。想象一下,上一轮训练结果的误差传不回来,下一轮如何在上一轮的基础上进行进一步优化训练?结果就会导致怎么训练神经网络最终的结果都无法收敛。
如果左侧卷积层学习到的数据不够好,那么叠加上无损通过的原始数据,依然保留了原始数据,不至于丢掉原始数据。而如果左侧卷积层学习到的效果很好,那么依然会保留着学习到的数据,下面的卷积层依然可以在这些数据基础上进一步学习优化。
Resnet50网络的结构其实说简单,它很简单,而且算法思想也很简洁,就是50层卷积的计算,依据卷积局部感受野这一特性,抽取出图像的不同特征,通过最后一层卷积(或者叫做全连接)将图片进行分类。
这样的网络设计,分类效果很好,使得Resnet50 多次在图像分类大赛中夺冠!Resnet50除了大量使用了卷积这一算法之外,一个简单暴力的残差结构的应用,使得该网络无论在训练还是推理过程中,其效果都极为出彩!
从此,残差这一结构,受到了人们的关注,以至于,有人开始专门研究不同层之间的残差连接。一句话,Resnet50的核心是卷积和残差,卷积的核心是特征抽取。
数据集准备
文章来源:https://www.toymoban.com/news/detail-801447.html
这里给出的是我的数据集保存格式,一张人脸图片的id对应一个136个坐标点,坐标点通过csv文件的形式保存(你可以通过表格或者其他文本的形式保存)文章来源地址https://www.toymoban.com/news/detail-801447.html
主体代码
import torch.nn as nn
from torchvision import models
import os
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
device = 'cuda'
class ResNet50ForFaceLandmarks(nn.Module):
def __init__(self, num_classes=68*2): # 68 landmarks, each with (x, y) coordinates
super(ResNet50ForFaceLandmarks, self).__init__()
# 使用预训练的ResNet50
self.model = models.resnet50(pretrained=False)
# 替换最后的全连接层以适应68点检测
self.model.fc = nn.Linear(self.model.fc.in_features, 512)
# 新增的层
self.new_fc = nn.Sequential(
nn.ReLU(), # ReLU激活层
nn.Linear(512, 136) # 第二个线性层输出132
)
def forward(self, x):
# 通过原始的 ResNet50
x = self.model(x)
# 通过新增的层
x = self.new_fc(x)
return x
model = ResNet50ForFaceLandmarks()
print(model)
model.to(device)
import torch
from torch.utils.data import Dataset
from torchvision import transforms
import pandas a
到了这里,关于pytorch实现AI小设计-1:Resnet50人脸68关键点检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!