PaddlePaddle飞桨论文复现营——3D Residual Networks for Action Recognition学习笔记

PaddlePaddle飞桨论文复现营——3D Residual Networks for Action Recognition学习笔记1 背景知识1.1 C3DC3D是一种3D卷积提取视频特征的方法,从水平(X)、垂直(Y)和时序(T)三个方向三个方面同时提取视频的时空特征,其提取到的特征比常规的2D卷积更自然[1]。缺点就是,因为多了一维“时序(T)”,卷积后会引起参数剧增,对计算机GPU算力要求较大。P.S: C3D源代码和预训练模型可参考:http://vlg.cs.dartmouth.e
摘要由CSDN通过智能技术生成

PaddlePaddle飞桨论文复现营——3D Residual Networks for Action Recognition学习笔记

1 背景知识

1.1 C3D

C3D是一种3D卷积提取视频特征的方法,从水平(X)、垂直(Y)和时序(T)三个方向三个方面同时提取视频的时空特征,其提取到的特征比常规的2D卷积更自然[1]。缺点就是,因为多了一维“时序(T)”,卷积后会引起参数剧增,对计算机GPU算力要求较大。
在这里插入图片描述
P.S: C3D源代码和预训练模型可参考:http://vlg.cs.dartmouth.edu/c3d/

在这里插入图片描述
通过上图,不难发现,相比VGG16或VGG19,C3D的卷积层相对较少,只有8层。此外,3D卷积核相比2D卷积核所多出的大量参数,在数据集不充足的情况下,网络易趋于过拟合。

1.2 Kinetics数据集

2017年5月22日,Deepmind团队发布了最具有影响力的视频分类数据集之一,目前,其包含大约650000个高质量视频链接,涵盖700个人类动作类,包括人与对象之间的交互(如演奏乐器)以及人与人之间的互动(如握手和拥抱)。每个动作类至少有600个视频剪辑。每个剪辑都是人工注释与单个动作类,并持续约10秒。
P.S: Kinetics地址:https://deepmind.com/research/open-source/kinetics

1.3 ResNet

更深的神经网络意味着更难的训练。因此,微软研究院何恺明等人在《Deep Residual Learning for Image Recognition》提出了一种减轻网络训练负担的残差学习框架(ResNet),这种网络比以前使用过的网络本质上层次更深。可理解为其显式地将层重新配置为参考层输入学习剩余函数,而不是学习未参考函数。他们通过提供了全面的经验证据,证明了这些残差网络更易于优化,并且可以通过深度的增加而获得准确性的提升。在ImageNet数据集上,深度最大为152层的残差网络-比VGG19网络还要深8倍,但复杂度仍然较低。这些残留网络的整体在ImageNet测试仪上实现了3.57%的误差。该结果在ILSVRC2015分类任务中获得第一名[2]。其框架如下图所示:
在这里插入图片描述
下图是ResNet在CIFAR-10测试集上的分类错误情况
在这里插入图片描述

2 研究方法

2.1 3D ResNets简述

在当时的研究背景下,最新的大型视频数据集(如,Kinetics),虽然能大幅度地改善过拟合的情况,但是,相对于优秀的2D网络(如,ResNet)而言,C3D的网络缺乏深度。因此,作者的团队就基于ResNet提出了3D ResNets这个网络架构。

2.2 3D ResNet网络架构

2.2.1 Residual block——残差块

在这里插入图片描述
ResNets引入了捷径连接(shortcut connections),可以绕过一层到另一层的标记。这些连接通过网络的梯度流从较后层到较早层,并简化了非常深层网络的训练。上图(Figure 1)展示了残差块的结构,它是ResNets的一个元素。连接从块的顶部到尾部绕过标记。ResNets由多个残差块组成。

2.2.2 Network Architecture——网络架构

在这里插入图片描述
通过Table1的3D ResNets网络架构图不难发现,3D ResNets与原始ResNets的区别在于卷积核(convolutional kernels)和池化层(pooling)的维数。3DResNet执行3D卷积和3D池化。卷积核的大小为“ 3 × 3 × 3”,并且conv1的时间步长(stride)为1,类似于C3D。网络使用16帧RGB剪辑作为输入。输入剪辑的大小为“3 × 16 × 112 × 112”。残差块显示在Table1的括号中。 每个卷积层之后是Batch Normalization(BN,对每批数据进行归一化处理)和relu(激活函数)。 输入的下采样由步长(stride)为2的conv3_1,conv4_1,conv5_1执行。当特征图(feature maps)的数量增加时,作者采用零填充的身份快捷方式来避免增加参数数量。框架的最后一层是为Kinetics数据集(400个类别)设置的最后一个完全连接层,其输出函数是softmax(将输出值限定在0~1之间的一个概率值)。

2.2.3 Training——训练

作者使用带有动量的随机梯度下降(SGD)来训练3D ResNet的网络,通过从训练数据中的视频中随机生成训练样本以执行数据增强。主要内容如下:

  1. 通过均匀采样选择每个样本的时间位置(temporal positions)。
  2. 在选定的时间位置(temporal positions)周围生成16帧剪辑。如若视频少于16帧,则将对视频进行必要的多次循环。
  3. 从4个角或中心随机选择空间位置。
  4. 对每个样本的空间尺度进行多尺度裁剪,尺度选自 { 1 , 1 2 1 / 4 , 1 2 , 1 2 1 / 4 , 1 2 } \left\{1, \frac{1}{2^{1 / 4}}, \frac{1}{\sqrt{2}}, \frac{1}{2^{1 / 4}}, \frac{1}{2}\right\} { 1,21/41,2 1,21/41,21},其中1为最大尺度。裁剪框的长宽比为1。生成的样本水平翻转的概率为50%。
  5. 对每个样本进行均值减法运算。所有生成的样本均与其原始视频具有相同的类别标签。

作者在训练时,学习率现(lr)先是设定为0.1,然后,当学习率降到0.0001后,验证损失达到饱和。较大的lr和batch对于实现良好的识别性能尤为重要。

2.2.4 Recognition——识别

首先,使用训练好的模型来识别视频中的动作。训练过程中,每个剪辑(每个视频被分成不重叠的16帧剪辑。)都以最大比例围绕中心位置进行裁剪。使用经过训练的模型估算每个剪辑的类别概率,并将它们平均化到视频的所有剪辑中,以识别视频中的动作。

2.2.5 Dataset——数据集

此实验中,作者使用了ActivityNet(v1.3)Kinetics数据集。

ActivityNet数据集提供了200个人类动作类别的样本,每个类别平均有137个未修剪的视频,每个视频的Activity Instances(活动实例)为1.41。视频总时长为849小时,Activity Instances(活动实例)的总数为28108。数据集随机分为三个子集:训练,验证和测试,其中50%用于训练,25%用于验证和25%用于测试。

2017年,Kinetics数据集刚发布时,其提供了400个人类动作类别的样本,并且每个类别包含400个(或更多)的视频。视频在时间上进行了修剪,因此它们不包含非动作帧,并且持续约10秒钟。视频总数为300,000或更多。训练,验证和测试集的数量分别约为240,000、20,000和40,000。Kinetics的Activity Instances(活动实例)数量是ActivityNet的Activity Instances(活动实例)数量的10倍,而两个数据集的总视频长度却很接近。

对于这两个数据集,作者都其将视频的大小调整为360像素高度,而未更改其宽高比,并将其存储。

3 研究成果

3.1 基于ActivityNet数据集的初步实验结果

在这里插入图片描述
此实验的目的是在相对较小的数据集上探索3D ResNet的训练效果。在此实验中,作者的团队训练了Table1中所述的18层的3D ResNet和Sports-1M预先训练的C3D。观察Figure2,可以发现18层的3D ResNet出现了过拟合,因此其验证精度明显低于训练精度。相比之下,经过Sports-1M预训练的C3D没有出现过拟合,并且获得了更好的识别精度。

3.2 基于Kinetics数据集的实验结果

在这里插入图片描述
此实验中,作者的团队训练了34层的3D ResNet而不是18层的3D ResNet,因为Kinetics的活动实例数量明显大于ActivityNet的活动实例数量。Figure3显示了34层的3D ResNet不会过拟合并获得良好的性能。如Figure1(b)所示,Sports-1M预训练的C3D也实现了良好的验证准确性,但是,它的训练精度明显低于验证精度。

在这里插入图片描述
Table2显示了34层的3D ResNet和同时期较新技术的准确性。34层的3D ResNet的精度高于Sports-1M预先训练的C3D和C3D,并且具有从头开始训练的Batch Normalization(BN,对每批数据进行归一化处理)。该结果证明了3DResNet的有效性。但是,深度数小于34层的3D ResNet的RGB-I3D达到了最佳性能却在此实验中表现优异,其原因可能是,训练RGB-I3D时,使用了32 个 GPU,而训练34层的3D ResNet,只使用了4个256批处理大小的GPU。由于 GPU 内存限制,3D ResNet 的大小为“3 × 16 × 112 × 112”,而 RGB-I3D 的大小为“3 × 64 × 224 × 224”。高空间分辨率和较长的持续时间可提高识别精度。因此,使用大量GPU并增加批处理大小,空间分辨率和时间持续时间可能会进一步实现3D ResNets 的改进。

4 Conclusion——结论

作者及其团队创新性地提出了3D卷积内核及3D池化层的概念,并据此结合一系列实验来探索论证了ResNets在视频分类领域的有效性(尤其是在大数据集的环境下)[3]

5 源码简析

源码参考地址:https://github.com/kenshohara/3D-ResNets

5.1 training.py

import torch	# 通过paddlepaddle实现时,此处需修改为对应的paddlepaddle包
import time
import os
import sys

import torch	# 通过paddlepaddle实现时,此处需修改为对应的paddlepaddle包
import torch.distributed as dist	# 通过paddlepaddle实现时,此处需修改为对应的paddlepaddle包

from utils import AverageMeter, calculate_accuracy


def train_epoch(epoch,	# 训练轮次
                data_loader,
                model,
                criterion,
                optimizer,
                device,
                current_lr,
                epoch_logger,
                batch_logger,
                tb_writer=None,
                distributed=False):
    print('train at epoch {}'.format(epoch))

    model.train()

    batch_time = AverageMeter()
    data_time = AverageMeter()
    losses = AverageMeter()
    accuracies = AverageMeter()

    end_time = time.time()
    for i, (inputs, targets) in enumerate(data_loader):
        data_time.update(time.time() - end_time)

        targets = targets.to(device, non_blocking=True)
        outputs = model(inputs)
        loss = criterion(outputs, targets)	# 损失值计算
        acc = calculate_accuracy(outputs, targets)	# 准确率计算

        losses.update(loss.item(), inputs.size(0))	# 损失值更新
        accuracies.update(acc, inputs.size(0))	# 准确率更新

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        batch_time.update(time.time() - end_time)
        end_time = time.time()

        if batch_logger is not None:
            batch_logger.log({
   
                'epoch': epoch,
                'batch': i + 1,
                'iter': (epoch - 1) * len(data_loader) + (i + 1),
                'loss': losses.val,
                'acc': accuracies.val,
                'lr': current_lr
            })

        print('Epoch: [{0}][{1}/{2}]\t'								# 打印运行日志
              'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
              'Data {data_time.val:.3f} ({data_time.avg:.3f})\t'
              'Loss {loss.val:.4f} ({loss.avg:.4f})\t'
              'Acc {acc.val:.3f} ({acc.avg:.3f})'.format(epoch,
                                                         i + 1,
                                                         len(data_loader),
                                                         batch_time=batch_time,
                                                         data_time=data_time,
                                                         loss=losses,
                                                         acc=accuracies))

    if distributed:
        loss_sum = torch.tensor([losses.sum],
                                dtype=torch.float32,
                                device=device)
        loss_count = torch.tensor([losses.count],
                                  dtype=torch.float32,
                                  device=device)</
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值