pytorch实现AI小设计-1:Resnet50人脸68关键点检测

该项目利用Resnet50网络进行人脸68关键点检测,训练集4580张,测试集2308张。Resnet50的核心是残差结构,通过增加short cut分支解决深度网络的梯度消失问题。数据集以CSV保存,代码展示了训练和推理效果,并提供量化到uint8的方案。
摘要由CSDN通过智能技术生成

 项目简介

        本项目是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的核心是卷积和残差,卷积的核心是特征抽取。

数据集准备

这里给出的是我的数据集保存格式,一张人脸图片的id对应一个136个坐标点,坐标点通过csv文件的形式保存(你可以通过表格或者其他文本的形式保存)

主体代码


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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值