视频分类Video-Swin-Transformer

视频分类Video-Swin-Transformer



前言

提示:这里可以添加本文要记录的大概内容:

星光不问赶路人,时光不负有心人。
时间就是这样转瞬即逝,没有时间停留,加油赶路人!


提示:以下是本篇文章正文内容,下面案例可供参考

一、Video-Swin-Transformer

在计算机视觉领域,模型正在从CNN 向Transformer转变,并且纯transformer架构在主要的视频识别方向获得了最高的精度,这些模型建立在能够在时间和空间维度上将patches全局连接起来的transformer层上。CNN向transformer的转变开始于vision transformer(ViT),它通过 transformer encoder对非重叠的图像快的空间关系进行全局建模,由于在图像上取得的巨大成功,使得开始了对于基于transformer的视频识别任务的研究。
之前的对于视频主干结构就是将用于图像的主干结构扩展到时间轴即可,如C3D,对于时间和空间联合建模,但这种方法既不经济也不容易优化,因此提出了一种对时空域进行分解的方法,该方法在速度和精度上有所折中。并且最初将transformer用于视频识别是,也采用过分解的方法,通过分解编码器或者分解自注意力,这种方法能够极大的减小模型的规模,同时不会大幅降低模型的性能。

更多详细内容查看官方git:
https://github.com/SwinTransformer/Video-Swin-Transformer

二、环境安装

根据需要阅读git里面的README即可,训练和测试模型,这里记录一些问题即可。
1、环境安装
这里主要提到两个包,MMCV和MMAction2
mmcv安装官方给的安装,直接pip安装安不上,也会报错
官方安装方式:https://github.com/open-mmlab/mmcv/blob/master/README_zh-CN.md
例如:pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.9.0/index.html
MMAction2安装
下面两种方式都可以
1、pip install -v -e .
2、python setup.py develop

三、数据预测

1、训练后进行验证
一个简单的demo

from mmaction.apis import init_recognizer, inference_recognizer

config_file = '../configs/recognition/tsn/tsn_r50_video_inference_1x1x3_100e_kinetics400_rgb.py'
# download the checkpoint from model zoo and put it in `checkpoints/`
checkpoint_file = '../checkpoints/tsn_r50_1x1x3_100e_kinetics400_rgb_20200614-e508be42.pth'

# build the model from a config file and a checkpoint file
model = init_recognizer(config_file, checkpoint_file, device='cpu')

# test a single video and show the result:
video = 'demo.mp4'
label = 'label_map_k400.txt'
results = inference_recognizer(model, video, label)

# show the results
for result in results:
    print(f'{result[0]}: ', result[1])

具体实现需要按照工程自己实现,不要使用test.py进行实时预测,里面冗余的东西太多

四、对源码进行更改

1、某些使用的包
下面谈一下在工程上需要进行更改的几个包
inference.py
位置: Video_swin\mmaction\apis\inference.py
对应inference_recognizer函数,根据自己的需要进行更改,比如当时我们要训练时候使用的是7张不同光照角度的同一张显微图像,开始是将7张图像合成视频进行分类,但会产生一些中间文件,为了避免产生,我们修改了原始代码,在inference_recognizer函数加入video_mapping,然后赋值给data

data['imgs_mapping'] = video_mapping

传入7张图像组成的frame_array
loading.py
Video_swin\mmaction\datasets\pipelines\loading.py
同时在loading.py文件需要定义DecordInit类,

 container = decord.VideoReader(file_obj, num_threads=self.num_threads)

不再使用decord.VideoReader对视频进行解码,使用自己合成相同维度的矩阵进行替换。

results['video_reader'] = results['imgs_mapping']
results['total_frames'] = len(results['imgs_mapping'])

还需要替换DecordDecode类,因为有类型错误

 frame_dict = {
           # idx: container[idx].asnumpy()
           idx: container[idx]
           for idx in np.unique(frame_inds)
       }

这样所有的代码更改完毕,如若更改,最好还是自己单独写一个类,毕竟改的是环境的代码,后面想跑原始数据,还需要更改回来。

注意这里有一个问题:
使用cv.imread()加载每一张图像以后形成的frame_array和使用视频解码器decord.VideoReader解码出的frame_array是有差别的,每个映射矩阵的数字在相同的位置差5(例如[144 130 130] 、[145 133 133])以至于预测结果会有偏差,大部分实在得分上,类别差的并不大,100个视频中只有2个有差别,本身这两个颗粒就有争议的。

这里展示一个博客来说的cv.imread()和decord.VideoReader差异
https://cloud.tencent.com/developer/ask/sof/1048047/answer/1474354

我正在使用opencv VideoWriter函数从摄像头捕获视频并保存它们。我将捕获的视频保存为未压缩的avi文件。当我完成录制视频时,我有另一个脚本,它应该逐帧读取视频,处理像素值。然而,当我尝试读取保存的视频的帧时,像素值有点偏离。

例如,比较正在写入的视频的第一帧和正在读取的视频(假设100%相同),我注意到像素值偏离了一个很小的数字(RGB值偏离了一个很小的数字,通常小于5)。

我已经确保我在写视频和阅读视频时使用的是完全相同的视频索引(下面的检查代码)

def write_video():
   out = cv2.VideoWriter("encrypted.avi" ,cv2.VideoWriter_fourcc(*'XVID'),30, (640,480))
   foreach frame:
       out.write(frame)

def read_video():
   cap = cv2.VideoCapture("encrypted.avi")
   cap.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc(*'XVID'))
   while(cap.isOpened()):
       ret, frame = cap.read()

对于我的应用程序,正在写入和读取的帧应该100%匹配。我已经添加了一张图像,突出了正在写入的视频中的第一帧和正在读取的视频之间的差异。任何帮助都是非常感谢的
在这里插入图片描述

五、总结

Video-Swin-Transformer代码值得深度学习,可以看看每个模块对数据的处理等,这个模型的工程化在我看来非常完美,从导包到数据处理到训练模型和最后解码,都值得细细的去品。
举一个例子:
我们来看一下他的configs

test_pipeline = [
   dict(type='DecordInit'),
   dict(
       type='SampleFrames',
       clip_len=32,
       frame_interval=2,
       num_clips=1,
       test_mode=True),
   dict(type='DecordDecode'),
   dict(type='Resize', scale=(-1, 256)),
   dict(type='CenterCrop', crop_size=224),
   dict(type='Flip', flip_ratio=0),
   dict(type='Normalize', **img_norm_cfg),
   dict(type='FormatShape', input_format='NCTHW'),
   dict(type='Collect', keys=['imgs', 'label'], meta_keys=[]),
   dict(type='ToTensor', keys=['imgs'])

从config中数据需要的处理就直接定义了,数据的整个流程都都写道这里面了,所以很好的代码,值得新人细细的学习一下

六、参考资料

https://github.com/SwinTransformer/Video-Swin-Transformer
https://cloud.tencent.com/developer/ask/sof/1048047/answer/1474354
https://blog.csdn.net/weixin_59340037/article/details/123635235

猜你喜欢

转载自blog.csdn.net/TF666666/article/details/125522195