基于Pytorch的行为识别

基于Pytorch的行为分析

参考文献

参考论文

3D Convolutional Neural Networks for Human Action Recognition

3D卷积

3D卷积针对的数据集是视频,所以3D是在2D卷积的基础上再加一个时间维度。它提取的是视频中某一帧和前后几帧的关联特征
左图是3D卷积,右图是2D卷积
如上,左图是3D卷积,右图是2D卷积。
它的Pytorch编写也很简单…

nn.Conv3d(in_channels, out channels, kernel_size = (7,7,3), padding = (1,1,1)) #假设我用的是7x7x3的卷积核

3D残差网络

行为分析说白了就是之前的图片分类任务中的图片,变成了视频而已,多了一个时间维度。所以我们需要运用3D卷积网络,去提取视频的特征
注:在看此网络之前,建议先去了解普通的残差网络。

#残差网络的基础模块:实线连接的那个基础模块
import torch.nn as nn
import torch.nn.functional as F

class BasicBlock(nn.Module):

    def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, downsample=None):
        super().__init__()

        self.conv1 = nn.Conv3d(in_channels, out_channels, kernel_size, stride, padding=1)
        self.bn1 = nn.BatchNorm3d(out_channels)
        self.conv2 = nn.Conv3d(in_channels, out_channels,kernel_size, stride, padding=1)
        self.bn2 = nn.BatchNorm3d(out_channels)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x     #残差边

        feat1 = F.relu(self.bn1(self.conv1(x)))  #第一层卷积
        feat2 = self.bn2(self.conv2(feat1))   #第二层卷积

        if self.downsample is not None:
            residual = self.downsample(x)

        out = F.relu(feat2+residual)
        
        return out

最后的就是主干网络了

#使用的是resnet34残差主干网络
import torch.nn as nn
import torch
import torch.nn.functional as F

#layers = [3, 4, 6, 3],block_inplanes[64, 128, 256, 512]
class ResNet(nn.Module):
              #block指的是上文提到的BasicBlock模块
    def __init__(self, block, layers, block_inplanes, n_input_channels=3, conv1_t_size=7,conv1_t_stride=1,no_max_pool=False, n_classes=10):
        super().__init__()


        self.in_planes = block_inplanes[0]
        self.no_max_pool = no_max_pool

        self.conv1 = nn.Conv3d(n_input_channels,self.in_planes,kernel_size=(conv1_t_size, 7, 7), stride=(conv1_t_stride, 2, 2),padding=(conv1_t_size // 2, 3, 3),bias=False)
        self.bn1 = nn.BatchNorm3d(self.in_planes)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool3d(kernel_size=3, stride=2, padding=1)
        self.layer1 = self._make_layer(block, block_inplanes[0], layers[0])
        self.layer2 = self._make_layer(block,block_inplanes[1],layers[1], stride=2)
        self.layer3 = self._make_layer(block, block_inplanes[2], layers[2], stride=2)
        self.layer4 = self._make_layer(block,block_inplanes[3],layers[3], stride=2)

        self.avgpool = nn.AdaptiveAvgPool3d((1, 1, 1))
        self.fc = nn.Linear(block_inplanes[3], n_classes)

        for m in self.modules():
            if isinstance(m, nn.Conv3d):
                nn.init.kaiming_normal_(m.weight,
                                        mode='fan_out',
                                        nonlinearity='relu')
            elif isinstance(m, nn.BatchNorm3d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

    def _downsample_basic_block(self, x, planes, stride):
        out = F.avg_pool3d(x, kernel_size=1, stride=stride)
        zero_pads = torch.zeros(out.size(0), planes - out.size(1), out.size(2),
                                out.size(3), out.size(4))
        if isinstance(out.data, torch.cuda.FloatTensor):
            zero_pads = zero_pads.cuda()

        out = torch.cat([out.data, zero_pads], dim=1)

        return out

    def _make_layer(self, block, planes, blocks, stride=1):
        downsample = None
        if stride != 1 or self.in_planes != planes:
                downsample = nn.Sequential(
                    nn.Conv2d(self.in_planes, planes, stride),
                    nn.BatchNorm3d(planes))

        layers = []
        layers.append(
            block(in_planes=self.in_planes, planes=planes, stride=stride, downsample=downsample))
        self.in_planes = planes
        for i in range(1, blocks):
            layers.append(block(self.in_planes, planes))

        return nn.Sequential(*layers)

    def forward(self, x):
        x = F.relu(self.bn1(self.conv1(x)))

        if not self.no_max_pool:
            x = self.maxpool(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)

        return x
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__TAT__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值