基于PyTorch搭建CNN实现视频图片动作分类任务

这里写自定义目录标题1 前言1.1 数据集1.2 运行环境1.3 总体概述2 项目开始2.1 数据加载2.1.1 Dataset 类2.2.2 Dataloader类2.2 数据解释和处理2.3 搭建网络模型3 训练步骤及模块4 训练并验证5 使用Resnet18网络训练1 前言对视频数据的处理是计算机视觉领域非常重要的一部分内容。视频主要是由大量的视频帧图像所构成。相比于单一的图像,视频中多出了时间维度的信息,物体在先后帧中出现的顺序和状态等信息都非常关键。同时视频数据的数据量更大,而且相邻帧间差距较
摘要由CSDN通过智能技术生成

1 前言

对视频数据的处理是计算机视觉领域非常重要的一部分内容。视频主要是由大量的视频帧图像所构成。相比于单一的图像,视频中多出了时间维度的信息,物体在先后帧中出现的顺序和状态等信息都非常关键。同时视频数据的数据量更大,而且相邻帧间差距较小,使得数据冗余度较高。所以在视频任务中,如何处理好时序信息、如何高效提取特征都是至关重要的问题。

本项目通过实例来介绍和实现一个简单的视频动作分类方法,通过加载和预处理数据、构造和提取特征、训练分类器得到一个可以应用的视频动作分类工具。

1.1 数据集

本次我们使用的数据集是精简版的UCF101数据集,该数据在UCF101数据的基础上选择了十个动作类别的数据,在每个视频数据中提取了三帧内容并将其压缩至低分辨率。从而将整个数据规模控制到一个较小的范围,便于在各种设备上进行学习和实验。

数据集下载链接https://download.csdn.net/download/w18165269429/16128413.

数据集 训练集 验证集 测试集 总数
数据量 7770 2230 3270 13270

1.2 运行环境

pytorch
python
torchvision
PIL
numpy
scipy

可以使用pip或conda工具安装上述模块。推荐尝试使用GPU来加速代码的训练,这需要使用nvidia显卡并且搭建相应的cuda环境,当然使用CPU也可以完成本项目。

1.3 总体概述

本项目包括以下内容:从原始的数据文件中加载数据、对数据进行预处理、神经网络的搭建、训练分类器、结果展示。该模型使用经典的卷积+激活+池化结构的堆叠,逐步提取特征值,并在最后使用全连接层进行分类。

2 项目开始

首先导入第三方库

import torch
import torch.nn as nn
from torch.autograd import Variable
from torch.utils.data import DataLoader, Dataset
from torchvision import models
from torchvision import transforms
from PIL import Image
import os
import scipy.io

2.1 数据加载

在这一部分,我们将完成数据加载的工作。

我们将主要使用pytorch中设计好的Dataloader作为我们的数据的加载器。该加载器能够根据设定在每一次请求时自动加载一批训练数据,能够自主实现多线程加载,能够在快速加载的同时尽可能的节省内存开销。

而Dataloader类所加载的数据必须是pytorch中定义好的Dataset类,所以我们的第一步,就是将我们的数据封装成一个Dataset类。

首先,加载数据中的整体配置文件,并且打印出训练集和验证集的大小。

print(torch.cuda.device_count())
label_mat = scipy.io.loadmat('./dataset/q3_2_data.mat')
label_train = label_mat['trLb']
print('train_len:', len(label_train))
label_val = label_mat['valLb']
print('val len', len(label_val))
train_len: 7770
val len 2230

2.1.1 Dataset 类

Dataset类被定义在torch.utils.data.Dataset处,在使用Dataset类加载自定义数据集时需要重写其中的lengetitem方法。

__len__:返回当前dataset的大小。
__getitem__:返回一批数据

len方法的主要作用就是给出当前数据的数量信息。而在我们最终使用时,我们首先会告诉Dataloader类要求加载一批数据,然后Dataloader类就会找到其中数据的getitem方法,该方法会返回一批数据来供我们使用。

class ActionDataset(Dataset):
    def __init__(self, root_dir, labels=[], transform=None):
        """
        :param root_dir: 整个数据路径
        :param labels: 图片标签
        :param transform: 想要对数据进行的处理函数
        """
        self.root_dir = root_dir
        self.transform = transform
        self.length = len(os.listdir(self.root_dir))
        self.labels = labels

    def __len__(self):  # 此方法只返回数据数量
        return self.length * 3  # 每个视频都包含三帧

    def __getitem__(self, idx):
        folder = idx // 3 + 1  # // 表示向下整除
        imidx = idx % 3 + 1
        folder = format(folder, '05d')
        imgname = str(imidx) + '.jpg'
        img_path = os.path.join(self.root_dir, folder, imgname)
        image = Image.open(img_path)

        if len(self.labels) != 0:
            Label = self.labels[idx // 3][0] - 1
        if self.transform:
            image = self.transform(image)
        if len(self.labels) != 0:
            sample = {
   'image': image, 'img_path': img_path, 'Label': Label}
        else:
            sample = {
   'image': image, 'img_path': img_path}
        return sample

2.2.2 Dataloader类

虽然在封装了Dataset类之后我们能够完成对数据的记载,但是在实际训练过程中我们还需要更多的步骤:

	一次加载batch size大小的数据。
	打乱数据的顺序。
	多线程加载数据。

而这些需求已经全部被DataLoader类所实现:

image_dataset_train = ActionDataset(root_dir='./dataset/trainClips/', labels=label_train,
                                    transform=transforms.ToTensor())
image_dataloader_train = DataLoader(image_dataset_train, batch_size=32,
                                    shuffle=True, num_workers=0)
image_dataset_val = ActionDataset(root_dir='./dataset/valClips/', labels=label_val, transform=transforms.ToTensor())
image_dataloader_val = DataLoader(image_dataset_val, batch_size=32,
                                  shuffle=True, num_workers=
  • 17
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值