写点什么

MXNet 视频 I/O 读取速度提升 18 倍的优化策略

  • 2020-02-24
  • 本文字数:2116 字

    阅读完需:约 7 分钟

MXNet 视频I/O读取速度提升18倍的优化策略

大规模视频数据的模型训练中,视频读取时间严重影响模型的训练速度。MXNet 仅提供读取图像的迭代器,没有提供读取视频的迭代器,本文提出一种优化策略,可以将训练速度提升 18 倍。

一、前言

大规模视频数据的模型训练中,视频读取时间严重影响模型的训练速度。MXNet 仅提供读取图像的迭代器,没有提供读取视频的迭代器。传统方法基于 opencv 或 skimage 直接读取原始图像,速度较慢。我们将原始图像打包成 Rec 格式,然后使用 ImageRecordIter 迭代器构建新的迭代器,具体代码实现见 MTCloudVision/mxnet-videoio(https://github.com/MTCloudVision/mxnet-videoio)。使用4个Titan 1080ti GPU,优化后训练速度提升了~18 倍。


MXNet 框架使用迭代器器模式实现读取硬盘中图像的 I/O 接口。目前 MXNet 官方提供的读取图像的迭代器有:image.ImageIter、io.ImageRecordIter(io.ImageRecordUInt8Iter)、io.MNISTIter。MXNet 的 I/O 接口可扩展性强,支持开发者对于图像进行打包,生成用于训练模型的迭代器。目前 MXNet 没有提供读取视频的 I/O 接口。


本文首先比较 MXNet 不同接口的图像 I/O 性能;然后在 Rec 图像迭代器基础上,实现视频 I/O 迭代器,同时对比了优化前后的性能指标。

二、图像 I/O 接口性能对比

MXNet 三种图像 I/O 迭代器:


  • io.MNISTIter:该接口是为 MNIST 数据集设计的,仅支持读取 MNIST 图像数据,数据增强格式支持有限;

  • io.ImageRecordIter:支持 Rec 格式的数据读取。该接口同时支持多种图像增强方式。基于 C++实现,执行效率较高,读取速度较快。缺点是需要将所有训练图像一次性打包成 Rec 格式,占用磁盘空间较大;

  • image.ImageIter:同时支持读取 Rec 和原始图像,相比以上两接口,更加灵活,同时也支持多种图像增强方式。接口基于 Python 实现,读取速度慢于 io.ImageRecordIter 接口;


我们对 image.ImageIter 和 io.ImageRecordIter 做了如下对比测试:


测试环境:


MXNet 版本:0.11.0


网络结构:Inception-v3


类别(num-classes):3


GPU:titan x


测试结果:


单 GPU,batchsize=128



可以看出,前两种读取方式的 I\O 时间主要消耗在 data_iter 阶段,第三种 I\O 时间主要消耗在 update_metric 阶段,且前两种时间消耗大约是第三种的 1.4 倍。调试 ImageRecordIter 接口的 update_metric 阶段操作,发现耗时主要集中在 pred_label.asnumpy()或 pred.asnumpy()操作。


多 GPU(3),batchsize=128*3



可以看出,多 GPU 时,前两种 io 时间约为第三种的 4.4 倍。


结论:单 GPU 时,ImageRecordIter(Rec 格式)的读取速度是其他接口的 1.4 倍;多 GPU 时,ImageRecordIter(Rec 格式)是其他接口的 4.4 倍。原因是其他接口 I/O 读取数据时间是训练时间的 30 倍+,多 GPU 时,其他接口速度基本不变。如果数据集是固定的,建议使用 ImageRecordIter 接口进行图像读取,缺点是占用磁盘空间较大。

三、视频 I/O 优化性能分析

本部分介绍基于 mxnet 图像 io 迭代器 ImageRecordIter 的视频读取迭代器的实现方法,具体实现可以参考:MTCloudVision/mxnet-videoio(https://github.com/MTCloudVision/mxnet-videoio)。


mxnet 图像 I/O 迭代器的输出结构:(batchsize, channel, height, width)。


我们要实现的读取视频的迭代器输出结构:(batchsize, frame_pervideo, channel, height, width),有两种方式可以实现这种迭代器,即基于 opencv 接口实现迭代器和对已有迭代器接口进行封装。


  • 基于 OpenCV 接口实现迭代器:使用 OpenCV 读取视频,将读取数据进行打包成结构为(batchsize,frame_pervideo, channel, height, width)的数据。该方法优点:基于 Python 代码容易实现。缺点:视频读取很慢,对于大规模视频训练任务,严重影响模型的迭代效率。

  • 封装 ImageRecordIter 接口:以每个视频取 3 帧为例,先将视频的数据封装成结构为(3batchsize, channel, height, width)的图像数据,将标签封装成(3batchsize,)的结构;然后调用 ImageRecordIter,将图像数据 reshape 成(batchsize, 3, channel, height, width),并将标签进行稀疏采样成(batchsize,)的结构。

  • 基于以上两种方法,我们做了三组性能对比实验,结果如下:




通过对比,可以看到:


  • 基于 Rec 格式的数据读取速度约为使用 opencv 读取图像速度的 18 倍;

  • 基于 Rec 格式的数据读取速度与 GPU 数正相关,4 个 GPU 的训练速度大概是单个 GPU 的 4 倍,即多 GPU 训练性能提升显著;

  • OpenCV 读取视频图像时,单 GPU 和多 GPU 的读取速度相近,即使用多 GPU 对训练速度的提升几乎没有帮助;

  • OpenCV 读取视频图像,多线程(10)读取比单线程读取速度有提升,但提升有限;


以上实验结果的测试环境:


MXNet 版本:1.0.1


网络结构:BN-Inception


批次数(BatchSize):50


机器:GTX1080ti


训练数据类别数(num_class):101


视频处理:视频采样 3 帧,每帧大小 256x320


实际应用中,训练数据 10W 视频,每个视频截取 10 帧时,采用 resnet-200 在 titan x 上训练 20 个 epoch,采用 cv2.imread 四个线程 io 需要~228 小时,而基于 Rec 视频迭代器只需~22 小时。


作者介绍:付志康,美图云视觉技术部门,计算机视觉工程师。


本文转载自美图技术公众号。


原文链接:https://mp.weixin.qq.com/s/Nq-fZY1L_ULO5DtBVg8eAw


2020-02-24 19:18999

评论

发布
暂无评论
发现更多内容

Spring 数据库配置文件进行解密操作,和网易大佬的技术面谈

Java 程序员 后端

Socket和ServerSocket的简单介绍及例子,mybatis源码面试题

Java 程序员 后端

Spring Cloud Gateway修改请求和响应body的内容

Java 程序员 后端

Spring--快速入门,rabbitmq面试题总结

Java 程序员 后端

SpringBoot中好用的数据连接池,入职3个月的Java程序员面临转正

Java 程序员 后端

springboot入门教程,4000多页合集的计算机、网络、算法知识总结

Java 程序员 后端

set集合框架,java消息中间件面试

Java 程序员 后端

Spring Cloud入门-Zuul服务网关(Hoxton版本)

Java 程序员 后端

SpringBoot2---指标监控,kalilinux教程下载

Java 程序员 后端

Spring MVC面试题(2020最新版),java书籍入门下载

Java 程序员 后端

SpringBoot---入门和配置,深入java虚拟机百度云

Java 程序员 后端

SpringBoot---错误处理机制,kafka实现负载均衡的原理

Java 程序员 后端

SpringBoot基于微服务架构的前后端分离博客系统源码免费赠送(1)

Java 程序员 后端

SpringBoot整合SpringSecurity超详细入门教程

Java 程序员 后端

RocketMQ 5,linux端口转发技术

Java 程序员 后端

Spring Cloud Gateway自定义过滤器实战(观测断路器状态变化)

Java 程序员 后端

Spring-Boot-+-Redis-实现接口幂等性,看这篇就太好了

Java 程序员 后端

springboo 使用自定义的 Tomcat,java常用的设计模式面试

Java 程序员 后端

Spring Boot 精讲,看完你还敢说你不会 Spring Boot ?

Java 程序员 后端

Spring boot记录sql探索,java堆和栈面试题

Java 程序员 后端

Spring MVC—XML配置与注解配置+使用注解完成请求参数绑定

Java 程序员 后端

Spring MVC+Spring+Mybatis实现支付宝支付功能

Java 程序员 后端

SpringBoot源码学习系列之嵌入式Servlet容器

Java 程序员 后端

SDS——Redis源码剖析,java工程师进阶书籍

Java 程序员 后端

Spring Boot 快速入门(二),华为工程师面试经历

Java 程序员 后端

Spring Cloud原理详解,java程序员进阶

Java 程序员 后端

SpringBoot基于微服务架构的前后端分离博客系统源码免费赠送

Java 程序员 后端

Springboot过滤器和拦截器详解及使用场景,nginx原理和架构

Java 程序员 后端

Spring Boot 项目的这些文件都是干啥用的?,java电子书免费

Java 程序员 后端

springboot 整合 thymeleaf,java技术核心卷二

Java 程序员 后端

SpringBoot中的yaml语法及静态资源访问问题,mysql面试笔试题

Java 程序员 后端

MXNet 视频I/O读取速度提升18倍的优化策略_行业深度_付志康_InfoQ精选文章