Pytorch模型和训练集搭建与训练,以人体姿势分类为例

72 阅读4分钟

本文将以一个简单的人体姿态分类模型为例来展示Pytorch模型搭建和训练的过程,为读者日后理解或搭建更复杂的模型提供基础。

完整代码请通过公众号聊天,输入自定义模型和训练集.py获取。

扫码_搜索联合传播样式-标准色版.png

流程

01 丨构建数据类

数据的获取和处理的逻辑封装在一个类中,这个类必须继承Pytorch提供的Dataset类。在这个类中我们一般写哪些东西呢?一般情况下, init、__getitem__和__len__ 这三个魔法函数是必要的。init__是类的实例化时调用的函数即构造器;我们知道,实现了魔法函数__getitem,对象就可以被索引访问,返回一个数据样本,以这个分类任务为例,一个样本就是形如这样的元组: (样本标签,样本数据) ;__len__返回数据集中样本的总数,这个数值也有多个用处,这里不赘述

实验数据使用代码随机生成:

640.webp

下面展示的是随机生成的假数据,数据保存在data.txt中(当然,保存在.csv或其他格式的文件也可以),每一行第一个值是标签,取值有0、1、2、3,代表人体姿势的4种类别,这里假设4种类别为分别为站立、蹲下、跳跃和奔跑;剩余5个值是特征数据,代表人体的5个关键点在图片中的相对位置,所以他们的值在0~1之间,5个关键点分别为鼻子、左手腕、右手腕、左脚踝、右脚踝,该数据仅做演示功能使用,没有实际意义:

image.png

下面定义数据类,各部分含义如上文所述:

641.webp

02 丨构建模型类

模型相关的信息被封装在自定义的模型类中,这个类必须继承Pytorch提供的Module类。在模型类中实现 __init__和forward这两个方法是必要的。在__init__中定义组成模型的各个组件,比如全连接层、2D卷积层和激活函数等等;而forward则代表前向传播,即数据从输入开始,一步步是怎么被计算的,最终得到输出,所以这个方法在模型推理数据时会被自动调用,返回推理结果

下面定义模型类,各部分含义如上文所述:

642.webp

03 丨 编写训练代码

有了数据和模型,接下来设定一些超参数,例如学习率lr、批大小batchsize、损失函数loss function、训练轮次epochs、优化器optimizer等等;接着编写训练和验证的逻辑代码,大体上包含for循环、可视化(这里用比Tensorboard使用起来更简便的visdom)以及模型保存

注意,我们定义的数据类提供的数据不是直接拿来训练或验证模型,而是通过DataLoader即数据加载器打包成一个个batch后使用的:

643.webp

那么一个batch的数据长什么样呢?参见下图:

644.webp

可以很清楚地看到,一个batchsize大小的特征数据被整合到一个tensor中,而其对应的一个batchsize大小的标签也被整合到一个tensor中,这就是DataLoader做的主要工作。如下面几行代码所示,取出一个batch的特征数据和标签,做前向推理和损失计算:

645.webp

此外,在创建模型的时候要注意模型的输入输出维度,因为我们这里是5个特征字段,所以对输入层的全连接神经元个数为5,而类别为4,所以最终的输出层的神经元个数为4:

646.webp

通常在训练过程中我们会观察一些指标性数据,如本实验有关注损失值的大小、准确度(注意,它指的是accuracy,一个全局的性能指标,反映正确预测的样本数占总的样本数的比例,即 (真正例+真负例)/总样本。区别于精确度,对应单词precision,反映的是预测的正样本中真的正样本所占的比例,即真正例/(真正例+假正例) ),在每个epoch后进行一次验证,下面是验证模型在验证集上的准确度上的代码:

647.webp

其他

本文实验中使用了visdom可视化工具,这是一个由Tornado(Flask、FastAPI、Django、Tornado等)构建的web服务,使用时只需创建一个Visdom对象并指定环境名称,作图时指定下图像窗口名称,填入一些必要信息,一行代码便可作出一幅图像,如下展示生成每次迭代的损失值的折线图:

648.webp

visdom使用指导:

本实验的可视化结果如下:

649.webp