torch.backends.cudnn.benchmark

设置torch.backends.cudnn.benchmark=True能在固定网络结构和输入尺寸时加速CNN,通过测试并选择最佳卷积实现。但若网络或输入尺寸变化频繁,可能导致反效果,因需不断重新优化。适用于结构不变、输入尺寸固定的模型,如常见的CV任务。
摘要由CSDN通过智能技术生成

设置 torch.backends.cudnn.benchmark=True 将会让程序在开始时花费一点额外时间,为整个网络的每个卷积层搜索最适合它的卷积实现算法,进而实现网络的加速。适用场景是网络结构固定(不是动态变化的),网络的输入形状(包括 batch size,图片大小,输入的通道)是不变的,其实也就是一般情况下都比较适用。反之,如果卷积层的设置一直变化,将会导致程序不停地做优化,反而会耗费更多的时间。

卷积层是卷积神经网络中的最重要的部分,也往往是运算量最大的部分。如果我们可以在底层代码中提升卷积运算的效率的话,就可以在不改变给定的神经网络结构的情况下,大大提升其训练和预测的速度。

对于卷积这个操作来说,其实现方式是多种多样的。最简单的实现方式就是使用多层循环嵌套,对于每张输入图像,对于每个要输出的通道,对于每个输入的通道,选取一个区域,同指定卷积核进行卷积操作,然后逐行滑动,直到整张图像都处理完毕,这个方法一般被称为 direct 法,这个方法虽然简单,但是看到这么多循环,我们就知道效率在一般情况下不会很高了。除此之外,实现卷积层的算法还有基于 GEMM (General Matrix Multiply) 的,基于 FFT 的,基于 Winograd 算法的等等,而且每个算法还有自己的一些变体。在一个开源的 C++ 库 triNNity 中,就实现了接近 80 种的卷积前向传播算法!

每种卷积算法,都有其特有的一些优势,比如有的算法在卷积核大的情况下,速度很快;比如有的算法在某些情况下内存使用比较小。给定一个卷积神经网络(比如 ResNet-101),给定输入图片的尺寸,给定硬件平台,实现这个网络最简单的方法就是对所有卷积层都采用相同的卷积算法(比如 direct 算法),但是这样运行肯定不是最优的;比较好的方法是,我们可以预先进行一些简单的优化测试,在每一个卷积层中选择最适合(最快)它的卷积算法,决定好每层最快的算法之后,我们再运行整个网络,这样效率就会提升不少。

实际上,设置这个 flag 为 True,我们就可以在 PyTorch 中对模型里的卷积层进行预先的优化,也就是在每一个卷积层中测试 cuDNN 提供的所有卷积实现算法,然后选择最快的那个。这样在模型启动的时候,只要额外多花一点点预处理时间,就可以较大幅度地减少训练时间。

这岂不是,用 cudnn.benchmark 一时爽,一直用一直爽吗?其实不然,在某些情况,使用它可能会大大增加运行时间!在背景知识里面我们已经提到过,但是在这里我们更加具体的定义一下,到底哪些因素会影响到卷积层的运行时间。

(1)首先,当然是卷积层本身的参数,常见的包括卷积核大小,stride,dilation,padding ,输出通道的个数等;
(2)其次,是输入的相关参数,包括输入的宽和高,输入通道的个数等;
(3)最后,还有一些其他的因素,比如硬件平台,输入输出精度、布局等等。
我们定义一个卷积场景的参数主要包括 (1) 和 (2),因为在同一个程序中 (3) 往往都是相同的,我们暂且忽略不计。不同的卷积场景有不同的最优卷积算法,需要分别进行测试和选择。

据此我们可以看出来,首先如果我们的网络模型一直变的话,那肯定是不能设置 cudnn.benchmark=True 的。因为网络结构经常变,每次 PyTorch 都会自动来根据新的卷积场景做优化:这次花费了半天选出最合适的算法出来,结果下次你结构又变了,之前就白做优化了。不仅如此,还得要根据这个新的结构继续做选择最高效的算法组合,又花费不少的时间。这样反而会大大降低效率。

另外,我们输入的大小也不能变。对于一个卷积层,这次的输入形状比如是 (8, 3, 224, 224),下次换成了 (8, 3, 112, 112),那也不行。输入的情况变了,最优的算法不一定适用了(比如有的算法在大尺寸输入情况下速度快),PyTorch 还是会重新寻找最优算法的。注意,这里的 batch size,输入通道,图片大小都不能变。

不过一般的 CV 模型来说,网络的结构一般是不会动态变化的,其次,图像一般都 resize 到固定的尺寸,batch size 也是固定的。所以,在大部分情况下,我们都可以在程序中加上这行神奇的代码,来减少运行时间!

参考文献:
https://zhuanlan.zhihu.com/p/73711222

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值