计算机系统应用教程网站

网站首页 > 技术文章 正文

Python 深度学习之人脸识别(yolo+facenet)

btikc 2024-09-05 12:20:20 技术文章 14 ℃ 0 评论

简介:

YOLOv5(You Only Look Once version 5)是一种目标检测模型,用于在视频或图像中识别和定位物体。它是YOLO(You Only Look Once)算法的最新版本,在YOLOv4的基础上进行了改进。YOLOv5是一种端到端的深度学习模型,可以直接从原始图像中检测和定位目标。它使用卷积神经网络(CNN)来学习图像中物体的特征,并使用多尺度预测和网格分割来检测和定位目标。YOLOv5的优势在于它可以在高速运行,并且可以在不同的图像分辨率上很好地工作。总的来说,YOLOv5是一种高效的目标检测模型,可以应用于许多不同的场景,包括自动驾驶,机器人感知,图像分析等。

1.首先创建python3.8的虚拟环境,请在命令行中执行下列操作:

conda create -n yolo5 python==3.8.5
conda activate yolo5

2.pytorch安装(gpu版本和cpu版本的安装)

(cuda环境部署前期已经有介绍:CUDA环境部署

pytorch官网地址:https://pytorch.org/get-started/locally/

我使用命令行安装,安装过程:

安装完成后,使用命令验证一下是否成功

python
import torch
print(torch.__version__)
print(torch.cuda.is_available())

3.下载yolo v5代码

https://github.com/ultralytics/yolov5

文件结构

进入目录,安装其他库

cd D:\PycharmProjects\pythonProject\yolov5-mask-42-master
d:
pip install -r requirements.txt

报错,缺少tensorflow库,先安装普通版本的吧,GPU版本老有问题

又报错:

发现命令中多了个空格,太粗心了。。。。

改后正常完成

查看结果

4.修改数据集配置文件

yolov5-mask-42-master
└─ score
       ├─ images
       │    ├─ test # 下面放测试集图片
       │    ├─ train # 下面放训练集图片
       │    └─ val # 下面放验证集图片
       └─ labels
              ├─ test # 下面放测试集标签
              ├─ train # 下面放训练集标签
              ├─ val # 下面放验证集标签

这里的配置文件是为了方便我们后期训练使用,我们需要在data目录下创建一个mask_data.yaml的文件,如下图所示:

在models下建立一个mask_yolov5s.yaml的模型配置文件,内容如下:

模型训练之前,请确保代码目录下有以下文件

执行下列代码运行程序即可:

python train.py --data mask_data.yaml --cfg mask_yolov5s.yaml --weights pretrained/yolov5s.pt --epoch 100 --batch-size 4 --device gpu


pip install numpy==1.20.3

报错:

修改utils/loss.py文件中的两处内容:

在loss.py中,找到

  for i in range(self.nl):
        anchors = self.anchors[i]

把上面的代码改成

 for i in range(self.nl):
        anchors, shape = self.anchors[i], p[i].shape

在改了上面的内容之后,在找到控制点的

indices.append((b, a, gj.clamp_(0, gain[3] - 1), gi.clamp_(0, gain[2] - 1)))  # image, anchor, grid 
#改成
indices.append((b, a, gj.clamp_(0, shape[2] - 1), gi.clamp_(0, shape[3] - 1)))  # image, anchor, grid

此解决方案网上找的。

CPU 训练完成:

在train/runs/exp6的目录下可以找到训练得到的模型和日志文件

构建可视化界面

可视化界面的部分在window.py文件中,是通过pyqt5完成的界面设计,在启动界面前,你需要将模型替换成你训练好的模型,替换的位置在window.py的第60行,修改成你的模型地址即可,如果你有GPU的话,可以将device设置为0,表示使用第0行GPU,这样可以加快模型的识别速度嗷。

此部分代码详解请参照

parser = argparse.ArgumentParser()
    parser.add_argument('--weights', type=str, default= 'yolov5s.pt', help='initial weights path')
#预训练模型,可不填,但效果会很差,默认为yolov5s.pt
    parser.add_argument('--cfg', type=str, default='models/myyolov5s.yaml', help='model.yaml path')
#必要修改
#修改地址为models/myyolov5s.yaml,训练模型文件位置
    parser.add_argument('--data', type=str, default='data/mydata.yaml', help='dataset.yaml path')
#必要修改
#修改地址为data/mydata.yaml,数据集文件位置
    parser.add_argument('--hyp', type=str, default= 'data/hyps/hyp.scratch-low.yaml', help='hyperparameters path')
    parser.add_argument('--epochs', type=int, default=100)
#修改训练轮数为100,轮数越高,精度越高,速度越慢,默认300
    parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs, -1 for autobatch')
#线程数默认为16,越大越快,不能过大,
    parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='train, val image size (pixels)')
#图片大小,越小越快,但精度越差,一般图片多大填多大,不规则填最长边尺寸
    parser.add_argument('--rect', action='store_true', help='rectangular training')
    parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')
#继续训练,如果上一次训练中止了,只要在这里填上Ture,就可以继续完成上一次训练
    parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
    parser.add_argument('--noval', action='store_true', help='only validate final epoch')
    parser.add_argument('--noautoanchor', action='store_true', help='disable AutoAnchor')
    parser.add_argument('--noplots', action='store_true', help='save no plot files')
    parser.add_argument('--evolve', type=int, nargs='?', const=300, help='evolve hyperparameters for x generations')
    parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
    parser.add_argument('--cache', type=str, nargs='?', const='ram', help='--cache images in "ram" (default) or "disk"')
    parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')
    parser.add_argument('--device', default='0', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
#必要修改
#修改为0,0的意思是调用gpu0,如果你的电脑有几块gpu可以填1,2,3,如果没有gpu可以在上面填cpu
    parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')
    parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class')
    parser.add_argument('--optimizer', type=str, choices=['SGD', 'Adam', 'AdamW'], default='SGD', help='optimizer')
    parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
    parser.add_argument('--workers', type=int, default=8, help='max dataloader workers (per RANK in DDP mode)')
    parser.add_argument('--project', default=ROOT / 'runs/train', help='save to project/name')
    parser.add_argument('--name', default='exp', help='save to project/name')
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    parser.add_argument('--quad', action='store_true', help='quad dataloader')
    parser.add_argument('--cos-lr', action='store_true', help='cosine LR scheduler')
    parser.add_argument('--label-smoothing', type=float, default=0.0, help='Label smoothing epsilon')
    parser.add_argument('--patience', type=int, default=100, help='EarlyStopping patience (epochs without improvement)')
    parser.add_argument('--freeze', nargs='+', type=int, default=[0], help='Freeze layers: backbone=10, first3=0 1 2')
    parser.add_argument('--save-period', type=int, default=-1, help='Save checkpoint every x epochs (disabled if < 1)')
    parser.add_argument('--seed', type=int, default=0, help='Global training seed')
    parser.add_argument('--local_rank', type=int, default=-1, help='Automatic DDP Multi-GPU argument, do not modify')

换成GPU跑速度提高2倍

但是数据都是nan

CPU 跑结果没问题,但GPU跑就都是nan 原因可能是精度的变化导致经过model后数据被莫名其妙更改,引起某些指数计算,算得值为INF、梯度变化等情况,这里仅为猜测,没有深入研究,解决方法:

更改:train.py文件中

原代码:
       # Forward
       with amp.autocast(enabled=cuda):
        	pred = model(imgs)  # forward
            loss, loss_items = /
            compute_loss(pred, targets.to(device))  
更改后的代码:
       # Forward
       # with amp.autocast(enabled=cuda):
       pred = model(imgs)  # forward
       loss, loss_items = compute_loss(pred, /
       				targets.to(device)) 

YOLO v5的人脸识别和性别识别完成,下面做自定义UI和facenet人名算法

facenet模型

人脸图片

图片中人脸转128位向量

 '''
        加载目标人的特征
        '''
        # 记录名字
        name_list = []
        # 输入网络的所有人脸图片
        known_faces_input = []
        # 遍历
        known_face_list = glob.glob('./images/origin/*')
        for face in tqdm.tqdm(known_face_list, desc='处理目标人脸...'):
            name = face.split('\\')[-1].split('.')[0]
            name_list.append(name)
            # 裁剪人脸
            croped_face = self.getCropedFaceFromFile(face)
            if croped_face is None:
                print('图片:{} 未检测到人脸,跳过'.format(face))
                continue
            # 预处理
            img_input = self.imgPreprocess(croped_face)
            known_faces_input.append(img_input)
        # 转为Nummpy
        faces_input = np.array(known_faces_input)
        # 转tensor并放到GPU
        tensor_input = torch.from_numpy(faces_input).to(self.device)
        # 得到所有的embedding,转numpy
        known_embedding = self.facenet(tensor_input).detach().cpu().numpy()

最终结果

以上就是实施过程,欢迎批评指正,感谢点赞加关注!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表